Simon Hunt
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
...@@ -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');
......