GUI - Implemented link labels showing data on links when traffic is flowing..
Change-Id: I3fe602d20c5756620d2c4eb793dac2a0c8d1379c
diff --git a/web/gui/src/main/webapp/json/ev/links/ev_23_onos.json b/web/gui/src/main/webapp/json/ev/links/ev_23_onos.json
index 7d14845..2c42f2d 100644
--- a/web/gui/src/main/webapp/json/ev/links/ev_23_onos.json
+++ b/web/gui/src/main/webapp/json/ev/links/ev_23_onos.json
@@ -12,9 +12,9 @@
"of:0000ffffffff0007/1-0E:2A:69:30:13:89/-1/0"
],
"labels": [
- "Load{rate=98, latest=38080}",
- "Load{rate=98, latest=38080}",
- "Load{rate=98, latest=38080}"
+ "Load{rate=20, latest=20000}",
+ "Load{rate=10, latest=20000}",
+ ""
]
}
]
diff --git a/web/gui/src/main/webapp/json/ev/links/ev_24_onos.json b/web/gui/src/main/webapp/json/ev/links/ev_24_onos.json
index 93b6aa6..00702ea 100644
--- a/web/gui/src/main/webapp/json/ev/links/ev_24_onos.json
+++ b/web/gui/src/main/webapp/json/ev/links/ev_24_onos.json
@@ -12,9 +12,9 @@
"of:0000ffffffff0007/1-0E:2A:69:30:13:89/-1/0"
],
"labels": [
- "Load{rate=98, latest=38080}",
- "Load{rate=98, latest=38080}",
- "Load{rate=98, latest=38080}"
+ "",
+ "Load{rate=98, latest=38456}",
+ "Load{rate=98, latest=38789}"
]
}
]
diff --git a/web/gui/src/main/webapp/topo2.css b/web/gui/src/main/webapp/topo2.css
index f1dbf5e..d14b966 100644
--- a/web/gui/src/main/webapp/topo2.css
+++ b/web/gui/src/main/webapp/topo2.css
@@ -154,6 +154,17 @@
stroke-dasharray: 8 8
}
+#topo svg .linkLabel rect {
+ fill: #eef;
+ stroke: blue;
+ stroke-width: 0.3;
+}
+#topo svg .linkLabel text {
+ text-anchor: middle;
+ fill: #a13d11;
+ stroke: none;
+ font-size: 8pt;
+}
/* Fly-in details pane */
diff --git a/web/gui/src/main/webapp/topo2.js b/web/gui/src/main/webapp/topo2.js
index e5e73f6..66366c7 100644
--- a/web/gui/src/main/webapp/topo2.js
+++ b/web/gui/src/main/webapp/topo2.js
@@ -186,8 +186,10 @@
topoG,
nodeG,
linkG,
+ linkLabelG,
node,
link,
+ linkLabel,
mask;
// the projection for the map background
@@ -710,17 +712,25 @@
// Revert any links hilighted previously.
link.classed('primary secondary animated optical', false);
+ // Remove all previous labels.
+ removeLinkLabels();
- // Now hilight all links in the paths payload.
+ // Now hilight all links in the paths payload, and attach
+ // labels to them, if they are defined.
paths.forEach(function (p) {
- var cls = p.class;
- p.links.forEach(function (id) {
- var lnk = findLinkById(id);
- if (lnk) {
- lnk.el.classed(cls, true);
+ var n = p.links.length,
+ i,
+ ldata;
+
+ for (i=0; i<n; i++) {
+ ldata = findLinkById(p.links[i]);
+ if (ldata) {
+ ldata.el.classed(p.class, true);
+ ldata.label = p.labels[i];
}
- });
+ }
});
+ updateLinks();
}
// ...............................
@@ -891,6 +901,10 @@
return 'translate(' + x + ',' + y + ')';
}
+ function rotate(deg) {
+ return 'rotate(' + deg + ')';
+ }
+
function missMsg(what, id) {
return '\n[' + what + '] "' + id + '" missing ';
}
@@ -973,6 +987,12 @@
return lnk;
}
+ function removeLinkLabels() {
+ network.links.forEach(function (d) {
+ d.label = '';
+ });
+ }
+
var widthRatio = 1.4,
linkScale = d3.scale.linear()
.domain([1, 12])
@@ -1004,13 +1024,15 @@
// provide ref to element selection from backing data....
d.el = link;
restyleLinkElement(d);
-
- // TODO: add src/dst port labels etc.
});
// operate on both existing and new links, if necessary
//link .foo() .bar() ...
+ // apply or remove labels
+ var labelData = getLabelData();
+ applyLinkLabels(labelData);
+
// operate on exiting links:
link.exit()
.attr('stroke-dasharray', '3, 3')
@@ -1024,6 +1046,95 @@
})
.style('opacity', 0.0)
.remove();
+
+ // NOTE: invoke a single tick to force the labels to position
+ // onto their links.
+ tick();
+ }
+
+ function getLabelData() {
+ // create the backing data for showing labels..
+ var data = [];
+ link.each(function (d) {
+ if (d.label) {
+ data.push({
+ id: 'lab-' + d.key,
+ key: d.key,
+ label: d.label,
+ ldata: d
+ });
+ }
+ });
+ return data;
+ }
+
+ var linkLabelOffset = '0.3em';
+
+ function applyLinkLabels(data) {
+ var entering;
+
+ linkLabel = linkLabelG.selectAll('.linkLabel')
+ .data(data, function (d) { return d.id; });
+
+ entering = linkLabel.enter().append('g')
+ .classed('linkLabel', true)
+ .attr('id', function (d) { return d.id; });
+
+ entering.each(function (d) {
+ var el = d3.select(this),
+ rect,
+ text,
+ parms = {
+ x1: d.ldata.x1,
+ y1: d.ldata.y1,
+ x2: d.ldata.x2,
+ y2: d.ldata.y2
+ };
+
+ d.el = el;
+ rect = el.append('rect');
+ text = el.append('text').text(d.label);
+ rect.attr(rectAroundText(el));
+ text.attr('dy', linkLabelOffset);
+
+ el.attr('transform', transformLabel(parms));
+ });
+
+ // Remove any links that are no longer required.
+ linkLabel.exit().remove();
+ }
+
+ function rectAroundText(el) {
+ var text = el.select('text'),
+ box = text.node().getBBox();
+
+ // translate the bbox so that it is centered on [x,y]
+ box.x = -box.width / 2;
+ box.y = -box.height / 2;
+
+ // add padding
+ box.x -= 1;
+ box.width += 2;
+ return box;
+ }
+
+ function transformLabel(p) {
+ var dx = p.x2 - p.x1,
+ dy = p.y2 - p.y1,
+ xMid = dx/2 + p.x1,
+ yMid = dy/2 + p.y1;
+ //length = Math.sqrt(dx*dx + dy*dy),
+ //rads = Math.asin(dy/length),
+ //degs = rads / (Math.PI*2) * 360;
+
+ return translate(xMid, yMid);
+
+ // TODO: consider making label parallel to line
+ //return [
+ // translate(xMid, yMid),
+ // rotate(degs),
+ // translate(0, 8)
+ //].join('');
}
function createDeviceNode(device) {
@@ -1443,6 +1554,18 @@
x2: function (d) { return d.target.x; },
y2: function (d) { return d.target.y; }
});
+
+ linkLabel.each(function (d) {
+ var el = d3.select(this);
+ var lnk = findLinkById(d.key),
+ parms = {
+ x1: lnk.source.x,
+ y1: lnk.source.y,
+ x2: lnk.target.x,
+ y2: lnk.target.y
+ };
+ el.attr('transform', transformLabel(parms));
+ });
}
// ==============================
@@ -1839,12 +1962,14 @@
.attr('id', 'topo-G')
.attr('transform', fcfg.translate());
- // subgroups for links and nodes
+ // subgroups for links, link labels, and nodes
linkG = topoG.append('g').attr('id', 'links');
+ linkLabelG = topoG.append('g').attr('id', 'linkLabels');
nodeG = topoG.append('g').attr('id', 'nodes');
- // selection of nodes and links
+ // selection of links, linkLabels, and nodes
link = linkG.selectAll('.link');
+ linkLabel = linkLabelG.selectAll('.linkLabel');
node = nodeG.selectAll('.node');
function chrg(d) {