Committed by
Gerrit Code Review
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
Showing
3 changed files
with
87 additions
and
15 deletions
... | @@ -347,7 +347,8 @@ | ... | @@ -347,7 +347,8 @@ |
347 | 347 | ||
348 | function setRadioButtons(vid, btnSet) { | 348 | function setRadioButtons(vid, btnSet) { |
349 | var view = views[vid], | 349 | var view = views[vid], |
350 | - btnG; | 350 | + btnG, |
351 | + api = {}; | ||
351 | 352 | ||
352 | // lazily create the buttons... | 353 | // lazily create the buttons... |
353 | if (!(btnG = view.radioButtons)) { | 354 | if (!(btnG = view.radioButtons)) { |
... | @@ -365,10 +366,12 @@ | ... | @@ -365,10 +366,12 @@ |
365 | }) | 366 | }) |
366 | .text(txt); | 367 | .text(txt); |
367 | 368 | ||
369 | + btn.id = bid; | ||
368 | btnG.buttonDef[uid] = btn; | 370 | btnG.buttonDef[uid] = btn; |
369 | 371 | ||
370 | if (i === 0) { | 372 | if (i === 0) { |
371 | button.classed('active', true); | 373 | button.classed('active', true); |
374 | + btnG.selected = bid; | ||
372 | } | 375 | } |
373 | }); | 376 | }); |
374 | 377 | ||
... | @@ -382,6 +385,7 @@ | ... | @@ -382,6 +385,7 @@ |
382 | if (!act) { | 385 | if (!act) { |
383 | btnG.selectAll('span').classed('active', false); | 386 | btnG.selectAll('span').classed('active', false); |
384 | button.classed('active', true); | 387 | button.classed('active', true); |
388 | + btnG.selected = btn.id; | ||
385 | if (isF(btn.cb)) { | 389 | if (isF(btn.cb)) { |
386 | btn.cb(view.token(), btn); | 390 | btn.cb(view.token(), btn); |
387 | } | 391 | } |
... | @@ -389,10 +393,16 @@ | ... | @@ -389,10 +393,16 @@ |
389 | }); | 393 | }); |
390 | 394 | ||
391 | view.radioButtons = btnG; | 395 | view.radioButtons = btnG; |
396 | + | ||
397 | + api.selected = function () { | ||
398 | + return btnG.selected; | ||
399 | + } | ||
392 | } | 400 | } |
393 | 401 | ||
394 | // attach the buttons to the masthead | 402 | // attach the buttons to the masthead |
395 | $mastRadio.node().appendChild(btnG.node()); | 403 | $mastRadio.node().appendChild(btnG.node()); |
404 | + // return an api for interacting with the button set | ||
405 | + return api; | ||
396 | } | 406 | } |
397 | 407 | ||
398 | function setupGlobalKeys() { | 408 | function setupGlobalKeys() { |
... | @@ -662,7 +672,7 @@ | ... | @@ -662,7 +672,7 @@ |
662 | }, | 672 | }, |
663 | 673 | ||
664 | setRadio: function (btnSet) { | 674 | setRadio: function (btnSet) { |
665 | - setRadioButtons(this.vid, btnSet); | 675 | + return setRadioButtons(this.vid, btnSet); |
666 | }, | 676 | }, |
667 | 677 | ||
668 | setKeys: function (keyArg) { | 678 | setKeys: function (keyArg) { | ... | ... |
... | @@ -225,8 +225,15 @@ | ... | @@ -225,8 +225,15 @@ |
225 | border: 2px solid #555; | 225 | border: 2px solid #555; |
226 | } | 226 | } |
227 | 227 | ||
228 | -#topo svg .suppressed, | 228 | +#topo-oibox .onosInst.mastership { |
229 | -#topo-oibox .suppressed { | 229 | + opacity: 0.3; |
230 | +} | ||
231 | +#topo-oibox .onosInst.mastership.affinity { | ||
232 | + opacity: 1.0; | ||
233 | +} | ||
234 | + | ||
235 | + | ||
236 | +#topo svg .suppressed { | ||
230 | opacity: 0.2; | 237 | opacity: 0.2; |
231 | } | 238 | } |
232 | 239 | ... | ... |
... | @@ -112,11 +112,17 @@ | ... | @@ -112,11 +112,17 @@ |
112 | }; | 112 | }; |
113 | 113 | ||
114 | // radio buttons | 114 | // radio buttons |
115 | - var btnSet = [ | 115 | + var layerButtons = [ |
116 | - { text: 'All Layers', cb: showAllLayers }, | 116 | + { text: 'All Layers', id: 'all', cb: showAllLayers }, |
117 | - { text: 'Packet Only', cb: showPacketLayer }, | 117 | + { text: 'Packet Only', id: 'pkt', cb: showPacketLayer }, |
118 | - { text: 'Optical Only', cb: showOpticalLayer } | 118 | + { text: 'Optical Only', id: 'opt', cb: showOpticalLayer } |
119 | - ]; | 119 | + ], |
120 | + layerBtnSet, | ||
121 | + layerBtnDispatch = { | ||
122 | + all: showAllLayers, | ||
123 | + pkt: showPacketLayer, | ||
124 | + opt: showOpticalLayer | ||
125 | + }; | ||
120 | 126 | ||
121 | // key bindings | 127 | // key bindings |
122 | var keyDispatch = { | 128 | var keyDispatch = { |
... | @@ -129,7 +135,7 @@ | ... | @@ -129,7 +135,7 @@ |
129 | P: togglePorts, | 135 | P: togglePorts, |
130 | U: unpin, | 136 | U: unpin, |
131 | R: resetZoomPan, | 137 | R: resetZoomPan, |
132 | - esc: deselectAll | 138 | + esc: handleEscape |
133 | }; | 139 | }; |
134 | 140 | ||
135 | // state variables | 141 | // state variables |
... | @@ -163,8 +169,8 @@ | ... | @@ -163,8 +169,8 @@ |
163 | onosInstances = {}, | 169 | onosInstances = {}, |
164 | onosOrder = [], | 170 | onosOrder = [], |
165 | oiBox, | 171 | oiBox, |
172 | + oiShowMaster = false, | ||
166 | 173 | ||
167 | - viewMode = 'showAll', | ||
168 | portLabelsOn = false; | 174 | portLabelsOn = false; |
169 | 175 | ||
170 | // D3 selections | 176 | // D3 selections |
... | @@ -311,6 +317,14 @@ | ... | @@ -311,6 +317,14 @@ |
311 | } | 317 | } |
312 | } | 318 | } |
313 | 319 | ||
320 | + function handleEscape(view) { | ||
321 | + if (oiShowMaster) { | ||
322 | + cancelAffinity(); | ||
323 | + } else { | ||
324 | + deselectAll(); | ||
325 | + } | ||
326 | + } | ||
327 | + | ||
314 | // ============================== | 328 | // ============================== |
315 | // Radio Button Callbacks | 329 | // Radio Button Callbacks |
316 | 330 | ||
... | @@ -352,13 +366,17 @@ | ... | @@ -352,13 +366,17 @@ |
352 | }); | 366 | }); |
353 | } | 367 | } |
354 | 368 | ||
355 | - function showAllLayers() { | 369 | + function suppressLayers(b) { |
356 | - node.classed('suppressed', false); | 370 | + node.classed('suppressed', b); |
357 | - link.classed('suppressed', false); | 371 | + link.classed('suppressed', b); |
358 | // d3.selectAll('svg .port').classed('inactive', false); | 372 | // d3.selectAll('svg .port').classed('inactive', false); |
359 | // d3.selectAll('svg .portText').classed('inactive', false); | 373 | // d3.selectAll('svg .portText').classed('inactive', false); |
360 | } | 374 | } |
361 | 375 | ||
376 | + function showAllLayers() { | ||
377 | + suppressLayers(false); | ||
378 | + } | ||
379 | + | ||
362 | function showPacketLayer() { | 380 | function showPacketLayer() { |
363 | node.classed('suppressed', true); | 381 | node.classed('suppressed', true); |
364 | link.classed('suppressed', true); | 382 | link.classed('suppressed', true); |
... | @@ -371,6 +389,10 @@ | ... | @@ -371,6 +389,10 @@ |
371 | unsuppressLayer('opt'); | 389 | unsuppressLayer('opt'); |
372 | } | 390 | } |
373 | 391 | ||
392 | + function restoreLayerState() { | ||
393 | + layerBtnDispatch[layerBtnSet.selected()](); | ||
394 | + } | ||
395 | + | ||
374 | // ============================== | 396 | // ============================== |
375 | // Private functions | 397 | // Private functions |
376 | 398 | ||
... | @@ -674,6 +696,7 @@ | ... | @@ -674,6 +696,7 @@ |
674 | .append('div') | 696 | .append('div') |
675 | .attr('class', 'onosInst') | 697 | .attr('class', 'onosInst') |
676 | .classed('online', function (d) { return d.online; }) | 698 | .classed('online', function (d) { return d.online; }) |
699 | + .on('click', clickInst) | ||
677 | .text(function (d) { return d.id; }); | 700 | .text(function (d) { return d.id; }); |
678 | 701 | ||
679 | // operate on existing + new onoses here | 702 | // operate on existing + new onoses here |
... | @@ -685,6 +708,38 @@ | ... | @@ -685,6 +708,38 @@ |
685 | .remove(); | 708 | .remove(); |
686 | } | 709 | } |
687 | 710 | ||
711 | + function clickInst(d) { | ||
712 | + var el = d3.select(this), | ||
713 | + aff = el.classed('affinity'); | ||
714 | + if (!aff) { | ||
715 | + setAffinity(el, d); | ||
716 | + } else { | ||
717 | + cancelAffinity(); | ||
718 | + } | ||
719 | + } | ||
720 | + | ||
721 | + function setAffinity(el, d) { | ||
722 | + d3.selectAll('.onosInst') | ||
723 | + .classed('mastership', true) | ||
724 | + .classed('affinity', false); | ||
725 | + el.classed('affinity', true); | ||
726 | + | ||
727 | + suppressLayers(true); | ||
728 | + node.each(function (n) { | ||
729 | + if (n.master === d.id) { | ||
730 | + n.el.classed('suppressed', false); | ||
731 | + } | ||
732 | + }); | ||
733 | + oiShowMaster = true; | ||
734 | + } | ||
735 | + | ||
736 | + function cancelAffinity() { | ||
737 | + d3.selectAll('.onosInst') | ||
738 | + .classed('mastership affinity', false); | ||
739 | + restoreLayerState(); | ||
740 | + oiShowMaster = false; | ||
741 | + } | ||
742 | + | ||
688 | // ============================== | 743 | // ============================== |
689 | // force layout modification functions | 744 | // force layout modification functions |
690 | 745 | ||
... | @@ -1682,7 +1737,7 @@ | ... | @@ -1682,7 +1737,7 @@ |
1682 | } | 1737 | } |
1683 | 1738 | ||
1684 | // set our radio buttons and key bindings | 1739 | // set our radio buttons and key bindings |
1685 | - view.setRadio(btnSet); | 1740 | + layerBtnSet = view.setRadio(layerButtons); |
1686 | view.setKeys(keyDispatch); | 1741 | view.setKeys(keyDispatch); |
1687 | 1742 | ||
1688 | // patch in our "button bar" for now | 1743 | // patch in our "button bar" for now | ... | ... |
-
Please register or login to post a comment