Bri Prebilic Cole
Committed by Gerrit Code Review

ONOS-2328 GUI -- Started work on seeing multiple links between devices on the to…

…pology view. Device links are now grouped based on what device they are between. Also minor bug fixes and investigations into other bugs. WIP.

Change-Id: I444f016268efc5c489ba6ad0282d0f7827fff462
......@@ -367,6 +367,7 @@
.classed('linkLabel', true)
.attr('id', function (d) { return d.id; });
// FIXME: x and y position calculated here, use link.position obj
entering.each(function (d) {
var el = d3.select(this),
rect,
......@@ -410,6 +411,7 @@
return box;
}
// FIXME: x and y position calculated here
function transformLabel(p) {
var dx = p.x2 - p.x1,
dy = p.y2 - p.y1,
......
......@@ -24,8 +24,7 @@
// injected refs
var $log, $timeout, fs, sus, is, ts, flash, wss,
tis, tms, td3, tss, tts, tos, fltr, tls,
icfg, uplink, svg;
tis, tms, td3, tss, tts, tos, fltr, tls, uplink, svg;
// configuration
var linkConfig = {
......@@ -50,6 +49,7 @@
network = {
nodes: [],
links: [],
linksByDevice: {},
lookup: {},
revLinkToKey: {}
},
......@@ -215,6 +215,7 @@
d = tms.createLink(data);
if (d) {
network.links.push(d);
aggregateLink(d, data);
lu[d.key] = d;
updateLinks();
fStart();
......@@ -241,10 +242,40 @@
// ========================
function makeNodeKey(node1, node2) {
return node1 + '-' + node2;
}
function findNodePair(key, keyRev) {
if (network.linksByDevice[key]) {
return key;
} else if (network.linksByDevice[keyRev]) {
return keyRev;
} else {
return false;
}
}
function aggregateLink(ldata, link) {
var key = makeNodeKey(link.src, link.dst),
keyRev = makeNodeKey(link.dst, link.src),
found = findNodePair(key, keyRev);
if (found) {
network.linksByDevice[found].push(ldata);
ldata.devicePair = found;
} else {
network.linksByDevice[key] = [ ldata ];
ldata.devicePair = key;
}
}
function addLinkUpdate(ldata, link) {
// add link event, but we already have the reverse link installed
ldata.fromTarget = link;
rlk[link.id] = ldata.key;
// possible solution to el being undefined in restyleLinkElement:
//_updateLinks();
restyleLinkElement(ldata);
}
......@@ -267,7 +298,12 @@
delay = immediate ? 0 : 1000;
// FIXME: understand why el is sometimes undefined on addLink events...
if (el) {
// Investigated:
// el is undefined when it's a reverse link that is being added.
// updateLinks (which sets ldata.el) isn't called before this is called.
// Calling _updateLinks in addLinkUpdate fixes it, but there might be
// a more efficient way to fix it.
if (el && !el.empty()) {
el.classed('link', true);
el.classed('inactive', !online);
el.classed(allLinkTypes, false);
......@@ -383,7 +419,7 @@
d.metaUi = metaUi;
wss.sendEvent('updateMeta', {
id: d.id,
'class': d.class,
class: d.class,
memento: metaUi
});
}
......@@ -503,7 +539,11 @@
.attr({
id: function (d) { return sus.safeId(d.id); },
class: mkSvgClass,
transform: function (d) { return sus.translate(d.x, d.y); },
transform: function (d) {
// sometimes says d.x and d.y are NaN?
// I have a feeling it's a timing issue
return sus.translate(d.x, d.y);
},
opacity: 0
})
.call(drag)
......@@ -548,6 +588,9 @@
link = linkG.selectAll('.link')
.data(network.links, function (d) { return d.key; });
// This seems to do nothing? I've only triggered it on timeout errors
// when adding links, link var is empty because there aren't any links
// when removing links, link var is empty already
// operate on existing links:
link.each(function (d) {
// this is supposed to be an existing link, but we have observed
......@@ -559,6 +602,7 @@
});
// operate on entering links:
// FIXME: x and y position calculated here - calculate position and add it to the link
var entering = link.enter()
.append('line')
.attr({
......@@ -620,6 +664,7 @@
nodeAttr: {
transform: function (d) { return sus.translate(d.x, d.y); }
},
// FIXME: x and y position calculated here, will be deleted
linkAttr: {
x1: function (d) { return d.source.x; },
y1: function (d) { return d.source.y; },
......@@ -630,6 +675,7 @@
transform: function (d) {
var lnk = tms.findLinkById(d.key);
if (lnk) {
// FIXME: x and y position calculated here, use link.position object
return td3.transformLabel({
x1: lnk.source.x,
y1: lnk.source.y,
......@@ -643,9 +689,16 @@
function tick() {
// guard against null (which can happen when our view pages out)...
if (node) node.attr(tickStuff.nodeAttr);
if (link) link.attr(tickStuff.linkAttr);
if (linkLabel) linkLabel.attr(tickStuff.linkLabelAttr);
if (node) {
node.attr(tickStuff.nodeAttr);
}
if (link) {
// FIXME: instead of tickStuff here, use link.position object
link.attr(tickStuff.linkAttr);
}
if (linkLabel) {
linkLabel.attr(tickStuff.linkLabelAttr);
}
}
......@@ -734,7 +787,7 @@
showHosts: function () { return showHosts; },
restyleLinkElement: restyleLinkElement,
updateLinkLabelModel: updateLinkLabelModel
}
};
}
function mkSelectApi(uplink) {
......@@ -755,7 +808,7 @@
hovered: tss.hovered,
validateSelectionContext: tss.validateSelectionContext,
selectOrder: tss.selectOrder
}
};
}
function mkObliqueApi(uplink, fltr) {
......@@ -797,19 +850,18 @@
angular.module('ovTopo')
.factory('TopoForceService',
['$log', '$timeout', 'FnService', 'SvgUtilService', 'IconService',
['$log', '$timeout', 'FnService', 'SvgUtilService',
'ThemeService', 'FlashService', 'WebSocketService',
'TopoInstService', 'TopoModelService',
'TopoD3Service', 'TopoSelectService', 'TopoTrafficService',
'TopoObliqueService', 'TopoFilterService', 'TopoLinkService',
function (_$log_, _$timeout_, _fs_, _sus_, _is_, _ts_, _flash_, _wss_,
function (_$log_, _$timeout_, _fs_, _sus_, _ts_, _flash_, _wss_,
_tis_, _tms_, _td3_, _tss_, _tts_, _tos_, _fltr_, _tls_) {
$log = _$log_;
$timeout = _$timeout_;
fs = _fs_;
sus = _sus_;
is = _is_;
ts = _ts_;
flash = _flash_;
wss = _wss_;
......@@ -822,8 +874,6 @@
fltr = _fltr_;
tls = _tls_;
icfg = is.iconConfig();
var themeListener = ts.addListener(function () {
updateLinks();
updateNodes();
......@@ -902,12 +952,24 @@
// clean up internal state
network.nodes = [];
network.links = [];
network.linksByDevice = {};
network.lookup = {};
network.revLinkToKey = {};
linkG = linkLabelG = nodeG = portLabelG = null;
link = linkLabel = node = null;
force = drag = null;
// clean up $timeout promises
if (fTimer) {
$timeout.cancel(fTimer);
}
if (fNodesTimer) {
$timeout.cancel(fNodesTimer);
}
if (fLinksTimer) {
$timeout.cancel(fLinksTimer);
}
}
return {
......
......@@ -104,6 +104,7 @@
return {x:x4, y:y4};
}
// FIXME: x and y position calculated here, use link.position
function lineSeg(d) {
return {
x1: d.source.x,
......@@ -200,6 +201,7 @@
td3.applyPortLabels(data, api.portLabelG());
}
// FIXME: x and y position calculated here somewhere
function locatePortLabel(link, src) {
var near = src ? 'source' : 'target',
far = src ? 'target' : 'source',
......
......@@ -36,7 +36,7 @@
*/
// shorthand
var lu, rlk, nodes, links;
var lu, rlk, nodes, links, linksByDevice;
var dim; // dimensions of layout [w,h]
......@@ -185,6 +185,12 @@
fromSource: link,
srcPort: link.srcPort,
tgtPort: link.dstPort,
position: {
x1: 0,
y1: 0,
x2: 0,
y2: 0
},
// functions to aggregate dual link state
type: function () {
......@@ -292,6 +298,11 @@
} else {
result.removeRawLink = function () {
// remove link out of aggregate linksByDevice list
var linksForDevPair = linksByDevice[ldata.devicePair],
rmvIdx = fs.find(ldata.key, linksForDevPair, 'key');
linksForDevPair.splice(rmvIdx, 1);
if (link) {
// remove fromSource
ldata.fromSource = null;
......@@ -393,6 +404,7 @@
rlk = api.network.revLinkToKey;
nodes = api.network.nodes;
links = api.network.links;
linksByDevice = api.network.linksByDevice;
}
function newDim(_dim_) {
......