Bri Prebilic Cole

ONOS-2328 GUI -- Enhanced Topology View to show multiple links individually betw…

…een devices (1 - 4). 5 or more is a thick line.

Change-Id: Ie096086454fd8d1d5d40f09396681f9cba8597a1
...@@ -367,17 +367,10 @@ ...@@ -367,17 +367,10 @@
367 .classed('linkLabel', true) 367 .classed('linkLabel', true)
368 .attr('id', function (d) { return d.id; }); 368 .attr('id', function (d) { return d.id; });
369 369
370 - // FIXME: x and y position calculated here, use link.position obj
371 entering.each(function (d) { 370 entering.each(function (d) {
372 var el = d3.select(this), 371 var el = d3.select(this),
373 rect, 372 rect,
374 - text, 373 + text;
375 - parms = {
376 - x1: d.ldata.source.x,
377 - y1: d.ldata.source.y,
378 - x2: d.ldata.target.x,
379 - y2: d.ldata.target.y
380 - };
381 374
382 if (d.ldata.type() === 'hostLink') { 375 if (d.ldata.type() === 'hostLink') {
383 el.classed('hostLinkLabel', true); 376 el.classed('hostLinkLabel', true);
...@@ -390,7 +383,7 @@ ...@@ -390,7 +383,7 @@
390 rect.attr(rectAroundText(el)); 383 rect.attr(rectAroundText(el));
391 text.attr('dy', linkLabelOffset); 384 text.attr('dy', linkLabelOffset);
392 385
393 - el.attr('transform', transformLabel(parms)); 386 + el.attr('transform', transformLabel(d.ldata.position));
394 }); 387 });
395 388
396 // Remove any labels that are no longer required. 389 // Remove any labels that are no longer required.
...@@ -411,7 +404,6 @@ ...@@ -411,7 +404,6 @@
411 return box; 404 return box;
412 } 405 }
413 406
414 - // FIXME: x and y position calculated here
415 function transformLabel(p) { 407 function transformLabel(p) {
416 var dx = p.x2 - p.x1, 408 var dx = p.x2 - p.x1,
417 dy = p.y2 - p.y1, 409 dy = p.y2 - p.y1,
......
...@@ -575,6 +575,82 @@ ...@@ -575,6 +575,82 @@
575 575
576 // ========================== 576 // ==========================
577 577
578 + function getDefaultPos(link) {
579 + return {
580 + x1: link.source.x,
581 + y1: link.source.y,
582 + x2: link.target.x,
583 + y2: link.target.y
584 + };
585 + }
586 +
587 + // returns amount of adjustment along the normal for given link
588 + function amt(numLinks, linkIdx) {
589 + var gap = 6;
590 + return (linkIdx - ((numLinks - 1) / 2)) * gap;
591 + }
592 +
593 + function calcMovement(d, amt, flipped) {
594 + var pos = getDefaultPos(d),
595 + mult = flipped ? -amt : amt,
596 + dx = pos.x2 - pos.x1,
597 + dy = pos.y2 - pos.y1,
598 + length = Math.sqrt((dx * dx) + (dy * dy));
599 +
600 + return {
601 + x1: pos.x1 + (mult * dy / length),
602 + y1: pos.y1 + (mult * -dx / length),
603 + x2: pos.x2 + (mult * dy / length),
604 + y2: pos.y2 + (mult * -dx / length)
605 + };
606 + }
607 +
608 + function calcPosition() {
609 + var lines = this,
610 + linkSrcId;
611 + lines.each(function (d) {
612 + if (d.type() === 'hostLink') {
613 + d.position = getDefaultPos(d);
614 + }
615 + });
616 +
617 + function normalizeLinkSrc(link) {
618 + // ensure source device is consistent across set of links
619 + // temporary measure until link modeling is refactored
620 + if (!linkSrcId) {
621 + linkSrcId = link.source.id;
622 + return false;
623 + }
624 +
625 + return link.source.id !== linkSrcId;
626 + }
627 +
628 + angular.forEach(network.linksByDevice, function (linkArr) {
629 + var numLinks = linkArr.length,
630 + link;
631 +
632 + if (numLinks === 1) {
633 + link = linkArr[0];
634 + link.position = getDefaultPos(link);
635 + } else if (numLinks >= 5) {
636 + // this code is inefficient, in the future the way links
637 + // are modeled will be changed
638 + angular.forEach(linkArr, function (link) {
639 + link.position = getDefaultPos(link);
640 + link.position.multiLink = true;
641 + });
642 + } else {
643 + // calculate position of links
644 + linkSrcId = null;
645 + angular.forEach(linkArr, function (link, index) {
646 + var offsetAmt = amt(numLinks, index),
647 + needToFlip = normalizeLinkSrc(link);
648 + link.position = calcMovement(link, offsetAmt, needToFlip);
649 + });
650 + }
651 + });
652 + }
653 +
578 function updateLinks() { 654 function updateLinks() {
579 if (fLinksTimer) { 655 if (fLinksTimer) {
580 $timeout.cancel(fLinksTimer); 656 $timeout.cancel(fLinksTimer);
...@@ -602,14 +678,14 @@ ...@@ -602,14 +678,14 @@
602 }); 678 });
603 679
604 // operate on entering links: 680 // operate on entering links:
605 - // FIXME: x and y position calculated here - calculate position and add it to the link
606 var entering = link.enter() 681 var entering = link.enter()
607 .append('line') 682 .append('line')
683 + .call(calcPosition)
608 .attr({ 684 .attr({
609 - x1: function (d) { return d.source.x; }, 685 + x1: function (d) { return d.position.x1; },
610 - y1: function (d) { return d.source.y; }, 686 + y1: function (d) { return d.position.y1; },
611 - x2: function (d) { return d.target.x; }, 687 + x2: function (d) { return d.position.x2; },
612 - y2: function (d) { return d.target.y; }, 688 + y2: function (d) { return d.position.y2; },
613 stroke: linkConfig[th].inColor, 689 stroke: linkConfig[th].inColor,
614 'stroke-width': linkConfig.inWidth 690 'stroke-width': linkConfig.inWidth
615 }); 691 });
...@@ -664,24 +740,17 @@ ...@@ -664,24 +740,17 @@
664 nodeAttr: { 740 nodeAttr: {
665 transform: function (d) { return sus.translate(d.x, d.y); } 741 transform: function (d) { return sus.translate(d.x, d.y); }
666 }, 742 },
667 - // FIXME: x and y position calculated here, will be deleted
668 linkAttr: { 743 linkAttr: {
669 - x1: function (d) { return d.source.x; }, 744 + x1: function (d) { return d.position.x1; },
670 - y1: function (d) { return d.source.y; }, 745 + y1: function (d) { return d.position.y1; },
671 - x2: function (d) { return d.target.x; }, 746 + x2: function (d) { return d.position.x2; },
672 - y2: function (d) { return d.target.y; } 747 + y2: function (d) { return d.position.y2; }
673 }, 748 },
674 linkLabelAttr: { 749 linkLabelAttr: {
675 transform: function (d) { 750 transform: function (d) {
676 var lnk = tms.findLinkById(d.key); 751 var lnk = tms.findLinkById(d.key);
677 if (lnk) { 752 if (lnk) {
678 - // FIXME: x and y position calculated here, use link.position object 753 + return td3.transformLabel(lnk.position);
679 - return td3.transformLabel({
680 - x1: lnk.source.x,
681 - y1: lnk.source.y,
682 - x2: lnk.target.x,
683 - y2: lnk.target.y
684 - });
685 } 754 }
686 } 755 }
687 } 756 }
...@@ -693,8 +762,8 @@ ...@@ -693,8 +762,8 @@
693 node.attr(tickStuff.nodeAttr); 762 node.attr(tickStuff.nodeAttr);
694 } 763 }
695 if (link) { 764 if (link) {
696 - // FIXME: instead of tickStuff here, use link.position object 765 + link.call(calcPosition)
697 - link.attr(tickStuff.linkAttr); 766 + .attr(tickStuff.linkAttr);
698 } 767 }
699 if (linkLabel) { 768 if (linkLabel) {
700 linkLabel.attr(tickStuff.linkLabelAttr); 769 linkLabel.attr(tickStuff.linkLabelAttr);
...@@ -827,7 +896,8 @@ ...@@ -827,7 +896,8 @@
827 return old; 896 return old;
828 }, 897 },
829 opacifyMap: uplink.opacifyMap, 898 opacifyMap: uplink.opacifyMap,
830 - inLayer: fltr.inLayer 899 + inLayer: fltr.inLayer,
900 + calcLinkPos: calcPosition
831 }; 901 };
832 } 902 }
833 903
......
...@@ -104,16 +104,6 @@ ...@@ -104,16 +104,6 @@
104 return {x:x4, y:y4}; 104 return {x:x4, y:y4};
105 } 105 }
106 106
107 - // FIXME: x and y position calculated here, use link.position
108 - function lineSeg(d) {
109 - return {
110 - x1: d.source.x,
111 - y1: d.source.y,
112 - x2: d.target.x,
113 - y2: d.target.y
114 - };
115 - }
116 -
117 function lineHit(line, p, m) { 107 function lineHit(line, p, m) {
118 if (p.x < line.x1 && p.x < line.x2) return false; 108 if (p.x < line.x1 && p.x < line.x2) return false;
119 if (p.x > line.x1 && p.x > line.x2) return false; 109 if (p.x > line.x1 && p.x > line.x2) return false;
...@@ -131,7 +121,7 @@ ...@@ -131,7 +121,7 @@
131 return; // skip hidden host links 121 return; // skip hidden host links
132 } 122 }
133 123
134 - var line = lineSeg(d), 124 + var line = d.position,
135 point = pdrop(line, mouse), 125 point = pdrop(line, mouse),
136 hit = lineHit(line, point, mouse), 126 hit = lineHit(line, point, mouse),
137 dist; 127 dist;
...@@ -201,24 +191,23 @@ ...@@ -201,24 +191,23 @@
201 td3.applyPortLabels(data, api.portLabelG()); 191 td3.applyPortLabels(data, api.portLabelG());
202 } 192 }
203 193
204 - // FIXME: x and y position calculated here somewhere
205 function locatePortLabel(link, src) { 194 function locatePortLabel(link, src) {
206 - var near = src ? 'source' : 'target', 195 + var offset = 32,
207 - far = src ? 'target' : 'source', 196 + pos = link.position,
208 - ln = link[near], 197 + nearX = src ? pos.x1 : pos.x2,
209 - lf = link[far], 198 + nearY = src ? pos.y1 : pos.y2,
210 - offset = 32; 199 + farX = src ? pos.x2 : pos.x1,
200 + farY = src ? pos.y2 : pos.y1;
211 201
212 function dist(x, y) { return Math.sqrt(x*x + y*y); } 202 function dist(x, y) { return Math.sqrt(x*x + y*y); }
213 203
214 - var dx = lf.x - ln.x, 204 + var dx = farX - nearX,
215 - dy = lf.y - ln.y, 205 + dy = farY - nearY,
216 k = offset / dist(dx, dy); 206 k = offset / dist(dx, dy);
217 207
218 - return {x: k * dx + ln.x, y: k * dy + ln.y}; 208 + return {x: k * dx + nearX, y: k * dy + nearY};
219 } 209 }
220 210
221 -
222 function selectLink(ldata) { 211 function selectLink(ldata) {
223 // if the new link is same as old link, do nothing 212 // if the new link is same as old link, do nothing
224 if (selectedLink && ldata && selectedLink.key === ldata.key) return; 213 if (selectedLink && ldata && selectedLink.key === ldata.key) return;
......
...@@ -209,7 +209,7 @@ ...@@ -209,7 +209,7 @@
209 t = lnk.fromTarget, 209 t = lnk.fromTarget,
210 ws = (s && s.linkWidth) || 0, 210 ws = (s && s.linkWidth) || 0,
211 wt = (t && t.linkWidth) || 0; 211 wt = (t && t.linkWidth) || 0;
212 - return Math.max(ws, wt); 212 + return lnk.position.multiLink ? 5 : Math.max(ws, wt);
213 } 213 }
214 }); 214 });
215 return lnk; 215 return lnk;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
39 nodeLock(b) // test-and-set nodeLock state 39 nodeLock(b) // test-and-set nodeLock state
40 opacifyMap(b) // show or hide map layer 40 opacifyMap(b) // show or hide map layer
41 inLayer(d, layer) // return true if d in layer {'pkt'|'opt'} 41 inLayer(d, layer) // return true if d in layer {'pkt'|'opt'}
42 + calcLinkPos() // recomputes link pos based on node data
42 */ 43 */
43 44
44 // configuration 45 // configuration
...@@ -155,6 +156,7 @@ ...@@ -155,6 +156,7 @@
155 .attr(api.tickStuff.nodeAttr); 156 .attr(api.tickStuff.nodeAttr);
156 api.link().transition() 157 api.link().transition()
157 .duration(time) 158 .duration(time)
159 + .call(api.calcLinkPos)
158 .attr(api.tickStuff.linkAttr); 160 .attr(api.tickStuff.linkAttr);
159 api.linkLabel().transition() 161 api.linkLabel().transition()
160 .duration(time) 162 .duration(time)
......