Simon Hunt
Committed by Gerrit Code Review

GUI -- Added CSS classes for primary, secondary, animated, and optical links

 - refactored showTraffic(...) to handle the updated payload.
 - created 'traffic' scenario:: run with ... webapp/index2.html#topo,traffic?local

Change-Id: I5e3a33abcbc9c82f751165b4f52807f7cd59ef03
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
2 "event": "requestTraffic", 2 "event": "requestTraffic",
3 "sid": 2, 3 "sid": 2,
4 "payload": { 4 "payload": {
5 - "ids": [ "00:00:00:00:00:01/-1", "00:00:00:00:00:02/-1" ] 5 + "ids": [ "00:00:00:00:00:01/-1", "00:00:00:00:00:02/-1" ],
6 + "hover": ""
6 } 7 }
7 } 8 }
......
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffff0003/4-of:0000ffffffffff03/1",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffff0003",
8 + "srcPort": "4",
9 + "dst": "of:0000ffffffffff03",
10 + "dstPort": "1",
11 + "props" : {
12 + "BW": "90 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffffff08/4-of:0000ffffffffff03/1",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffffff08",
8 + "srcPort": "4",
9 + "dst": "of:0000ffffffffff03",
10 + "dstPort": "1",
11 + "props" : {
12 + "BW": "90 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "event": "addHost",
3 + "payload": {
4 + "id": "0E:2A:69:30:13:86/-1",
5 + "ingress": "0E:2A:69:30:13:86/-1/0-of:0000ffffffff0003/101",
6 + "egress": "of:0000ffffffff0003/101-0E:2A:69:30:13:86/-1/0",
7 + "cp": {
8 + "device": "of:0000ffffffff0003",
9 + "port": 101
10 + },
11 + "labels": [
12 + "1.2.3.4",
13 + "0E:2A:69:30:13:86"
14 + ],
15 + "props": {}
16 + }
17 +}
1 +{
2 + "event": "addHost",
3 + "payload": {
4 + "id": "0E:2A:69:30:13:88/-1",
5 + "ingress": "0E:2A:69:30:13:88/-1/0-of:0000ffffffff0007/101",
6 + "egress": "of:0000ffffffff0007/101-0E:2A:69:30:13:86/-1/0",
7 + "cp": {
8 + "device": "of:0000ffffffff0007",
9 + "port": 101
10 + },
11 + "labels": [
12 + "4.5.7.6",
13 + "0E:2A:69:30:13:88"
14 + ],
15 + "props": {}
16 + }
17 +}
1 +{
2 + "event": "addHost",
3 + "payload": {
4 + "id": "0E:2A:69:30:13:aa/-1",
5 + "ingress": "0E:2A:69:30:13:aa/-1/0-of:0000ffffffff0008/101",
6 + "egress": "of:0000ffffffff0008/101-0E:2A:69:30:13:aa/-1/0",
7 + "cp": {
8 + "device": "of:0000ffffffff0008",
9 + "port": 101
10 + },
11 + "labels": [
12 + "12.13.14.15",
13 + "0E:2A:69:30:13:aa"
14 + ],
15 + "props": {}
16 + }
17 +}
1 +{
2 + "event": "showTraffic",
3 + "sid": 1,
4 + "payload": {
5 + "paths": [
6 + {
7 + "intentId": "0x4321",
8 + "links": [
9 + "0E:2A:69:30:13:86/-1/0-of:0000ffffffff0003/101",
10 + "0E:2A:69:30:13:aa/-1/0-of:0000ffffffff0008/101"
11 + ],
12 + "class": "primary"
13 + },
14 + {
15 + "intentId": "0xbab3",
16 + "links": [
17 + "of:0000ffffffff0003/4-of:0000ffffffffff03/1",
18 + "of:0000ffffffff0008/4-of:0000ffffffffff08/1",
19 + "of:0000ffffffffff08/4-of:0000ffffffffff03/1"
20 + ],
21 + "class": "primary optical"
22 + }
23 + ]
24 + }
25 +}
1 +{
2 + "event": "showTraffic",
3 + "sid": 1,
4 + "payload": {
5 + "paths": [
6 + {
7 + "intentId": "0x4321",
8 + "links": [
9 + "0E:2A:69:30:13:86/-1/0-of:0000ffffffff0003/101",
10 + "0E:2A:69:30:13:aa/-1/0-of:0000ffffffff0008/101"
11 + ],
12 + "class": "secondary"
13 + },
14 + {
15 + "intentId": "0xbab3",
16 + "links": [
17 + "of:0000ffffffff0003/4-of:0000ffffffffff03/1",
18 + "of:0000ffffffff0008/4-of:0000ffffffffff08/1",
19 + "of:0000ffffffffff08/4-of:0000ffffffffff03/1"
20 + ],
21 + "class": "secondary optical"
22 + }
23 + ]
24 + }
25 +}
1 +{
2 + "event": "showTraffic",
3 + "sid": 1,
4 + "payload": {
5 + "paths": [
6 + {
7 + "intentId": "0x4321",
8 + "links": [
9 + "0E:2A:69:30:13:86/-1/0-of:0000ffffffff0003/101",
10 + "0E:2A:69:30:13:aa/-1/0-of:0000ffffffff0008/101"
11 + ],
12 + "class": "animated"
13 + },
14 + {
15 + "intentId": "0xbab3",
16 + "links": [
17 + "of:0000ffffffff0003/4-of:0000ffffffffff03/1",
18 + "of:0000ffffffff0008/4-of:0000ffffffffff08/1",
19 + "of:0000ffffffffff08/4-of:0000ffffffffff03/1"
20 + ],
21 + "class": "animated optical"
22 + }
23 + ]
24 + }
25 +}
1 +{
2 + "event": "showTraffic",
3 + "sid": 1,
4 + "payload": {
5 + "paths": [
6 + {
7 + "intentId": "0x1234",
8 + "links": [
9 + "of:0000ffffffff0008/2-of:0000ffffffff0003/1"
10 + ],
11 + "class": "primary"
12 + },
13 + {
14 + "intentId": "0x4321",
15 + "links": [
16 + "of:0000ffffffff0003/9-of:0000ffffffff0007/2"
17 + ],
18 + "class": "secondary"
19 + },
20 + {
21 + "intentId": "0xbabe",
22 + "links": [
23 + "of:0000ffffffff0008/4-of:0000ffffffff0007/1"
24 + ],
25 + "class": "animated"
26 + },
27 + {
28 + "intentId": "0xbab1",
29 + "links": [
30 + "of:0000ffffffff0008/4-of:0000ffffffffff08/1"
31 + ],
32 + "class": "primary optical"
33 + },
34 + {
35 + "intentId": "0xbab2",
36 + "links": [
37 + "of:0000ffffffff0003/4-of:0000ffffffffff03/1"
38 + ],
39 + "class": "secondary optical"
40 + },
41 + {
42 + "intentId": "0xbab3",
43 + "links": [
44 + "of:0000ffffffffff08/4-of:0000ffffffffff03/1"
45 + ],
46 + "class": "animated optical"
47 + }
48 + ]
49 + }
50 +}
1 +{
2 + "event": "showTraffic",
3 + "sid": 1,
4 + "payload": {
5 + "paths": [
6 + ]
7 + }
8 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0008",
5 + "type": "switch",
6 + "online": true,
7 + "labels": [
8 + "0000ffffffff0008",
9 + "FF:FF:FF:FF:00:08",
10 + "sw-8"
11 + ],
12 + "metaUi": {
13 + "x": 734,
14 + "y": 477
15 + }
16 + }
17 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0003",
5 + "type": "switch",
6 + "online": true,
7 + "labels": [
8 + "0000ffffffff0003",
9 + "FF:FF:FF:FF:00:03",
10 + "sw-3"
11 + ],
12 + "metaUi": {
13 + "x": 282,
14 + "y": 503
15 + }
16 + }
17 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffff0007",
5 + "type": "switch",
6 + "online": true,
7 + "labels": [
8 + "0000ffffffff0007",
9 + "FF:FF:FF:FF:00:07",
10 + "sw-7"
11 + ],
12 + "metaUi": {
13 + "x": 530,
14 + "y": 330
15 + }
16 + }
17 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffffff08",
5 + "type": "roadm",
6 + "online": true,
7 + "labels": [
8 + "0000ffffffffff08",
9 + "FF:FF:FF:FF:FF:08",
10 + "opt-8"
11 + ],
12 + "metaUi": {
13 + "x": 734,
14 + "y": 577
15 + }
16 + }
17 +}
1 +{
2 + "event": "addDevice",
3 + "payload": {
4 + "id": "of:0000ffffffffff03",
5 + "type": "roadm",
6 + "online": true,
7 + "labels": [
8 + "0000ffffffffff03",
9 + "FF:FF:FF:FF:FF:03",
10 + "opt-3"
11 + ],
12 + "metaUi": {
13 + "x": 282,
14 + "y": 603
15 + }
16 + }
17 +}
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffff0003/9-of:0000ffffffff0007/2",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffff0003",
8 + "srcPort": "9",
9 + "dst": "of:0000ffffffff0007",
10 + "dstPort": "2",
11 + "props" : {
12 + "BW": "120 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffff0008/2-of:0000ffffffff0003/1",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffff0008",
8 + "srcPort": "2",
9 + "dst": "of:0000ffffffff0003",
10 + "dstPort": "1",
11 + "props" : {
12 + "BW": "70 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffff0008/4-of:0000ffffffff0007/1",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffff0008",
8 + "srcPort": "4",
9 + "dst": "of:0000ffffffff0007",
10 + "dstPort": "1",
11 + "props" : {
12 + "BW": "90 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "event": "addLink",
3 + "payload": {
4 + "id": "of:0000ffffffff0008/4-of:0000ffffffffff08/1",
5 + "type": "direct",
6 + "linkWidth": 2,
7 + "src": "of:0000ffffffff0008",
8 + "srcPort": "4",
9 + "dst": "of:0000ffffffffff08",
10 + "dstPort": "1",
11 + "props" : {
12 + "BW": "90 Gb"
13 + }
14 + }
15 +}
1 +{
2 + "comments": [
3 + "Stepping through showTraffic"
4 + ],
5 + "title": "Show Traffic Scenario",
6 + "params": {
7 + "lastAuto": 14
8 + },
9 + "description": [
10 + "Figure out primary, secondary and animated link visualizations.",
11 + "",
12 + "Press 'S' to load initial events.",
13 + "",
14 + "Press spacebar to complete the scenario..."
15 + ]
16 +}
...@@ -108,10 +108,33 @@ ...@@ -108,10 +108,33 @@
108 opacity: .7; 108 opacity: .7;
109 } 109 }
110 110
111 -#topo svg .link.showPath { 111 +#topo svg .link.primary {
112 - stroke: #f00; 112 + stroke: #f11;
113 stroke-width: 6px; 113 stroke-width: 6px;
114 } 114 }
115 +#topo svg .link.secondary {
116 + stroke: rgba(255,100,100,0.5);
117 + stroke-width: 4px;
118 +}
119 +#topo svg .link.animated {
120 + stroke: #f11;
121 + stroke-width: 10px;
122 + stroke-dasharray: 8 8
123 +}
124 +
125 +#topo svg .link.primary.optical {
126 + stroke: #74f;
127 + stroke-width: 6px;
128 +}
129 +#topo svg .link.secondary.optical {
130 + stroke: rgba(128,64,255,0.5);
131 + stroke-width: 4px;
132 +}
133 +#topo svg .link.animated.optical {
134 + stroke: #74f;
135 + stroke-width: 10px;
136 + stroke-dasharray: 8 8
137 +}
115 138
116 139
117 /* Fly-in details pane */ 140 /* Fly-in details pane */
......
...@@ -120,9 +120,9 @@ ...@@ -120,9 +120,9 @@
120 120
121 // key bindings 121 // key bindings
122 var keyDispatch = { 122 var keyDispatch = {
123 - //M: testMe, // TODO: remove (testing only) 123 + M: testMe, // TODO: remove (testing only)
124 - //S: injectStartupEvents, // TODO: remove (testing only) 124 + S: injectStartupEvents, // TODO: remove (testing only)
125 - //space: injectTestEvent, // TODO: remove (testing only) 125 + space: injectTestEvent, // TODO: remove (testing only)
126 126
127 B: toggleBg, 127 B: toggleBg,
128 L: cycleLabels, 128 L: cycleLabels,
...@@ -159,8 +159,8 @@ ...@@ -159,8 +159,8 @@
159 selectOrder = [], 159 selectOrder = [],
160 selections = {}, 160 selections = {},
161 hovered = null, 161 hovered = null,
162 + antTimer = null,
162 163
163 - highlighted = null,
164 viewMode = 'showAll', 164 viewMode = 'showAll',
165 portLabelsOn = false; 165 portLabelsOn = false;
166 166
...@@ -503,23 +503,19 @@ ...@@ -503,23 +503,19 @@
503 } 503 }
504 504
505 function showTraffic(data) { 505 function showTraffic(data) {
506 - // TODO: review - making sure we are handling the payload correctly.
507 - // TODO: handle 'class' of link: primary, secondary, animated...
508 fnTrace('showTraffic', data.payload.id); 506 fnTrace('showTraffic', data.payload.id);
509 var paths = data.payload.paths; 507 var paths = data.payload.paths;
510 508
511 // Revert any links hilighted previously. 509 // Revert any links hilighted previously.
512 - network.links.forEach(function (d) { 510 + link.classed('primary secondary animated optical', false);
513 - d.el.classed('showPath', false);
514 - });
515 511
516 // Now hilight all links in the paths payload. 512 // Now hilight all links in the paths payload.
517 - paths.forEach(function (d) { 513 + paths.forEach(function (p) {
518 - var links = d.links; 514 + var cls = p.class;
519 - links.forEach(function (d, i) { 515 + p.links.forEach(function (id) {
520 - var link = network.lookup[d]; 516 + var lnk = network.lookup[id];
521 - if (link) { 517 + if (lnk) {
522 - link.el.classed('showPath', true); 518 + lnk.el.classed(cls, true);
523 } 519 }
524 }); 520 });
525 }); 521 });
...@@ -1174,8 +1170,10 @@ ...@@ -1174,8 +1170,10 @@
1174 _send : function(message) { 1170 _send : function(message) {
1175 if (webSock.ws) { 1171 if (webSock.ws) {
1176 webSock.ws.send(message); 1172 webSock.ws.send(message);
1177 - } else { 1173 + } else if (config.useLiveData) {
1178 network.view.alert('no web socket open\n\n' + message); 1174 network.view.alert('no web socket open\n\n' + message);
1175 + } else {
1176 + console.log('WS Send: ' + JSON.stringify(message));
1179 } 1177 }
1180 } 1178 }
1181 1179
...@@ -1536,6 +1534,8 @@ ...@@ -1536,6 +1534,8 @@
1536 d3.select(self).classed('fixed', true); 1534 d3.select(self).classed('fixed', true);
1537 if (config.useLiveData) { 1535 if (config.useLiveData) {
1538 sendUpdateMeta(d); 1536 sendUpdateMeta(d);
1537 + } else {
1538 + console.log('Moving node ' + d.id + ' to [' + d.x + ',' + d.y + ']');
1539 } 1539 }
1540 } 1540 }
1541 1541
...@@ -1599,6 +1599,21 @@ ...@@ -1599,6 +1599,21 @@
1599 1599
1600 // Load map data asynchronously; complete startup after that.. 1600 // Load map data asynchronously; complete startup after that..
1601 loadGeoJsonData(); 1601 loadGeoJsonData();
1602 +
1603 + // start the and timer
1604 + var dashIdx = 0;
1605 + antTimer = setInterval(function () {
1606 + // TODO: figure out how to choose Src-->Dst and Dst-->Src, per link
1607 + dashIdx = dashIdx === 0 ? 14 : dashIdx - 2;
1608 + d3.selectAll('.animated').style('stroke-dashoffset', dashIdx);
1609 + }, 35);
1610 + }
1611 +
1612 + function unload(view, ctx, flags) {
1613 + if (antTimer) {
1614 + clearInterval(antTimer);
1615 + antTimer = null;
1616 + }
1602 } 1617 }
1603 1618
1604 // TODO: move these to config/state portion of script 1619 // TODO: move these to config/state portion of script
...@@ -1687,6 +1702,7 @@ ...@@ -1687,6 +1702,7 @@
1687 onos.ui.addView('topo', { 1702 onos.ui.addView('topo', {
1688 preload: preload, 1703 preload: preload,
1689 load: load, 1704 load: load,
1705 + unload: unload,
1690 resize: resize 1706 resize: resize
1691 }); 1707 });
1692 1708
......