Simon Hunt

GUI -- [ONOS-89] - completed device mastership affinity coloring work.

Change-Id: I6d42c41cf30c042171550352ce05325b53560841
1 +/*
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/*
18 + D3 Utilities CSS file
19 +
20 + @author Simon Hunt
21 + */
22 +
23 +#d3u .light.norm.c1 {
24 + color: #1f77b4;
25 +}
26 +
27 +#d3u .light.norm.c2 {
28 + color: #2ca02c;
29 +}
30 +
31 +#d3u .light.norm.c3 {
32 + color: #d62728;
33 +}
34 +
35 +#d3u .light.norm.c4 {
36 + color: #9467bd;
37 +}
38 +
39 +#d3u .light.norm.c5 {
40 + color: #e377c2;
41 +}
42 +
43 +#d3u .light.norm.c6 {
44 + color: #bcbd22;
45 +}
46 +
47 +#d3u .light.norm.c7 {
48 + color: #17becf;
49 +}
50 +
51 +
52 +
53 +#d3u .light.mute.c1 {
54 + color: #aec7e8;
55 +}
56 +
57 +#d3u .light.mute.c2 {
58 + color: #98df8a;
59 +}
60 +
61 +#d3u .light.mute.c3 {
62 + color: #ff9896;
63 +}
64 +
65 +#d3u .light.mute.c4 {
66 + color: #c5b0d5;
67 +}
68 +
69 +#d3u .light.mute.c5 {
70 + color: #f7b6d2;
71 +}
72 +
73 +#d3u .light.mute.c6 {
74 + color: #dbdb8d;
75 +}
76 +
77 +#d3u .light.mute.c7 {
78 + color: #9edae5;
79 +}
80 +
81 +
82 +
83 +#d3u .dark.norm.c1 {
84 + color: #1f77b4;
85 +}
86 +
87 +#d3u .dark.norm.c2 {
88 + color: #2ca02c;
89 +}
90 +
91 +#d3u .dark.norm.c3 {
92 + color: #d62728;
93 +}
94 +
95 +#d3u .dark.norm.c4 {
96 + color: #9467bd;
97 +}
98 +
99 +#d3u .dark.norm.c5 {
100 + color: #e377c2;
101 +}
102 +
103 +#d3u .dark.norm.c6 {
104 + color: #bcbd22;
105 +}
106 +
107 +#d3u .dark.norm.c7 {
108 + color: #17becf;
109 +}
110 +
111 +
112 +
113 +#d3u .dark.mute.c1 {
114 + color: #aec7e8;
115 +}
116 +
117 +#d3u .dark.mute.c2 {
118 + color: #639a56;
119 +}
120 +
121 +#d3u .dark.mute.c3 {
122 + color: #ff9896;
123 +}
124 +
125 +#d3u .dark.mute.c4 {
126 + color: #c5b0d5;
127 +}
128 +
129 +#d3u .dark.mute.c5 {
130 + color: #f7b6d2;
131 +}
132 +
133 +#d3u .dark.mute.c6 {
134 + color: #dbdb8d;
135 +}
136 +
137 +#d3u .dark.mute.c7 {
138 + color: #9edae5;
139 +}
140 +
1 +{
2 + "event": "addInstance",
3 + "payload": {
4 + "id": "onos-leader",
5 + "ip": "192.168.0.5",
6 + "online": true,
7 + "uiAttached": false,
8 + "switches": 0,
9 + "labels": [
10 + "onos-leader",
11 + "192.168.0.5"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "addInstance",
3 + "payload": {
4 + "id": "onos-6",
5 + "ip": "192.168.0.66",
6 + "online": true,
7 + "uiAttached": false,
8 + "switches": 0,
9 + "labels": [
10 + "onos-6",
11 + "192.168.0.66"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "addInstance",
3 + "payload": {
4 + "id": "onos-7",
5 + "ip": "192.168.0.77",
6 + "online": true,
7 + "uiAttached": false,
8 + "switches": 0,
9 + "labels": [
10 + "onos-7",
11 + "192.168.0.77"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-master",
5 + "ip": "192.168.0.7",
6 + "online": true,
7 + "uiAttached": false,
8 + "switches": 300,
9 + "labels": [
10 + "onos-master",
11 + "192.168.0.7"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0002",
5 + "type": "switch",
6 + "online": false,
7 + "master": "192.168.56.101",
8 + "labels": [
9 + "",
10 + "sw-2",
11 + "0000ffffffff0002"
12 + ],
13 + "metaUi": {
14 + "x": 142,
15 + "y": 503
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffffff02",
5 + "type": "roadm",
6 + "online": false,
7 + "master": "192.168.56.101",
8 + "labels": [
9 + "",
10 + "opt-2",
11 + "0000ffffffffff02"
12 + ],
13 + "metaUi": {
14 + "x": 142,
15 + "y": 603
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0006",
5 + "type": "switch",
6 + "online": false,
7 + "master": "onos-master",
8 + "labels": [
9 + "",
10 + "sw-6",
11 + "0000ffffffff0006"
12 + ],
13 + "metaUi": {
14 + "x": 382,
15 + "y": 333
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000a",
5 + "type": "switch",
6 + "online": true,
7 + "master": "onos-slave",
8 + "labels": [
9 + "",
10 + "sw-A",
11 + "0000ffffffff000a"
12 + ],
13 + "metaUi": {
14 + "x": 195,
15 + "y": 259
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000b",
5 + "type": "switch",
6 + "online": false,
7 + "master": "onos-slave",
8 + "labels": [
9 + "",
10 + "sw-B",
11 + "0000ffffffff000b"
12 + ],
13 + "metaUi": {
14 + "x": 52,
15 + "y": 262
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000c",
5 + "type": "switch",
6 + "online": true,
7 + "master": "onos-leader",
8 + "labels": [
9 + "",
10 + "sw-C",
11 + "0000ffffffff000c"
12 + ],
13 + "metaUi": {
14 + "x": 229,
15 + "y": 354
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000d",
5 + "type": "switch",
6 + "online": false,
7 + "master": "onos-leader",
8 + "labels": [
9 + "",
10 + "sw-D",
11 + "0000ffffffff000d"
12 + ],
13 + "metaUi": {
14 + "x": 100,
15 + "y": 357
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000e",
5 + "type": "switch",
6 + "online": true,
7 + "master": "onos-6",
8 + "labels": [
9 + "",
10 + "sw-E",
11 + "0000ffffffff000e"
12 + ],
13 + "metaUi": {
14 + "x": 757,
15 + "y": 267
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff000f",
5 + "type": "switch",
6 + "online": false,
7 + "master": "onos-6",
8 + "labels": [
9 + "",
10 + "sw-F",
11 + "0000ffffffff000f"
12 + ],
13 + "metaUi": {
14 + "x": 877,
15 + "y": 267
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0010",
5 + "type": "switch",
6 + "online": true,
7 + "master": "onos-7",
8 + "labels": [
9 + "",
10 + "sw-1-0",
11 + "0000ffffffff0010"
12 + ],
13 + "metaUi": {
14 + "x": 442,
15 + "y": 508
16 + }
17 + }
18 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0011",
5 + "type": "switch",
6 + "online": false,
7 + "master": "onos-7",
8 + "labels": [
9 + "",
10 + "sw-1-1",
11 + "0000ffffffff0011"
12 + ],
13 + "metaUi": {
14 + "x": 576,
15 + "y": 519
16 + }
17 + }
18 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "192.168.56.101",
5 + "ip": "192.168.56.101",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 4,
9 + "labels": [
10 + "192.168.56.101",
11 + "192.168.56.101"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-2",
5 + "ip": "192.168.0.2",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 3,
9 + "labels": [
10 + "onos-2",
11 + "192.168.0.2"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-leader",
5 + "ip": "192.168.0.5",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 0,
9 + "labels": [
10 + "onos-leader",
11 + "192.168.0.5"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-master",
5 + "ip": "192.168.0.7",
6 + "online": true,
7 + "uiAttached": true,
8 + "switches": 300,
9 + "labels": [
10 + "onos-master",
11 + "192.168.0.7"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-slave",
5 + "ip": "192.168.0.11",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 17,
9 + "labels": [
10 + "onos-slave",
11 + "192.168.0.11"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-6",
5 + "ip": "192.168.0.66",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 17,
9 + "labels": [
10 + "onos-6",
11 + "192.168.0.66"
12 + ]
13 + }
14 +}
1 +{
2 + "event": "updateInstance",
3 + "payload": {
4 + "id": "onos-7",
5 + "ip": "192.168.0.77",
6 + "online": false,
7 + "uiAttached": false,
8 + "switches": 17,
9 + "labels": [
10 + "onos-7",
11 + "192.168.0.77"
12 + ]
13 + }
14 +}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 "id": "of:0000ffffffff0007", 4 "id": "of:0000ffffffff0007",
5 "type": "switch", 5 "type": "switch",
6 "online": true, 6 "online": true,
7 - "master": "192.168.56.101", 7 + "master": "onos-master",
8 "labels": [ 8 "labels": [
9 "", 9 "",
10 "sw-7", 10 "sw-7",
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
4 ], 4 ],
5 "title": "Color-Tweaking Scenario", 5 "title": "Color-Tweaking Scenario",
6 "params": { 6 "params": {
7 - "lastAuto": 12 7 + "lastAuto": 29
8 }, 8 },
9 "description": [ 9 "description": [
10 "Press 'S' to load initial events." 10 "Press 'S' to load initial events."
......
...@@ -79,12 +79,12 @@ ...@@ -79,12 +79,12 @@
79 } 79 }
80 80
81 #topo svg .node.device.online { 81 #topo svg .node.device.online {
82 - fill: #17f; 82 + fill: #6e7fa3;
83 } 83 }
84 84
85 /* note: device is offline without the 'online' class */ 85 /* note: device is offline without the 'online' class */
86 #topo svg .node.device text { 86 #topo svg .node.device text {
87 - fill: #aaa; 87 + fill: #bbb;
88 font: 10pt sans-serif; 88 font: 10pt sans-serif;
89 } 89 }
90 90
...@@ -102,7 +102,7 @@ ...@@ -102,7 +102,7 @@
102 fill: #f90; 102 fill: #f90;
103 } 103 }
104 #topo svg .node.device.online .glyphIcon rect { 104 #topo svg .node.device.online .glyphIcon rect {
105 - fill: #8ab; 105 + fill: #ccc;
106 } 106 }
107 #topo svg .node.device.online .glyphIcon use { 107 #topo svg .node.device.online .glyphIcon use {
108 fill: #000; 108 fill: #000;
......
...@@ -190,7 +190,8 @@ ...@@ -190,7 +190,8 @@
190 oiBox, 190 oiBox,
191 oiShowMaster = false, 191 oiShowMaster = false,
192 portLabelsOn = false, 192 portLabelsOn = false,
193 - cat7 = d3u.cat7(); 193 + cat7 = d3u.cat7(),
194 + colorAffinity = false;
194 195
195 var hoverModeAll = 1, 196 var hoverModeAll = 1,
196 hoverModeFlows = 2, 197 hoverModeFlows = 2,
...@@ -349,7 +350,7 @@ ...@@ -349,7 +350,7 @@
349 } else if (detailPane.isVisible()) { 350 } else if (detailPane.isVisible()) {
350 deselectAll(); 351 deselectAll();
351 } else if (oiBox.isVisible()) { 352 } else if (oiBox.isVisible()) {
352 - oiBox.hide(); 353 + hideInstances();
353 } else if (summaryPane.isVisible()) { 354 } else if (summaryPane.isVisible()) {
354 cancelSummary(); 355 cancelSummary();
355 } 356 }
...@@ -864,20 +865,28 @@ ...@@ -864,20 +865,28 @@
864 return true; 865 return true;
865 } 866 }
866 867
867 - function colorAffinity(on) {
868 - // FIXME: need to code this portion up.
869 - }
870 -
871 function toggleInstances() { 868 function toggleInstances() {
872 if (!oiBox.isVisible()) { 869 if (!oiBox.isVisible()) {
873 - oiBox.show(); 870 + showInstances();
874 - colorAffinity(true);
875 } else { 871 } else {
876 - oiBox.hide(); 872 + hideInstances();
877 - colorAffinity(false);
878 } 873 }
879 } 874 }
880 875
876 + function showInstances() {
877 + oiBox.show();
878 + colorAffinity = true;
879 + updateDeviceColors();
880 + }
881 +
882 + function hideInstances() {
883 + oiBox.hide();
884 + colorAffinity = false;
885 + cancelAffinity();
886 + updateDeviceColors();
887 + }
888 +
889 +
881 function toggleSummary() { 890 function toggleSummary() {
882 if (!summaryPane.isVisible()) { 891 if (!summaryPane.isVisible()) {
883 requestSummary(); 892 requestSummary();
...@@ -1024,7 +1033,7 @@ ...@@ -1024,7 +1033,7 @@
1024 y: pad, 1033 y: pad,
1025 width: dim.w - pad*2, 1034 width: dim.w - pad*2,
1026 height: dim.h - pad*2, 1035 height: dim.h - pad*2,
1027 - rx: 8 1036 + rx: 6
1028 }; 1037 };
1029 } 1038 }
1030 1039
...@@ -1691,7 +1700,6 @@ ...@@ -1691,7 +1700,6 @@
1691 }); 1700 });
1692 1701
1693 node.filter('.host').each(function (d) { 1702 node.filter('.host').each(function (d) {
1694 - //var node = d3.select(this);
1695 var node = d.el; 1703 var node = d.el;
1696 // TODO: appropriate update of host visuals 1704 // TODO: appropriate update of host visuals
1697 }); 1705 });
...@@ -1753,7 +1761,7 @@ ...@@ -1753,7 +1761,7 @@
1753 }); 1761 });
1754 1762
1755 // operate on both existing and new nodes, if necessary 1763 // operate on both existing and new nodes, if necessary
1756 - //node .foo() .bar() ... 1764 + updateDeviceColors();
1757 1765
1758 // operate on exiting nodes: 1766 // operate on exiting nodes:
1759 // Note that the node is removed after 2 seconds. 1767 // Note that the node is removed after 2 seconds.
...@@ -1791,6 +1799,62 @@ ...@@ -1791,6 +1799,62 @@
1791 network.force.resume(); 1799 network.force.resume();
1792 } 1800 }
1793 1801
1802 + // note: these are the device icon colors without affinity
1803 + var deviceColor = {
1804 + sel: '#f90',
1805 + light: {
1806 + online: {
1807 + glyph: '#000',
1808 + rect: '#ddd',
1809 + },
1810 + offline: {
1811 + glyph: '#888',
1812 + rect: '#bbb'
1813 + }
1814 + },
1815 + dark: {
1816 + online: {
1817 + glyph: '#000',
1818 + rect: '#ddd'
1819 + },
1820 + offline: {
1821 + glyph: '#888',
1822 + rect: '#bbb'
1823 + }
1824 + }
1825 + };
1826 +
1827 + function devBaseColor(d) {
1828 + var t = network.view.getTheme(),
1829 + o = d.online ? 'online' : 'offline';
1830 + return deviceColor[t][o];
1831 + }
1832 +
1833 + function setDeviceColor(d) {
1834 + var o = d.online,
1835 + s = d.el.classed('selected'),
1836 + c = devBaseColor(d),
1837 + a = instColor(d.master, o),
1838 + g, r,
1839 + icon = d.el.select('g.deviceIcon');
1840 +
1841 + if (s) {
1842 + g = c.glyph;
1843 + r = deviceColor.sel;
1844 + } else if (colorAffinity) {
1845 + g = o ? a : c.glyph;
1846 + r = o ? c.rect : a;
1847 + } else {
1848 + g = c.glyph;
1849 + r = c.rect;
1850 + }
1851 +
1852 + icon.select('use')
1853 + .style('fill', g);
1854 + icon.select('rect')
1855 + .style('fill', r);
1856 + }
1857 +
1794 function addDeviceIcon(node, box, noLabel, iid) { 1858 function addDeviceIcon(node, box, noLabel, iid) {
1795 var cfg = config.icons.device, 1859 var cfg = config.icons.device,
1796 dx, 1860 dx,
...@@ -1915,7 +1979,7 @@ ...@@ -1915,7 +1979,7 @@
1915 webSock.ws.onopen = function() { 1979 webSock.ws.onopen = function() {
1916 noWebSock(false); 1980 noWebSock(false);
1917 requestSummary(); 1981 requestSummary();
1918 - oiBox.show(); 1982 + showInstances();
1919 }; 1983 };
1920 1984
1921 webSock.ws.onmessage = function(m) { 1985 webSock.ws.onmessage = function(m) {
...@@ -2053,6 +2117,7 @@ ...@@ -2053,6 +2117,7 @@
2053 selectOrder.push(obj.id); 2117 selectOrder.push(obj.id);
2054 2118
2055 n.classed('selected', true); 2119 n.classed('selected', true);
2120 + updateDeviceColors(obj);
2056 updateDetailPane(); 2121 updateDetailPane();
2057 } 2122 }
2058 2123
...@@ -2066,6 +2131,7 @@ ...@@ -2066,6 +2131,7 @@
2066 if (idx >= 0) { 2131 if (idx >= 0) {
2067 selectOrder.splice(idx, 1); 2132 selectOrder.splice(idx, 1);
2068 } 2133 }
2134 + updateDeviceColors(obj.obj);
2069 } 2135 }
2070 } 2136 }
2071 2137
...@@ -2074,12 +2140,18 @@ ...@@ -2074,12 +2140,18 @@
2074 node.classed('selected', false); 2140 node.classed('selected', false);
2075 selections = {}; 2141 selections = {};
2076 selectOrder = []; 2142 selectOrder = [];
2143 + updateDeviceColors();
2077 updateDetailPane(); 2144 updateDetailPane();
2078 } 2145 }
2079 2146
2080 - // update the state of the sumary pane 2147 + function updateDeviceColors(d) {
2081 - function updateSummaryPane() { 2148 + if (d) {
2082 - 2149 + setDeviceColor(d);
2150 + } else {
2151 + node.filter('.device').each(function (d) {
2152 + setDeviceColor(d);
2153 + });
2154 + }
2083 } 2155 }
2084 2156
2085 // update the state of the detail pane, based on current selections 2157 // update the state of the detail pane, based on current selections
...@@ -2591,8 +2663,7 @@ ...@@ -2591,8 +2663,7 @@
2591 2663
2592 function theme(view, ctx, flags) { 2664 function theme(view, ctx, flags) {
2593 updateInstances(); 2665 updateInstances();
2594 - // TODO: update other theme-affected elements 2666 + updateDeviceColors();
2595 -
2596 } 2667 }
2597 2668
2598 function birdTranslate(w, h) { 2669 function birdTranslate(w, h) {
......