ONOS-2385 -- Bug fixes for removing individual links on the Topo View. 5 or more links between devices have a label indicating how many there are between each one.

Change-Id: I301ca6da8c453b54e16980a47e09dfd9f2f80f8b
diff --git a/web/gui/src/main/webapp/app/view/topo/topoD3.js b/web/gui/src/main/webapp/app/view/topo/topoD3.js
index 4dcf3f0..d29748b 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoD3.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoD3.js
@@ -429,6 +429,100 @@
         });
     }
 
+    function labelPoint(linkPos) {
+        var lengthUpLine = 1 / 3,
+            dx = linkPos.x2 - linkPos.x1,
+            dy = linkPos.y2 - linkPos.y1,
+            movedX = dx * lengthUpLine,
+            movedY = dy * lengthUpLine;
+
+        return {
+            x: movedX,
+            y: movedY
+        };
+    }
+
+    function calcGroupPos(linkPos) {
+        var moved = labelPoint(linkPos);
+        return sus.translate(linkPos.x1 + moved.x, linkPos.y1 + moved.y);
+    }
+
+    // calculates where on the link that the hash line for 5+ label appears
+    function hashAttrs(linkPos) {
+        var hashLength = 25,
+            halfLength = hashLength / 2,
+            dx = linkPos.x2 - linkPos.x1,
+            dy = linkPos.y2 - linkPos.y1,
+            length = Math.sqrt((dx * dx) + (dy * dy)),
+            moveAmtX = (dx / length) * halfLength,
+            moveAmtY = (dy / length) * halfLength,
+            mid = labelPoint(linkPos),
+            angle = Math.atan(dy / dx) + 45;
+
+        return {
+            x1: mid.x - moveAmtX,
+            y1: mid.y - moveAmtY,
+            x2: mid.x + moveAmtX,
+            y2: mid.y + moveAmtY,
+            stroke: api.linkConfig()[ts.theme()].baseColor,
+            transform: 'rotate(' + angle + ',' + mid.x + ',' + mid.y + ')'
+        };
+    }
+
+    function textLabelPos(linkPos) {
+        var point = labelPoint(linkPos),
+            dist = 20;
+        return {
+            x: point.x + dist,
+            y: point.y + dist
+        };
+    }
+
+    function applyNumLinkLabels(data, lblsG) {
+        var labels = lblsG.selectAll('g.numLinkLabel')
+                .data(data, function (d) { return 'pair-' + d.id; }),
+            entering;
+
+        // update existing labels
+        labels.each(function (d) {
+            var el = d3.select(this);
+
+            el.attr({
+                transform: function (d) { return calcGroupPos(d.linkCoords); }
+            });
+            el.select('line')
+                .attr(hashAttrs(d.linkCoords));
+            el.select('text')
+                .attr(textLabelPos(d.linkCoords))
+                .text(d.num);
+        });
+
+        // add new labels
+        entering = labels
+            .enter()
+            .append('g')
+            .attr({
+                transform: function (d) { return calcGroupPos(d.linkCoords); },
+                id: function (d) { return 'pair-' + d.id; }
+            })
+            .classed('numLinkLabel', true);
+
+        entering.each(function (d) {
+            var el = d3.select(this);
+
+            el.append('line')
+                .classed('numLinkHash', true)
+                .attr(hashAttrs(d.linkCoords));
+            el.append('text')
+                .classed('numLinkText', true)
+                .attr(textLabelPos(d.linkCoords))
+                .text(d.num);
+        });
+
+        // remove old labels
+        labels.exit().remove();
+    }
+
     // ==========================
     // Module definition
 
@@ -475,7 +569,8 @@
                 linkEntering: linkEntering,
                 applyLinkLabels: applyLinkLabels,
                 transformLabel: transformLabel,
-                applyPortLabels: applyPortLabels
+                applyPortLabels: applyPortLabels,
+                applyNumLinkLabels: applyNumLinkLabels
             };
         }]);
 }());