Tweaked GUI files to clean-up the look and feel and to add a few enhancements.
Default for network.js is now to use live data.
Showing
14 changed files
with
103 additions
and
39 deletions
| ... | @@ -94,14 +94,18 @@ public class TopologyResource extends BaseResource { | ... | @@ -94,14 +94,18 @@ public class TopologyResource extends BaseResource { |
| 94 | DeviceService deviceService = get(DeviceService.class); | 94 | DeviceService deviceService = get(DeviceService.class); |
| 95 | Device device = deviceService.getDevice(deviceId); | 95 | Device device = deviceService.getDevice(deviceId); |
| 96 | Annotations annot = device.annotations(); | 96 | Annotations annot = device.annotations(); |
| 97 | + int portCount = deviceService.getPorts(deviceId).size(); | ||
| 97 | ObjectNode r = json(deviceId.toString(), | 98 | ObjectNode r = json(deviceId.toString(), |
| 99 | + device.type().toString().toLowerCase(), | ||
| 98 | new Prop("Name", annot.value("name")), | 100 | new Prop("Name", annot.value("name")), |
| 99 | new Prop("Vendor", device.manufacturer()), | 101 | new Prop("Vendor", device.manufacturer()), |
| 100 | new Prop("H/W Version", device.hwVersion()), | 102 | new Prop("H/W Version", device.hwVersion()), |
| 101 | new Prop("S/W Version", device.swVersion()), | 103 | new Prop("S/W Version", device.swVersion()), |
| 102 | new Prop("S/W Version", device.serialNumber()), | 104 | new Prop("S/W Version", device.serialNumber()), |
| 105 | + new Separator(), | ||
| 103 | new Prop("Latitude", annot.value("latitude")), | 106 | new Prop("Latitude", annot.value("latitude")), |
| 104 | - new Prop("Longitude", annot.value("longitude"))); | 107 | + new Prop("Longitude", annot.value("longitude")), |
| 108 | + new Prop("Ports", Integer.toString(portCount))); | ||
| 105 | return Response.ok(r.toString()).build(); | 109 | return Response.ok(r.toString()).build(); |
| 106 | } | 110 | } |
| 107 | 111 | ||
| ... | @@ -110,18 +114,20 @@ public class TopologyResource extends BaseResource { | ... | @@ -110,18 +114,20 @@ public class TopologyResource extends BaseResource { |
| 110 | HostService hostService = get(HostService.class); | 114 | HostService hostService = get(HostService.class); |
| 111 | Host host = hostService.getHost(hostId); | 115 | Host host = hostService.getHost(hostId); |
| 112 | Annotations annot = host.annotations(); | 116 | Annotations annot = host.annotations(); |
| 113 | - ObjectNode r = json(hostId.toString(), | 117 | + ObjectNode r = json(hostId.toString(), "host", |
| 114 | new Prop("MAC", host.mac().toString()), | 118 | new Prop("MAC", host.mac().toString()), |
| 115 | new Prop("IP", host.ipAddresses().toString()), | 119 | new Prop("IP", host.ipAddresses().toString()), |
| 120 | + new Separator(), | ||
| 116 | new Prop("Latitude", annot.value("latitude")), | 121 | new Prop("Latitude", annot.value("latitude")), |
| 117 | new Prop("Longitude", annot.value("longitude"))); | 122 | new Prop("Longitude", annot.value("longitude"))); |
| 118 | return Response.ok(r.toString()).build(); | 123 | return Response.ok(r.toString()).build(); |
| 119 | } | 124 | } |
| 120 | 125 | ||
| 121 | // Produces JSON property details. | 126 | // Produces JSON property details. |
| 122 | - private ObjectNode json(String id, Prop... props) { | 127 | + private ObjectNode json(String id, String type, Prop... props) { |
| 123 | ObjectMapper mapper = new ObjectMapper(); | 128 | ObjectMapper mapper = new ObjectMapper(); |
| 124 | - ObjectNode result = mapper.createObjectNode().put("id", id); | 129 | + ObjectNode result = mapper.createObjectNode() |
| 130 | + .put("id", id).put("type", type); | ||
| 125 | ObjectNode pnode = mapper.createObjectNode(); | 131 | ObjectNode pnode = mapper.createObjectNode(); |
| 126 | ArrayNode porder = mapper.createArrayNode(); | 132 | ArrayNode porder = mapper.createArrayNode(); |
| 127 | for (Prop p : props) { | 133 | for (Prop p : props) { |
| ... | @@ -273,13 +279,19 @@ public class TopologyResource extends BaseResource { | ... | @@ -273,13 +279,19 @@ public class TopologyResource extends BaseResource { |
| 273 | } | 279 | } |
| 274 | 280 | ||
| 275 | // Auxiliary key/value carrier. | 281 | // Auxiliary key/value carrier. |
| 276 | - private final class Prop { | 282 | + private class Prop { |
| 277 | private final String key; | 283 | private final String key; |
| 278 | private final String value; | 284 | private final String value; |
| 279 | 285 | ||
| 280 | - private Prop(String key, String value) { | 286 | + protected Prop(String key, String value) { |
| 281 | this.key = key; | 287 | this.key = key; |
| 282 | this.value = value; | 288 | this.value = value; |
| 283 | } | 289 | } |
| 284 | } | 290 | } |
| 291 | + | ||
| 292 | + private class Separator extends Prop { | ||
| 293 | + protected Separator() { | ||
| 294 | + super("-", ""); | ||
| 295 | + } | ||
| 296 | + } | ||
| 285 | } | 297 | } | ... | ... |
web/gui/src/main/webapp/img/roadm.png
0 → 100644
8.83 KB
web/gui/src/main/webapp/img/switch.png
0 → 100644
9.27 KB
| ... | @@ -39,7 +39,7 @@ | ... | @@ -39,7 +39,7 @@ |
| 39 | <body> | 39 | <body> |
| 40 | <div id="frame"> | 40 | <div id="frame"> |
| 41 | <div id="mast"> | 41 | <div id="mast"> |
| 42 | - <img id="logo" src="img/onos-logo.png" width="60" height="38"> | 42 | + <img id="logo" src="img/onos-logo.png"> |
| 43 | <span class="title">Open Network Operating System</span> | 43 | <span class="title">Open Network Operating System</span> |
| 44 | <span id="displayModes" class="right"> | 44 | <span id="displayModes" class="right"> |
| 45 | <span id="showAll" class="radio active">All Layers</span> | 45 | <span id="showAll" class="radio active">All Layers</span> | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000001", | 3 | "id": "of:0000000000000001", |
| 4 | - "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | 4 | + "type": "roadm", |
| 5 | + "propOrder": [ "name", "type", "-", "dpid", "latitude", "longitude", "allowed" ], | ||
| 5 | "props": { | 6 | "props": { |
| 6 | "allowed": true, | 7 | "allowed": true, |
| 7 | "latitude": 37.6, | 8 | "latitude": 37.6, |
| 8 | "longitude": 122.3, | 9 | "longitude": 122.3, |
| 9 | "name": "SFO-W10", | 10 | "name": "SFO-W10", |
| 10 | - "dpid": "00:00:00:00:00:00:00:01", | 11 | + "dpid": "00:00:00:00:00:00:00:01" |
| 11 | - "type": "Roadm" | ||
| 12 | } | 12 | } |
| 13 | } | 13 | } | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000002", | 3 | "id": "of:0000000000000002", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | 5 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "allowed": true, | 7 | "allowed": true, | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000003", | 3 | "id": "of:0000000000000003", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | 5 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "allowed": true, | 7 | "allowed": true, | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000004", | 3 | "id": "of:0000000000000004", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], | 5 | "propOrder": [ "name", "type", "dpid", "latitude", "longitude", "allowed" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "allowed": true, | 7 | "allowed": true, | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000011", | 3 | "id": "of:0000000000000011", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "optLink" ], | 5 | "propOrder": [ "name", "type", "dpid", "optLink" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "name": "SFO-pkt", | 7 | "name": "SFO-pkt", | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000012", | 3 | "id": "of:0000000000000012", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "optLink" ], | 5 | "propOrder": [ "name", "type", "dpid", "optLink" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "name": "SJC-pkt", | 7 | "name": "SJC-pkt", | ... | ... |
| 1 | { | 1 | { |
| 2 | "comment": "sample device properties", | 2 | "comment": "sample device properties", |
| 3 | "id": "of:0000000000000013", | 3 | "id": "of:0000000000000013", |
| 4 | + "type": "switch", | ||
| 4 | "propOrder": [ "name", "type", "dpid", "optLink" ], | 5 | "propOrder": [ "name", "type", "dpid", "optLink" ], |
| 5 | "props": { | 6 | "props": { |
| 6 | "name": "LAX-pkt", | 7 | "name": "LAX-pkt", | ... | ... |
| ... | @@ -37,10 +37,10 @@ | ... | @@ -37,10 +37,10 @@ |
| 37 | layering: true, | 37 | layering: true, |
| 38 | collisionPrevention: true | 38 | collisionPrevention: true |
| 39 | }, | 39 | }, |
| 40 | - XjsonUrl: 'rs/topology/graph', | 40 | + jsonUrl: 'rs/topology/graph', |
| 41 | - XjsonPrefix: '', | 41 | + jsonPrefix: '', |
| 42 | - jsonUrl: 'json/network.json', | 42 | + XjsonUrl: 'json/network.json', |
| 43 | - jsonPrefix: 'json/', | 43 | + XjsonPrefix: 'json/', |
| 44 | iconUrl: { | 44 | iconUrl: { |
| 45 | device: 'img/device.png', | 45 | device: 'img/device.png', |
| 46 | host: 'img/host.png', | 46 | host: 'img/host.png', |
| ... | @@ -239,6 +239,9 @@ | ... | @@ -239,6 +239,9 @@ |
| 239 | function processKeyEvent() { | 239 | function processKeyEvent() { |
| 240 | var code = d3.event.keyCode; | 240 | var code = d3.event.keyCode; |
| 241 | switch (code) { | 241 | switch (code) { |
| 242 | + case 71: // G | ||
| 243 | + cycleLayout(); | ||
| 244 | + break; | ||
| 242 | case 76: // L | 245 | case 76: // L |
| 243 | cycleLabels(); | 246 | cycleLabels(); |
| 244 | break; | 247 | break; |
| ... | @@ -252,6 +255,11 @@ | ... | @@ -252,6 +255,11 @@ |
| 252 | 255 | ||
| 253 | } | 256 | } |
| 254 | 257 | ||
| 258 | + function cycleLayout() { | ||
| 259 | + config.options.layering = !config.options.layering; | ||
| 260 | + network.force.resume(); | ||
| 261 | + } | ||
| 262 | + | ||
| 255 | function cycleLabels() { | 263 | function cycleLabels() { |
| 256 | console.log('Cycle Labels - context = ' + contextLabel()); | 264 | console.log('Cycle Labels - context = ' + contextLabel()); |
| 257 | } | 265 | } |
| ... | @@ -689,7 +697,8 @@ | ... | @@ -689,7 +697,8 @@ |
| 689 | } | 697 | } |
| 690 | 698 | ||
| 691 | function iconUrl(d) { | 699 | function iconUrl(d) { |
| 692 | - return config.iconUrl[d.icon]; | 700 | + return 'img/' + d.type + '.png'; |
| 701 | +// return config.iconUrl[d.icon]; | ||
| 693 | } | 702 | } |
| 694 | 703 | ||
| 695 | function translate(x, y) { | 704 | function translate(x, y) { |
| ... | @@ -928,17 +937,29 @@ | ... | @@ -928,17 +937,29 @@ |
| 928 | function displayDetails(data, pane) { | 937 | function displayDetails(data, pane) { |
| 929 | $('#flyout').empty(); | 938 | $('#flyout').empty(); |
| 930 | 939 | ||
| 931 | - pane.append('h2').text(data.id); | 940 | + var title = pane.append("h2"), |
| 932 | - | 941 | + table = pane.append("table"), |
| 933 | - var table = pane.append("table"), | ||
| 934 | tbody = table.append("tbody"); | 942 | tbody = table.append("tbody"); |
| 935 | 943 | ||
| 944 | + $('<img src="img/' + data.type + '.png">').appendTo(title); | ||
| 945 | + $('<span>').attr('class', 'icon').text(data.id).appendTo(title); | ||
| 946 | + | ||
| 947 | + | ||
| 936 | // TODO: consider using d3 data bind to TR/TD | 948 | // TODO: consider using d3 data bind to TR/TD |
| 937 | 949 | ||
| 938 | data.propOrder.forEach(function(p) { | 950 | data.propOrder.forEach(function(p) { |
| 939 | - addProp(tbody, p, data.props[p]); | 951 | + if (p === '-') { |
| 952 | + addSep(tbody); | ||
| 953 | + } else { | ||
| 954 | + addProp(tbody, p, data.props[p]); | ||
| 955 | + } | ||
| 940 | }); | 956 | }); |
| 941 | 957 | ||
| 958 | + function addSep(tbody) { | ||
| 959 | + var tr = tbody.append('tr'); | ||
| 960 | + $('<hr>').appendTo(tr.append('td').attr('colspan', 2)); | ||
| 961 | + } | ||
| 962 | + | ||
| 942 | function addProp(tbody, label, value) { | 963 | function addProp(tbody, label, value) { |
| 943 | var tr = tbody.append('tr'); | 964 | var tr = tbody.append('tr'); |
| 944 | 965 | ... | ... |
| ... | @@ -28,11 +28,17 @@ body, html { | ... | @@ -28,11 +28,17 @@ body, html { |
| 28 | * Classes | 28 | * Classes |
| 29 | */ | 29 | */ |
| 30 | 30 | ||
| 31 | +img#logo { | ||
| 32 | + height: 38px; | ||
| 33 | + padding-left: 8px; | ||
| 34 | + padding-right: 8px; | ||
| 35 | +} | ||
| 36 | + | ||
| 31 | span.title { | 37 | span.title { |
| 32 | - color: #37b; | 38 | + color: #369; |
| 33 | font-size: 14pt; | 39 | font-size: 14pt; |
| 34 | font-style: italic; | 40 | font-style: italic; |
| 35 | - vertical-align: 10px; | 41 | + vertical-align: 12px; |
| 36 | } | 42 | } |
| 37 | 43 | ||
| 38 | span.radio { | 44 | span.radio { |
| ... | @@ -41,6 +47,8 @@ span.radio { | ... | @@ -41,6 +47,8 @@ span.radio { |
| 41 | } | 47 | } |
| 42 | 48 | ||
| 43 | span.right { | 49 | span.right { |
| 50 | + padding-top: 8px; | ||
| 51 | + padding-right: 16px; | ||
| 44 | float: right; | 52 | float: right; |
| 45 | } | 53 | } |
| 46 | 54 | ||
| ... | @@ -89,14 +97,13 @@ svg .link { | ... | @@ -89,14 +97,13 @@ svg .link { |
| 89 | } | 97 | } |
| 90 | 98 | ||
| 91 | svg .link.host { | 99 | svg .link.host { |
| 92 | - stroke: #6a6; | 100 | + stroke: #666; |
| 93 | - stroke-dasharray: 3,3; | 101 | + stroke-width: 1px; |
| 102 | + Xstroke-dasharray: 3,3; | ||
| 94 | } | 103 | } |
| 95 | 104 | ||
| 96 | svg .node.device rect { | 105 | svg .node.device rect { |
| 97 | - stroke-width: 3.0px; | 106 | + stroke-width: 1.5px; |
| 98 | - stroke: white; | ||
| 99 | - stroke-dasharray: 2,2; | ||
| 100 | 107 | ||
| 101 | transition: opacity 250ms; | 108 | transition: opacity 250ms; |
| 102 | -webkit-transition: opacity 250ms; | 109 | -webkit-transition: opacity 250ms; |
| ... | @@ -104,19 +111,21 @@ svg .node.device rect { | ... | @@ -104,19 +111,21 @@ svg .node.device rect { |
| 104 | } | 111 | } |
| 105 | 112 | ||
| 106 | svg .node.device.fixed rect { | 113 | svg .node.device.fixed rect { |
| 107 | - stroke-width: 0; | 114 | + stroke-width: 1.5; |
| 115 | + stroke: #ccc; | ||
| 116 | + Xstroke-dasharray: 4,2; | ||
| 108 | } | 117 | } |
| 109 | 118 | ||
| 110 | svg .node.device.roadm rect { | 119 | svg .node.device.roadm rect { |
| 111 | - fill: #229; | 120 | + fill: #03c; |
| 112 | } | 121 | } |
| 113 | 122 | ||
| 114 | svg .node.device.switch rect { | 123 | svg .node.device.switch rect { |
| 115 | - fill: #55f; | 124 | + fill: #06f; |
| 116 | } | 125 | } |
| 117 | 126 | ||
| 118 | svg .node.host circle { | 127 | svg .node.host circle { |
| 119 | - fill: #898; | 128 | + fill: #c96; |
| 120 | stroke: #000; | 129 | stroke: #000; |
| 121 | } | 130 | } |
| 122 | 131 | ||
| ... | @@ -148,7 +157,7 @@ svg .node.inactive rect, | ... | @@ -148,7 +157,7 @@ svg .node.inactive rect, |
| 148 | svg .node.inactive circle, | 157 | svg .node.inactive circle, |
| 149 | svg .node.inactive text, | 158 | svg .node.inactive text, |
| 150 | svg .node.inactive image { | 159 | svg .node.inactive image { |
| 151 | - opacity: .05; | 160 | + opacity: .1; |
| 152 | } | 161 | } |
| 153 | 162 | ||
| 154 | svg .node.inactive.selected rect, | 163 | svg .node.inactive.selected rect, |
| ... | @@ -199,8 +208,9 @@ body { | ... | @@ -199,8 +208,9 @@ body { |
| 199 | #mast { | 208 | #mast { |
| 200 | height: 36px; | 209 | height: 36px; |
| 201 | padding: 4px; | 210 | padding: 4px; |
| 202 | - background-color: #ccc; | 211 | + background-color: #bbb; |
| 203 | vertical-align: baseline; | 212 | vertical-align: baseline; |
| 213 | + box-shadow: 0px 2px 8px #777; | ||
| 204 | } | 214 | } |
| 205 | 215 | ||
| 206 | #frame { | 216 | #frame { |
| ... | @@ -214,19 +224,27 @@ body { | ... | @@ -214,19 +224,27 @@ body { |
| 214 | z-index: 100; | 224 | z-index: 100; |
| 215 | display: block; | 225 | display: block; |
| 216 | top: 10%; | 226 | top: 10%; |
| 217 | - width: 300px; | 227 | + width: 280px; |
| 218 | - height: 80%; | 228 | + right: -300px; |
| 219 | - right: -320px; | ||
| 220 | opacity: 0; | 229 | opacity: 0; |
| 221 | - background-color: rgba(0,0,0,0.5); | 230 | + background-color: rgba(255,255,255,0.5); |
| 231 | + | ||
| 222 | padding: 10px; | 232 | padding: 10px; |
| 223 | - color: white; | 233 | + color: black; |
| 224 | font-size: 10pt; | 234 | font-size: 10pt; |
| 235 | + box-shadow: 2px 2px 16px #777; | ||
| 225 | } | 236 | } |
| 226 | 237 | ||
| 227 | #flyout h2 { | 238 | #flyout h2 { |
| 228 | margin: 8px 4px; | 239 | margin: 8px 4px; |
| 229 | - color: yellow; | 240 | + color: black; |
| 241 | + vertical-align: middle; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +#flyout h2 img { | ||
| 245 | + height: 32px; | ||
| 246 | + padding-right: 8px; | ||
| 247 | + vertical-align: middle; | ||
| 230 | } | 248 | } |
| 231 | 249 | ||
| 232 | #flyout p, table { | 250 | #flyout p, table { |
| ... | @@ -235,7 +253,7 @@ body { | ... | @@ -235,7 +253,7 @@ body { |
| 235 | 253 | ||
| 236 | #flyout td.label { | 254 | #flyout td.label { |
| 237 | font-style: italic; | 255 | font-style: italic; |
| 238 | - color: #ccf; | 256 | + color: #777; |
| 239 | padding-right: 12px; | 257 | padding-right: 12px; |
| 240 | } | 258 | } |
| 241 | 259 | ||
| ... | @@ -243,3 +261,10 @@ body { | ... | @@ -243,3 +261,10 @@ body { |
| 243 | 261 | ||
| 244 | } | 262 | } |
| 245 | 263 | ||
| 264 | +#flyout hr { | ||
| 265 | + height: 1px; | ||
| 266 | + color: #ccc; | ||
| 267 | + background-color: #ccc; | ||
| 268 | + border: 0; | ||
| 269 | +} | ||
| 270 | + | ... | ... |
-
Please register or login to post a comment