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