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
This commit is contained in:
Simon Hunt 2014-11-14 17:28:09 -08:00 committed by Gerrit Code Review
parent 85314296e1
commit 9462e8c84a
3 changed files with 87 additions and 15 deletions

View File

@ -347,7 +347,8 @@
function setRadioButtons(vid, btnSet) { function setRadioButtons(vid, btnSet) {
var view = views[vid], var view = views[vid],
btnG; btnG,
api = {};
// lazily create the buttons... // lazily create the buttons...
if (!(btnG = view.radioButtons)) { if (!(btnG = view.radioButtons)) {
@ -365,10 +366,12 @@
}) })
.text(txt); .text(txt);
btn.id = bid;
btnG.buttonDef[uid] = btn; btnG.buttonDef[uid] = btn;
if (i === 0) { if (i === 0) {
button.classed('active', true); button.classed('active', true);
btnG.selected = bid;
} }
}); });
@ -382,6 +385,7 @@
if (!act) { if (!act) {
btnG.selectAll('span').classed('active', false); btnG.selectAll('span').classed('active', false);
button.classed('active', true); button.classed('active', true);
btnG.selected = btn.id;
if (isF(btn.cb)) { if (isF(btn.cb)) {
btn.cb(view.token(), btn); btn.cb(view.token(), btn);
} }
@ -389,10 +393,16 @@
}); });
view.radioButtons = btnG; view.radioButtons = btnG;
api.selected = function () {
return btnG.selected;
}
} }
// attach the buttons to the masthead // attach the buttons to the masthead
$mastRadio.node().appendChild(btnG.node()); $mastRadio.node().appendChild(btnG.node());
// return an api for interacting with the button set
return api;
} }
function setupGlobalKeys() { function setupGlobalKeys() {
@ -662,7 +672,7 @@
}, },
setRadio: function (btnSet) { setRadio: function (btnSet) {
setRadioButtons(this.vid, btnSet); return setRadioButtons(this.vid, btnSet);
}, },
setKeys: function (keyArg) { setKeys: function (keyArg) {

View File

@ -225,8 +225,15 @@
border: 2px solid #555; border: 2px solid #555;
} }
#topo svg .suppressed, #topo-oibox .onosInst.mastership {
#topo-oibox .suppressed { opacity: 0.3;
}
#topo-oibox .onosInst.mastership.affinity {
opacity: 1.0;
}
#topo svg .suppressed {
opacity: 0.2; opacity: 0.2;
} }

View File

@ -112,11 +112,17 @@
}; };
// radio buttons // radio buttons
var btnSet = [ var layerButtons = [
{ text: 'All Layers', cb: showAllLayers }, { text: 'All Layers', id: 'all', cb: showAllLayers },
{ text: 'Packet Only', cb: showPacketLayer }, { text: 'Packet Only', id: 'pkt', cb: showPacketLayer },
{ text: 'Optical Only', cb: showOpticalLayer } { text: 'Optical Only', id: 'opt', cb: showOpticalLayer }
]; ],
layerBtnSet,
layerBtnDispatch = {
all: showAllLayers,
pkt: showPacketLayer,
opt: showOpticalLayer
};
// key bindings // key bindings
var keyDispatch = { var keyDispatch = {
@ -129,7 +135,7 @@
P: togglePorts, P: togglePorts,
U: unpin, U: unpin,
R: resetZoomPan, R: resetZoomPan,
esc: deselectAll esc: handleEscape
}; };
// state variables // state variables
@ -163,8 +169,8 @@
onosInstances = {}, onosInstances = {},
onosOrder = [], onosOrder = [],
oiBox, oiBox,
oiShowMaster = false,
viewMode = 'showAll',
portLabelsOn = false; portLabelsOn = false;
// D3 selections // D3 selections
@ -311,6 +317,14 @@
} }
} }
function handleEscape(view) {
if (oiShowMaster) {
cancelAffinity();
} else {
deselectAll();
}
}
// ============================== // ==============================
// Radio Button Callbacks // Radio Button Callbacks
@ -352,13 +366,17 @@
}); });
} }
function showAllLayers() { function suppressLayers(b) {
node.classed('suppressed', false); node.classed('suppressed', b);
link.classed('suppressed', false); link.classed('suppressed', b);
// d3.selectAll('svg .port').classed('inactive', false); // d3.selectAll('svg .port').classed('inactive', false);
// d3.selectAll('svg .portText').classed('inactive', false); // d3.selectAll('svg .portText').classed('inactive', false);
} }
function showAllLayers() {
suppressLayers(false);
}
function showPacketLayer() { function showPacketLayer() {
node.classed('suppressed', true); node.classed('suppressed', true);
link.classed('suppressed', true); link.classed('suppressed', true);
@ -371,6 +389,10 @@
unsuppressLayer('opt'); unsuppressLayer('opt');
} }
function restoreLayerState() {
layerBtnDispatch[layerBtnSet.selected()]();
}
// ============================== // ==============================
// Private functions // Private functions
@ -674,6 +696,7 @@
.append('div') .append('div')
.attr('class', 'onosInst') .attr('class', 'onosInst')
.classed('online', function (d) { return d.online; }) .classed('online', function (d) { return d.online; })
.on('click', clickInst)
.text(function (d) { return d.id; }); .text(function (d) { return d.id; });
// operate on existing + new onoses here // operate on existing + new onoses here
@ -685,6 +708,38 @@
.remove(); .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 // force layout modification functions
@ -1682,7 +1737,7 @@
} }
// set our radio buttons and key bindings // set our radio buttons and key bindings
view.setRadio(btnSet); layerBtnSet = view.setRadio(layerButtons);
view.setKeys(keyDispatch); view.setKeys(keyDispatch);
// patch in our "button bar" for now // patch in our "button bar" for now