Added sample switch data, and augmented selection logic to fetch the detail data from the server.
Also used styled table for displaying properties.
Showing
10 changed files
with
169 additions
and
23 deletions
... | @@ -14,37 +14,37 @@ | ... | @@ -14,37 +14,37 @@ |
14 | "devices": [ | 14 | "devices": [ |
15 | { | 15 | { |
16 | "id": "of:0000000000000001", | 16 | "id": "of:0000000000000001", |
17 | - "labels": ["00:00:00:00:00:00:00:01", "of/::01", "opt-1"], | 17 | + "labels": ["00:00:00:00:00:00:00:01", "SFO-W10", "opt-1"], |
18 | "type": "roadm" | 18 | "type": "roadm" |
19 | }, | 19 | }, |
20 | { | 20 | { |
21 | "id": "of:0000000000000002", | 21 | "id": "of:0000000000000002", |
22 | - "labels": ["00:00:00:00:00:00:00:02", "of/::02", "opt-2"], | 22 | + "labels": ["00:00:00:00:00:00:00:02", "SJC-W10", "opt-2"], |
23 | "type": "roadm" | 23 | "type": "roadm" |
24 | }, | 24 | }, |
25 | { | 25 | { |
26 | "id": "of:0000000000000003", | 26 | "id": "of:0000000000000003", |
27 | - "labels": ["00:00:00:00:00:00:00:03", "of/::03", "opt-3"], | 27 | + "labels": ["00:00:00:00:00:00:00:03", "LAX-W10", "opt-3"], |
28 | "type": "roadm" | 28 | "type": "roadm" |
29 | }, | 29 | }, |
30 | { | 30 | { |
31 | "id": "of:0000000000000004", | 31 | "id": "of:0000000000000004", |
32 | - "labels": ["00:00:00:00:00:00:00:04", "of/::04", "opt-4"], | 32 | + "labels": ["00:00:00:00:00:00:00:04", "SDG-W10", "opt-4"], |
33 | "type": "roadm" | 33 | "type": "roadm" |
34 | }, | 34 | }, |
35 | { | 35 | { |
36 | "id": "of:0000000000000011", | 36 | "id": "of:0000000000000011", |
37 | - "labels": ["00:00:00:00:00:00:00:11", "of/::11", "pkt-11"], | 37 | + "labels": ["00:00:00:00:00:00:00:11", "SFO-pkt", "pkt-11"], |
38 | "type": "switch" | 38 | "type": "switch" |
39 | }, | 39 | }, |
40 | { | 40 | { |
41 | "id": "of:0000000000000012", | 41 | "id": "of:0000000000000012", |
42 | - "labels": ["00:00:00:00:00:00:00:12", "of/::12", "pkt-12"], | 42 | + "labels": ["00:00:00:00:00:00:00:12", "SJC-pkt", "pkt-12"], |
43 | "type": "switch" | 43 | "type": "switch" |
44 | }, | 44 | }, |
45 | { | 45 | { |
46 | "id": "of:0000000000000013", | 46 | "id": "of:0000000000000013", |
47 | - "labels": ["00:00:00:00:00:00:00:13", "of/::13", "pkt-13"], | 47 | + "labels": ["00:00:00:00:00:00:00:13", "LAX-pkt", "pkt-13"], |
48 | "type": "switch" | 48 | "type": "switch" |
49 | } | 49 | } |
50 | ], | 50 | ], | ... | ... |
1 | +{ | ||
2 | + "comment": "sample device properties", | ||
3 | + "id": "of:0000000000000001", | ||
4 | + "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | ||
5 | + "props": { | ||
6 | + "allowed": true, | ||
7 | + "latitude": 37.6, | ||
8 | + "longitude": 122.3, | ||
9 | + "name": "SFO-W10", | ||
10 | + "dpid": "00:00:00:00:00:00:00:01", | ||
11 | + "type": "Roadm" | ||
12 | + } | ||
13 | +} |
1 | +{ | ||
2 | + "comment": "sample device properties", | ||
3 | + "id": "of:0000000000000002", | ||
4 | + "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | ||
5 | + "props": { | ||
6 | + "allowed": true, | ||
7 | + "latitude": 37.3, | ||
8 | + "longitude": 121.9, | ||
9 | + "name": "SJC-W10", | ||
10 | + "dpid": "00:00:00:00:00:00:00:02", | ||
11 | + "type": "Roadm" | ||
12 | + } | ||
13 | +} |
1 | +{ | ||
2 | + "comment": "sample device properties", | ||
3 | + "id": "of:0000000000000003", | ||
4 | + "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | ||
5 | + "props": { | ||
6 | + "allowed": true, | ||
7 | + "latitude": 33.9, | ||
8 | + "longitude": 118.4, | ||
9 | + "name": "LAX-W10", | ||
10 | + "dpid": "00:00:00:00:00:00:00:03", | ||
11 | + "type": "Roadm" | ||
12 | + } | ||
13 | +} |
1 | +{ | ||
2 | + "comment": "sample device properties", | ||
3 | + "id": "of:0000000000000004", | ||
4 | + "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | ||
5 | + "props": { | ||
6 | + "allowed": true, | ||
7 | + "latitude": 32.8, | ||
8 | + "longitude": 117.1, | ||
9 | + "name": "SDG-W10", | ||
10 | + "dpid": "00:00:00:00:00:00:00:04", | ||
11 | + "type": "Roadm" | ||
12 | + } | ||
13 | +} |
... | @@ -38,7 +38,8 @@ | ... | @@ -38,7 +38,8 @@ |
38 | collisionPrevention: true | 38 | collisionPrevention: true |
39 | }, | 39 | }, |
40 | XjsonUrl: 'rs/topology/graph', | 40 | XjsonUrl: 'rs/topology/graph', |
41 | - jsonUrl: 'network.json', | 41 | + jsonUrl: 'json/network.json', |
42 | + jsonPrefix: 'json/', | ||
42 | iconUrl: { | 43 | iconUrl: { |
43 | device: 'img/device.png', | 44 | device: 'img/device.png', |
44 | host: 'img/host.png', | 45 | host: 'img/host.png', |
... | @@ -873,10 +874,6 @@ | ... | @@ -873,10 +874,6 @@ |
873 | 874 | ||
874 | node.classed('selected', true); | 875 | node.classed('selected', true); |
875 | flyinPane(obj); | 876 | flyinPane(obj); |
876 | - | ||
877 | - // TODO animate incoming info pane | ||
878 | - // resize(true); | ||
879 | - // TODO: check bounds of selected node and scroll into view if needed | ||
880 | } | 877 | } |
881 | 878 | ||
882 | function deselectObject(doResize) { | 879 | function deselectObject(doResize) { |
... | @@ -891,23 +888,69 @@ | ... | @@ -891,23 +888,69 @@ |
891 | flyinPane(null); | 888 | flyinPane(null); |
892 | } | 889 | } |
893 | 890 | ||
891 | + function detailUrl(id) { | ||
892 | + var safeId = id.replace(/[^a-z0-9]/gi, '_'); | ||
893 | + return config.jsonPrefix + safeId + '.json'; | ||
894 | + } | ||
895 | + | ||
894 | function flyinPane(obj) { | 896 | function flyinPane(obj) { |
895 | var pane = d3.select('#flyout'), | 897 | var pane = d3.select('#flyout'), |
896 | - right = (obj ? '20px' : '-320px'), // TODO: parameterize | 898 | + url; |
897 | - opac = (obj ? 1.0 : 0.0); | ||
898 | 899 | ||
899 | if (obj) { | 900 | if (obj) { |
900 | - $('#flyout').empty(); | 901 | + // go get details of the selected object from the server... |
901 | - pane.append('h2').text(obj.id); | 902 | + url = detailUrl(obj.id); |
902 | - pane.append('p').text('class: ' + obj.class); | 903 | + d3.json(url, function (err, data) { |
903 | - if (obj.type) { | 904 | + if (err) { |
904 | - pane.append('p').text('type: ' + obj.type); | 905 | + alert('Oops! Error reading JSON...\n\n' + |
905 | - } | 906 | + 'URL: ' + url + '\n\n' + |
907 | + 'Error: ' + err.message); | ||
908 | + return; | ||
909 | + } | ||
910 | +// console.log("JSON data... " + url); | ||
911 | +// console.log(data); | ||
912 | + | ||
913 | + displayDetails(data, pane); | ||
914 | + }); | ||
915 | + | ||
916 | + } else { | ||
917 | + // hide pane | ||
918 | + pane.transition().duration(750) | ||
919 | + .style('right', '-320px') | ||
920 | + .style('opacity', 0.0); | ||
921 | + } | ||
922 | + } | ||
923 | + | ||
924 | + function displayDetails(data, pane) { | ||
925 | + $('#flyout').empty(); | ||
926 | + | ||
927 | + pane.append('h2').text(data.id); | ||
928 | + | ||
929 | + var table = pane.append("table"), | ||
930 | + tbody = table.append("tbody"); | ||
931 | + | ||
932 | + // TODO: consider using d3 data bind to TR/TD | ||
933 | + | ||
934 | + data.propOrder.forEach(function(p) { | ||
935 | + addProp(tbody, p, data.props[p]); | ||
936 | + }); | ||
937 | + | ||
938 | + function addProp(tbody, label, value) { | ||
939 | + var tr = tbody.append('tr'); | ||
940 | + | ||
941 | + tr.append('td') | ||
942 | + .attr('class', 'label') | ||
943 | + .text(label + ' :'); | ||
944 | + | ||
945 | + tr.append('td') | ||
946 | + .attr('class', 'value') | ||
947 | + .text(value); | ||
906 | } | 948 | } |
907 | 949 | ||
950 | + // show pane | ||
908 | pane.transition().duration(750) | 951 | pane.transition().duration(750) |
909 | - .style('right', right) | 952 | + .style('right', '20px') |
910 | - .style('opacity', opac); | 953 | + .style('opacity', 1.0); |
911 | } | 954 | } |
912 | 955 | ||
913 | function highlightObject(obj) { | 956 | function highlightObject(obj) { | ... | ... |
... | @@ -189,6 +189,13 @@ svg .legend .category text { | ... | @@ -189,6 +189,13 @@ svg .legend .category text { |
189 | * Specific structural elements | 189 | * Specific structural elements |
190 | */ | 190 | */ |
191 | 191 | ||
192 | +/* This is to ensure that the body does not expand to account for the | ||
193 | + flyout details pane, that is positioned "off screen". | ||
194 | + */ | ||
195 | +body { | ||
196 | + overflow: hidden; | ||
197 | +} | ||
198 | + | ||
192 | #mast { | 199 | #mast { |
193 | height: 36px; | 200 | height: 36px; |
194 | padding: 4px; | 201 | padding: 4px; |
... | @@ -214,6 +221,7 @@ svg .legend .category text { | ... | @@ -214,6 +221,7 @@ svg .legend .category text { |
214 | background-color: rgba(0,0,0,0.5); | 221 | background-color: rgba(0,0,0,0.5); |
215 | padding: 10px; | 222 | padding: 10px; |
216 | color: white; | 223 | color: white; |
224 | + font-size: 10pt; | ||
217 | } | 225 | } |
218 | 226 | ||
219 | #flyout h2 { | 227 | #flyout h2 { |
... | @@ -221,7 +229,17 @@ svg .legend .category text { | ... | @@ -221,7 +229,17 @@ svg .legend .category text { |
221 | color: yellow; | 229 | color: yellow; |
222 | } | 230 | } |
223 | 231 | ||
224 | -#flyout p { | 232 | +#flyout p, table { |
225 | margin: 4px 4px; | 233 | margin: 4px 4px; |
226 | } | 234 | } |
227 | 235 | ||
236 | +#flyout td.label { | ||
237 | + font-style: italic; | ||
238 | + color: #ccf; | ||
239 | + padding-right: 12px; | ||
240 | +} | ||
241 | + | ||
242 | +#flyout td.value { | ||
243 | + | ||
244 | +} | ||
245 | + | ... | ... |
-
Please register or login to post a comment