Committed by
Gerrit Code Review
GUI -- [ONOS-89] Creating affinity colors for ONOS instances. (WIP)
- added d3utils.cat7() to provide color scales. - added 'equals' and 'dash' ids for key binding. - added theme() callback to let views know when the theme changed. - re-bound test keys (0, dash, equals) Change-Id: Ie6c6140451ddab567e26c2ea17d65395fa9cc829
Showing
3 changed files
with
144 additions
and
9 deletions
| ... | @@ -119,10 +119,100 @@ | ... | @@ -119,10 +119,100 @@ |
| 119 | .attr('in', String); | 119 | .attr('in', String); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | + // --- Ordinal scales for 7 values. | ||
| 123 | + // TODO: tune colors for light and dark themes | ||
| 124 | + | ||
| 125 | + var lightNorm = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd', '#e377c2', '#bcbd22', '#17becf'], | ||
| 126 | + lightMute = ['#aec7e8', '#98df8a', '#ff9896', '#c5b0d5', '#f7b6d2', '#dbdb8d', '#9edae5'], | ||
| 127 | + darkNorm = ['#1f77b4', '#2ca02c', '#d62728', '#9467bd', '#e377c2', '#bcbd22', '#17becf'], | ||
| 128 | + darkMute = ['#aec7e8', '#98df8a', '#ff9896', '#c5b0d5', '#f7b6d2', '#dbdb8d', '#9edae5']; | ||
| 129 | + | ||
| 130 | + function cat7() { | ||
| 131 | + var colors = { | ||
| 132 | + light: { | ||
| 133 | + norm: d3.scale.ordinal().range(lightNorm), | ||
| 134 | + mute: d3.scale.ordinal().range(lightMute) | ||
| 135 | + }, | ||
| 136 | + dark: { | ||
| 137 | + norm: d3.scale.ordinal().range(darkNorm), | ||
| 138 | + mute: d3.scale.ordinal().range(darkMute) | ||
| 139 | + } | ||
| 140 | + }, | ||
| 141 | + tcid = 'd3utilTestCard'; | ||
| 142 | + | ||
| 143 | + function get(id, muted, theme) { | ||
| 144 | + // NOTE: since we are lazily assigning domain ids, we need to | ||
| 145 | + // get the color from all 4 scales, to keep the domains | ||
| 146 | + // in sync. | ||
| 147 | + var ln = colors.light.norm(id), | ||
| 148 | + lm = colors.light.mute(id), | ||
| 149 | + dn = colors.dark.norm(id), | ||
| 150 | + dm = colors.dark.mute(id); | ||
| 151 | + if (theme === 'dark') { | ||
| 152 | + return muted ? dm : dn; | ||
| 153 | + } else { | ||
| 154 | + return muted ? lm : ln; | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + function testCard(svg) { | ||
| 159 | + var g = svg.select('g#' + tcid), | ||
| 160 | + dom = d3.range(7), | ||
| 161 | + k, muted, theme, what; | ||
| 162 | + | ||
| 163 | + if (!g.empty()) { | ||
| 164 | + g.remove(); | ||
| 165 | + | ||
| 166 | + } else { | ||
| 167 | + g = svg.append('g') | ||
| 168 | + .attr('id', tcid) | ||
| 169 | + .attr('transform', 'scale(4)translate(20,20)'); | ||
| 170 | + | ||
| 171 | + for (k=0; k<4; k++) { | ||
| 172 | + muted = k%2; | ||
| 173 | + what = muted ? ' muted' : ' normal'; | ||
| 174 | + theme = k < 2 ? 'light' : 'dark'; | ||
| 175 | + dom.forEach(function (id, i) { | ||
| 176 | + var x = i * 20, | ||
| 177 | + y = k * 20, | ||
| 178 | + f = get(id, muted, theme); | ||
| 179 | + g.append('circle').attr({ | ||
| 180 | + cx: x, | ||
| 181 | + cy: y, | ||
| 182 | + r: 5, | ||
| 183 | + fill: f | ||
| 184 | + }); | ||
| 185 | + }); | ||
| 186 | + g.append('rect').attr({ | ||
| 187 | + x: 140, | ||
| 188 | + y: k * 20 - 5, | ||
| 189 | + width: 32, | ||
| 190 | + height: 10, | ||
| 191 | + rx: 2, | ||
| 192 | + fill: '#888' | ||
| 193 | + }); | ||
| 194 | + g.append('text').text(theme + what) | ||
| 195 | + .attr({ | ||
| 196 | + x: 142, | ||
| 197 | + y: k * 20 + 2, | ||
| 198 | + fill: 'white' | ||
| 199 | + }) | ||
| 200 | + .style('font-size', '4pt'); | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + return { | ||
| 206 | + testCard: testCard, | ||
| 207 | + get: get | ||
| 208 | + }; | ||
| 209 | + } | ||
| 210 | + | ||
| 122 | // === register the functions as a library | 211 | // === register the functions as a library |
| 123 | onos.ui.addLib('d3util', { | 212 | onos.ui.addLib('d3util', { |
| 124 | createDragBehavior: createDragBehavior, | 213 | createDragBehavior: createDragBehavior, |
| 125 | - appendGlow: appendGlow | 214 | + appendGlow: appendGlow, |
| 215 | + cat7: cat7 | ||
| 126 | }); | 216 | }); |
| 127 | 217 | ||
| 128 | }(ONOS)); | 218 | }(ONOS)); | ... | ... |
| ... | @@ -93,6 +93,8 @@ | ... | @@ -93,6 +93,8 @@ |
| 93 | case 40: return 'downArrow'; | 93 | case 40: return 'downArrow'; |
| 94 | case 91: return 'cmdLeft'; | 94 | case 91: return 'cmdLeft'; |
| 95 | case 93: return 'cmdRight'; | 95 | case 93: return 'cmdRight'; |
| 96 | + case 187: return 'equals'; | ||
| 97 | + case 189: return 'dash'; | ||
| 96 | case 191: return 'slash'; | 98 | case 191: return 'slash'; |
| 97 | default: | 99 | default: |
| 98 | if ((code >= 48 && code <= 57) || | 100 | if ((code >= 48 && code <= 57) || |
| ... | @@ -446,6 +448,7 @@ | ... | @@ -446,6 +448,7 @@ |
| 446 | current.theme = (current.theme === 'light') ? 'dark' : 'light'; | 448 | current.theme = (current.theme === 'light') ? 'dark' : 'light'; |
| 447 | body.classed('light dark', false); | 449 | body.classed('light dark', false); |
| 448 | body.classed(current.theme, true); | 450 | body.classed(current.theme, true); |
| 451 | + theme(view); | ||
| 449 | return true; | 452 | return true; |
| 450 | } | 453 | } |
| 451 | 454 | ||
| ... | @@ -546,6 +549,13 @@ | ... | @@ -546,6 +549,13 @@ |
| 546 | } | 549 | } |
| 547 | } | 550 | } |
| 548 | 551 | ||
| 552 | + function theme() { | ||
| 553 | + // allow current view to react to theme event... | ||
| 554 | + if (current.view) { | ||
| 555 | + current.view.theme(current.ctx, current.flags); | ||
| 556 | + } | ||
| 557 | + } | ||
| 558 | + | ||
| 549 | // .......................................................... | 559 | // .......................................................... |
| 550 | // View class | 560 | // View class |
| 551 | // Captures state information about a view. | 561 | // Captures state information about a view. |
| ... | @@ -607,7 +617,7 @@ | ... | @@ -607,7 +617,7 @@ |
| 607 | dataLoadError: this.dataLoadError, | 617 | dataLoadError: this.dataLoadError, |
| 608 | alert: this.alert, | 618 | alert: this.alert, |
| 609 | flash: this.flash, | 619 | flash: this.flash, |
| 610 | - theme: this.theme | 620 | + getTheme: this.getTheme |
| 611 | } | 621 | } |
| 612 | }, | 622 | }, |
| 613 | 623 | ||
| ... | @@ -672,6 +682,16 @@ | ... | @@ -672,6 +682,16 @@ |
| 672 | } | 682 | } |
| 673 | }, | 683 | }, |
| 674 | 684 | ||
| 685 | + theme: function (ctx, flags) { | ||
| 686 | + var c = ctx | '', | ||
| 687 | + fn = isF(this.cb.theme); | ||
| 688 | + traceFn('View.theme', this.vid); | ||
| 689 | + if (fn) { | ||
| 690 | + trace('THEME cb for ' + this.vid); | ||
| 691 | + fn(this.token(), c, flags); | ||
| 692 | + } | ||
| 693 | + }, | ||
| 694 | + | ||
| 675 | error: function (ctx, flags) { | 695 | error: function (ctx, flags) { |
| 676 | var c = ctx || '', | 696 | var c = ctx || '', |
| 677 | fn = isF(this.cb.error); | 697 | fn = isF(this.cb.error); |
| ... | @@ -699,7 +719,7 @@ | ... | @@ -699,7 +719,7 @@ |
| 699 | setKeyBindings(keyArg); | 719 | setKeyBindings(keyArg); |
| 700 | }, | 720 | }, |
| 701 | 721 | ||
| 702 | - theme: function () { | 722 | + getTheme: function () { |
| 703 | return current.theme; | 723 | return current.theme; |
| 704 | }, | 724 | }, |
| 705 | 725 | ... | ... |
| ... | @@ -136,9 +136,9 @@ | ... | @@ -136,9 +136,9 @@ |
| 136 | // key bindings | 136 | // key bindings |
| 137 | var keyDispatch = { | 137 | var keyDispatch = { |
| 138 | // TODO: remove these "development only" bindings | 138 | // TODO: remove these "development only" bindings |
| 139 | - M: testMe, | 139 | + 0: testMe, |
| 140 | - S: injectStartupEvents, | 140 | + equals: injectStartupEvents, |
| 141 | - space: injectTestEvent, | 141 | + dash: injectTestEvent, |
| 142 | 142 | ||
| 143 | O: [toggleSummary, 'Toggle ONOS summary pane'], | 143 | O: [toggleSummary, 'Toggle ONOS summary pane'], |
| 144 | I: [toggleInstances, 'Toggle ONOS instances pane'], | 144 | I: [toggleInstances, 'Toggle ONOS instances pane'], |
| ... | @@ -189,7 +189,8 @@ | ... | @@ -189,7 +189,8 @@ |
| 189 | onosOrder = [], | 189 | onosOrder = [], |
| 190 | oiBox, | 190 | oiBox, |
| 191 | oiShowMaster = false, | 191 | oiShowMaster = false, |
| 192 | - portLabelsOn = false; | 192 | + portLabelsOn = false, |
| 193 | + cat7 = d3u.cat7(); | ||
| 193 | 194 | ||
| 194 | var hoverModeAll = 1, | 195 | var hoverModeAll = 1, |
| 195 | hoverModeFlows = 2, | 196 | hoverModeFlows = 2, |
| ... | @@ -240,8 +241,9 @@ | ... | @@ -240,8 +241,9 @@ |
| 240 | // Key Callbacks | 241 | // Key Callbacks |
| 241 | 242 | ||
| 242 | function testMe(view) { | 243 | function testMe(view) { |
| 243 | - //view.alert('Theme is ' + view.theme()); | 244 | + //view.alert('Theme is ' + view.getTheme()); |
| 244 | //view.flash('This is some text'); | 245 | //view.flash('This is some text'); |
| 246 | + cat7.testCard(svg); | ||
| 245 | } | 247 | } |
| 246 | 248 | ||
| 247 | function abortIfLive() { | 249 | function abortIfLive() { |
| ... | @@ -862,12 +864,17 @@ | ... | @@ -862,12 +864,17 @@ |
| 862 | return true; | 864 | return true; |
| 863 | } | 865 | } |
| 864 | 866 | ||
| 867 | + function colorAffinity(on) { | ||
| 868 | + // FIXME: need to code this portion up. | ||
| 869 | + } | ||
| 865 | 870 | ||
| 866 | function toggleInstances() { | 871 | function toggleInstances() { |
| 867 | if (!oiBox.isVisible()) { | 872 | if (!oiBox.isVisible()) { |
| 868 | oiBox.show(); | 873 | oiBox.show(); |
| 874 | + colorAffinity(true); | ||
| 869 | } else { | 875 | } else { |
| 870 | oiBox.hide(); | 876 | oiBox.hide(); |
| 877 | + colorAffinity(false); | ||
| 871 | } | 878 | } |
| 872 | } | 879 | } |
| 873 | 880 | ||
| ... | @@ -1123,6 +1130,13 @@ | ... | @@ -1123,6 +1130,13 @@ |
| 1123 | }); | 1130 | }); |
| 1124 | 1131 | ||
| 1125 | // operate on existing + new onoses here | 1132 | // operate on existing + new onoses here |
| 1133 | + // set the affinity colors... | ||
| 1134 | + onoses.each(function (d) { | ||
| 1135 | + var el = d3.select(this), | ||
| 1136 | + rect = el.select('svg').select('rect'), | ||
| 1137 | + col = instColor(d.id, d.online); | ||
| 1138 | + rect.style('fill', col); | ||
| 1139 | + }); | ||
| 1126 | 1140 | ||
| 1127 | // adjust the panel size appropriately... | 1141 | // adjust the panel size appropriately... |
| 1128 | oiBox.width(instDim.w * onosOrder.length); | 1142 | oiBox.width(instDim.w * onosOrder.length); |
| ... | @@ -1132,6 +1146,10 @@ | ... | @@ -1132,6 +1146,10 @@ |
| 1132 | onoses.exit().remove(); | 1146 | onoses.exit().remove(); |
| 1133 | } | 1147 | } |
| 1134 | 1148 | ||
| 1149 | + function instColor(id, online) { | ||
| 1150 | + return cat7.get(id, !online, network.view.getTheme()); | ||
| 1151 | + } | ||
| 1152 | + | ||
| 1135 | function clickInst(d) { | 1153 | function clickInst(d) { |
| 1136 | var el = d3.select(this), | 1154 | var el = d3.select(this), |
| 1137 | aff = el.classed('affinity'); | 1155 | aff = el.classed('affinity'); |
| ... | @@ -2571,6 +2589,12 @@ | ... | @@ -2571,6 +2589,12 @@ |
| 2571 | .select('g').attr('transform', birdTranslate(w, h)); | 2589 | .select('g').attr('transform', birdTranslate(w, h)); |
| 2572 | } | 2590 | } |
| 2573 | 2591 | ||
| 2592 | + function theme(view, ctx, flags) { | ||
| 2593 | + updateInstances(); | ||
| 2594 | + // TODO: update other theme-affected elements | ||
| 2595 | + | ||
| 2596 | + } | ||
| 2597 | + | ||
| 2574 | function birdTranslate(w, h) { | 2598 | function birdTranslate(w, h) { |
| 2575 | var bdim = config.birdDim; | 2599 | var bdim = config.birdDim; |
| 2576 | return 'translate('+((w-bdim)*.4)+','+((h-bdim)*.1)+')'; | 2600 | return 'translate('+((w-bdim)*.4)+','+((h-bdim)*.1)+')'; |
| ... | @@ -2583,7 +2607,8 @@ | ... | @@ -2583,7 +2607,8 @@ |
| 2583 | preload: preload, | 2607 | preload: preload, |
| 2584 | load: load, | 2608 | load: load, |
| 2585 | unload: unload, | 2609 | unload: unload, |
| 2586 | - resize: resize | 2610 | + resize: resize, |
| 2611 | + theme: theme | ||
| 2587 | }); | 2612 | }); |
| 2588 | 2613 | ||
| 2589 | summaryPane = onos.ui.addFloatingPanel('topo-summary'); | 2614 | summaryPane = onos.ui.addFloatingPanel('topo-summary'); | ... | ... |
-
Please register or login to post a comment