Bri Prebilic Cole
Committed by Gerrit Code Review

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
......@@ -579,6 +579,26 @@ html[data-platform='iPad'] #topo-p-detail {
fill: #eee;
}
/* Number of Links Labels */
#ov-topo line.numLinkHash {
stroke-width: 3;
}
#ov-topo text.numLinkText {
font-size: 15pt;
}
#ov-topo text.numLinkText {
text-anchor: middle;
}
.light #ov-topo text.numLinkText {
fill: #444;
}
.dark #ov-topo text.numLinkText {
fill: #eee;
}
/* ------------------------------------------------- */
/* Sprite Layer */
......
......@@ -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
};
}]);
}());
......
......@@ -61,10 +61,11 @@
fTimer, // timer for delayed force layout
fNodesTimer, // timer for delayed nodes update
fLinksTimer, // timer for delayed links update
dim; // the dimensions of the force layout [w,h]
dim, // the dimensions of the force layout [w,h]
linkNums = []; // array of link number labels
// SVG elements;
var linkG, linkLabelG, portLabelG, nodeG;
var linkG, linkLabelG, numLinkLblsG, portLabelG, nodeG;
// D3 selections;
var link, linkLabel, node;
......@@ -608,6 +609,7 @@
function calcPosition() {
var lines = this,
linkSrcId;
linkNums = [];
lines.each(function (d) {
if (d.type() === 'hostLink') {
d.position = getDefaultPos(d);
......@@ -625,13 +627,14 @@
return link.source.id !== linkSrcId;
}
angular.forEach(network.linksByDevice, function (linkArr) {
angular.forEach(network.linksByDevice, function (linkArr, key) {
var numLinks = linkArr.length,
link;
if (numLinks === 1) {
link = linkArr[0];
link.position = getDefaultPos(link);
link.position.multiLink = false;
} else if (numLinks >= 5) {
// this code is inefficient, in the future the way links
// are modeled will be changed
......@@ -639,13 +642,18 @@
link.position = getDefaultPos(link);
link.position.multiLink = true;
});
linkNums.push({
id: key,
num: numLinks,
linkCoords: linkArr[0].position
});
} else {
// calculate position of links
linkSrcId = null;
angular.forEach(linkArr, function (link, index) {
var offsetAmt = amt(numLinks, index),
needToFlip = normalizeLinkSrc(link);
link.position = calcMovement(link, offsetAmt, needToFlip);
link.position.multiLink = false;
});
}
});
......@@ -696,6 +704,9 @@
// operate on both existing and new links:
//link.each(...)
// add labels for how many links are in a thick line
td3.applyNumLinkLabels(linkNums, numLinkLblsG);
// apply or remove labels
td3.applyLinkLabels();
......@@ -764,6 +775,7 @@
if (link) {
link.call(calcPosition)
.attr(tickStuff.linkAttr);
td3.applyNumLinkLabels(linkNums, numLinkLblsG);
}
if (linkLabel) {
linkLabel.attr(tickStuff.linkLabelAttr);
......@@ -855,7 +867,8 @@
posNode: tms.positionNode,
showHosts: function () { return showHosts; },
restyleLinkElement: restyleLinkElement,
updateLinkLabelModel: updateLinkLabelModel
updateLinkLabelModel: updateLinkLabelModel,
linkConfig: function () { return linkConfig; }
};
}
......@@ -897,7 +910,10 @@
},
opacifyMap: uplink.opacifyMap,
inLayer: fltr.inLayer,
calcLinkPos: calcPosition
calcLinkPos: calcPosition,
applyNumLinkLabels: function () {
td3.applyNumLinkLabels(linkNums, numLinkLblsG);
}
};
}
......@@ -975,6 +991,7 @@
linkG = forceG.append('g').attr('id', 'topo-links');
linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
numLinkLblsG = forceG.append('g').attr('id', 'topo-numLinkLabels');
nodeG = forceG.append('g').attr('id', 'topo-nodes');
portLabelG = forceG.append('g').attr('id', 'topo-portLabels');
......@@ -1026,7 +1043,9 @@
network.lookup = {};
network.revLinkToKey = {};
linkG = linkLabelG = nodeG = portLabelG = null;
linkNums = [];
linkG = linkLabelG = numLinkLblsG = nodeG = portLabelG = null;
link = linkLabel = node = null;
force = drag = null;
......
......@@ -301,7 +301,10 @@
// remove link out of aggregate linksByDevice list
var linksForDevPair = linksByDevice[ldata.devicePair],
rmvIdx = fs.find(ldata.key, linksForDevPair, 'key');
linksForDevPair.splice(rmvIdx, 1);
if (rmvIdx >= 0) {
linksForDevPair.splice(rmvIdx, 1);
}
ldata.position.multilink = linksForDevPair.length >= 5;
if (link) {
// remove fromSource
......
......@@ -157,7 +157,8 @@
api.link().transition()
.duration(time)
.call(api.calcLinkPos)
.attr(api.tickStuff.linkAttr);
.attr(api.tickStuff.linkAttr)
.call(api.applyNumLinkLabels);
api.linkLabel().transition()
.duration(time)
.attr(api.tickStuff.linkLabelAttr);
......