GUI -- implemented ONOS instance affinity display.
- augmented ESC key handling to cancel affinity display before deslecting nodes.
- augmented setRadioButtons to return buttonset api, so we can query what is currently selected.
Change-Id: I17532bae7ea5fa639ce5d600c67e6c44728ff67f
diff --git a/web/gui/src/main/webapp/onos2.js b/web/gui/src/main/webapp/onos2.js
index 87aa63d..20c679a 100644
--- a/web/gui/src/main/webapp/onos2.js
+++ b/web/gui/src/main/webapp/onos2.js
@@ -347,7 +347,8 @@
function setRadioButtons(vid, btnSet) {
var view = views[vid],
- btnG;
+ btnG,
+ api = {};
// lazily create the buttons...
if (!(btnG = view.radioButtons)) {
@@ -365,10 +366,12 @@
})
.text(txt);
+ btn.id = bid;
btnG.buttonDef[uid] = btn;
if (i === 0) {
button.classed('active', true);
+ btnG.selected = bid;
}
});
@@ -382,6 +385,7 @@
if (!act) {
btnG.selectAll('span').classed('active', false);
button.classed('active', true);
+ btnG.selected = btn.id;
if (isF(btn.cb)) {
btn.cb(view.token(), btn);
}
@@ -389,10 +393,16 @@
});
view.radioButtons = btnG;
+
+ api.selected = function () {
+ return btnG.selected;
+ }
}
// attach the buttons to the masthead
$mastRadio.node().appendChild(btnG.node());
+ // return an api for interacting with the button set
+ return api;
}
function setupGlobalKeys() {
@@ -662,7 +672,7 @@
},
setRadio: function (btnSet) {
- setRadioButtons(this.vid, btnSet);
+ return setRadioButtons(this.vid, btnSet);
},
setKeys: function (keyArg) {
diff --git a/web/gui/src/main/webapp/topo2.css b/web/gui/src/main/webapp/topo2.css
index f485e1e..94e6477 100644
--- a/web/gui/src/main/webapp/topo2.css
+++ b/web/gui/src/main/webapp/topo2.css
@@ -225,8 +225,15 @@
border: 2px solid #555;
}
-#topo svg .suppressed,
-#topo-oibox .suppressed {
+#topo-oibox .onosInst.mastership {
+ opacity: 0.3;
+}
+#topo-oibox .onosInst.mastership.affinity {
+ opacity: 1.0;
+}
+
+
+#topo svg .suppressed {
opacity: 0.2;
}
diff --git a/web/gui/src/main/webapp/topo2.js b/web/gui/src/main/webapp/topo2.js
index e14f020..3a5bacc 100644
--- a/web/gui/src/main/webapp/topo2.js
+++ b/web/gui/src/main/webapp/topo2.js
@@ -112,11 +112,17 @@
};
// radio buttons
- var btnSet = [
- { text: 'All Layers', cb: showAllLayers },
- { text: 'Packet Only', cb: showPacketLayer },
- { text: 'Optical Only', cb: showOpticalLayer }
- ];
+ var layerButtons = [
+ { text: 'All Layers', id: 'all', cb: showAllLayers },
+ { text: 'Packet Only', id: 'pkt', cb: showPacketLayer },
+ { text: 'Optical Only', id: 'opt', cb: showOpticalLayer }
+ ],
+ layerBtnSet,
+ layerBtnDispatch = {
+ all: showAllLayers,
+ pkt: showPacketLayer,
+ opt: showOpticalLayer
+ };
// key bindings
var keyDispatch = {
@@ -129,7 +135,7 @@
P: togglePorts,
U: unpin,
R: resetZoomPan,
- esc: deselectAll
+ esc: handleEscape
};
// state variables
@@ -163,8 +169,8 @@
onosInstances = {},
onosOrder = [],
oiBox,
+ oiShowMaster = false,
- viewMode = 'showAll',
portLabelsOn = false;
// D3 selections
@@ -311,6 +317,14 @@
}
}
+ function handleEscape(view) {
+ if (oiShowMaster) {
+ cancelAffinity();
+ } else {
+ deselectAll();
+ }
+ }
+
// ==============================
// Radio Button Callbacks
@@ -352,13 +366,17 @@
});
}
- function showAllLayers() {
- node.classed('suppressed', false);
- link.classed('suppressed', false);
+ function suppressLayers(b) {
+ node.classed('suppressed', b);
+ link.classed('suppressed', b);
// d3.selectAll('svg .port').classed('inactive', false);
// d3.selectAll('svg .portText').classed('inactive', false);
}
+ function showAllLayers() {
+ suppressLayers(false);
+ }
+
function showPacketLayer() {
node.classed('suppressed', true);
link.classed('suppressed', true);
@@ -371,6 +389,10 @@
unsuppressLayer('opt');
}
+ function restoreLayerState() {
+ layerBtnDispatch[layerBtnSet.selected()]();
+ }
+
// ==============================
// Private functions
@@ -674,6 +696,7 @@
.append('div')
.attr('class', 'onosInst')
.classed('online', function (d) { return d.online; })
+ .on('click', clickInst)
.text(function (d) { return d.id; });
// operate on existing + new onoses here
@@ -685,6 +708,38 @@
.remove();
}
+ function clickInst(d) {
+ var el = d3.select(this),
+ aff = el.classed('affinity');
+ if (!aff) {
+ setAffinity(el, d);
+ } else {
+ cancelAffinity();
+ }
+ }
+
+ function setAffinity(el, d) {
+ d3.selectAll('.onosInst')
+ .classed('mastership', true)
+ .classed('affinity', false);
+ el.classed('affinity', true);
+
+ suppressLayers(true);
+ node.each(function (n) {
+ if (n.master === d.id) {
+ n.el.classed('suppressed', false);
+ }
+ });
+ oiShowMaster = true;
+ }
+
+ function cancelAffinity() {
+ d3.selectAll('.onosInst')
+ .classed('mastership affinity', false);
+ restoreLayerState();
+ oiShowMaster = false;
+ }
+
// ==============================
// force layout modification functions
@@ -1682,7 +1737,7 @@
}
// set our radio buttons and key bindings
- view.setRadio(btnSet);
+ layerBtnSet = view.setRadio(layerButtons);
view.setKeys(keyDispatch);
// patch in our "button bar" for now