ONOS-293 Added summary pane and related keyboard shortcuts; also tweaked key hel…
…p sizes and dropped instances toggle from mast. Fixed ONOS-295 bug. Change-Id: I694901957451cf88df06e6fca3a8d71de144f68e
Showing
12 changed files
with
324 additions
and
70 deletions
| ... | @@ -43,10 +43,10 @@ public class SummaryCommand extends AbstractShellCommand { | ... | @@ -43,10 +43,10 @@ public class SummaryCommand extends AbstractShellCommand { |
| 43 | .put("node", get(ClusterService.class).getLocalNode().ip().toString()) | 43 | .put("node", get(ClusterService.class).getLocalNode().ip().toString()) |
| 44 | .put("version", get(CoreService.class).version().toString()) | 44 | .put("version", get(CoreService.class).version().toString()) |
| 45 | .put("nodes", get(ClusterService.class).getNodes().size()) | 45 | .put("nodes", get(ClusterService.class).getNodes().size()) |
| 46 | - .put("devices", get(DeviceService.class).getDeviceCount()) | 46 | + .put("devices", topology.deviceCount()) |
| 47 | - .put("links", get(LinkService.class).getLinkCount()) | 47 | + .put("links", topology.linkCount()) |
| 48 | .put("hosts", get(HostService.class).getHostCount()) | 48 | .put("hosts", get(HostService.class).getHostCount()) |
| 49 | - .put("clusters", topologyService.getClusters(topology).size()) | 49 | + .put("clusters", topology.clusterCount()) |
| 50 | .put("paths", topology.pathCount()) | 50 | .put("paths", topology.pathCount()) |
| 51 | .put("flows", get(FlowRuleService.class).getFlowRuleCount()) | 51 | .put("flows", get(FlowRuleService.class).getFlowRuleCount()) |
| 52 | .put("intents", get(IntentService.class).getIntentCount())); | 52 | .put("intents", get(IntentService.class).getIntentCount())); | ... | ... |
| ... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
| 4 | # ----------------------------------------------------------------------------- | 4 | # ----------------------------------------------------------------------------- |
| 5 | 5 | ||
| 6 | #export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} | 6 | #export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/} |
| 7 | -export JAVA_OPTS="${JAVA_OPTS:--Xms256M -Xmx2048M}" | 7 | +export JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx2048m}" |
| 8 | 8 | ||
| 9 | cd /opt/onos | 9 | cd /opt/onos |
| 10 | /opt/onos/apache-karaf-$KARAF_VERSION/bin/karaf "$@" | 10 | /opt/onos/apache-karaf-$KARAF_VERSION/bin/karaf "$@" | ... | ... |
| ... | @@ -23,6 +23,7 @@ import org.onlab.onos.cluster.ClusterEvent; | ... | @@ -23,6 +23,7 @@ import org.onlab.onos.cluster.ClusterEvent; |
| 23 | import org.onlab.onos.cluster.ClusterService; | 23 | import org.onlab.onos.cluster.ClusterService; |
| 24 | import org.onlab.onos.cluster.ControllerNode; | 24 | import org.onlab.onos.cluster.ControllerNode; |
| 25 | import org.onlab.onos.cluster.NodeId; | 25 | import org.onlab.onos.cluster.NodeId; |
| 26 | +import org.onlab.onos.core.CoreService; | ||
| 26 | import org.onlab.onos.mastership.MastershipService; | 27 | import org.onlab.onos.mastership.MastershipService; |
| 27 | import org.onlab.onos.net.Annotated; | 28 | import org.onlab.onos.net.Annotated; |
| 28 | import org.onlab.onos.net.Annotations; | 29 | import org.onlab.onos.net.Annotations; |
| ... | @@ -56,6 +57,8 @@ import org.onlab.onos.net.link.LinkService; | ... | @@ -56,6 +57,8 @@ import org.onlab.onos.net.link.LinkService; |
| 56 | import org.onlab.onos.net.provider.ProviderId; | 57 | import org.onlab.onos.net.provider.ProviderId; |
| 57 | import org.onlab.onos.net.statistic.Load; | 58 | import org.onlab.onos.net.statistic.Load; |
| 58 | import org.onlab.onos.net.statistic.StatisticService; | 59 | import org.onlab.onos.net.statistic.StatisticService; |
| 60 | +import org.onlab.onos.net.topology.Topology; | ||
| 61 | +import org.onlab.onos.net.topology.TopologyService; | ||
| 59 | import org.onlab.osgi.ServiceDirectory; | 62 | import org.onlab.osgi.ServiceDirectory; |
| 60 | import org.onlab.packet.IpAddress; | 63 | import org.onlab.packet.IpAddress; |
| 61 | import org.slf4j.Logger; | 64 | import org.slf4j.Logger; |
| ... | @@ -117,8 +120,10 @@ public abstract class TopologyViewMessages { | ... | @@ -117,8 +120,10 @@ public abstract class TopologyViewMessages { |
| 117 | protected final IntentService intentService; | 120 | protected final IntentService intentService; |
| 118 | protected final FlowRuleService flowService; | 121 | protected final FlowRuleService flowService; |
| 119 | protected final StatisticService statService; | 122 | protected final StatisticService statService; |
| 123 | + protected final TopologyService topologyService; | ||
| 120 | 124 | ||
| 121 | protected final ObjectMapper mapper = new ObjectMapper(); | 125 | protected final ObjectMapper mapper = new ObjectMapper(); |
| 126 | + private final String version; | ||
| 122 | 127 | ||
| 123 | // TODO: extract into an external & durable state; good enough for now and demo | 128 | // TODO: extract into an external & durable state; good enough for now and demo |
| 124 | private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>(); | 129 | private static Map<String, ObjectNode> metaUi = new ConcurrentHashMap<>(); |
| ... | @@ -138,6 +143,9 @@ public abstract class TopologyViewMessages { | ... | @@ -138,6 +143,9 @@ public abstract class TopologyViewMessages { |
| 138 | intentService = directory.get(IntentService.class); | 143 | intentService = directory.get(IntentService.class); |
| 139 | flowService = directory.get(FlowRuleService.class); | 144 | flowService = directory.get(FlowRuleService.class); |
| 140 | statService = directory.get(StatisticService.class); | 145 | statService = directory.get(StatisticService.class); |
| 146 | + topologyService = directory.get(TopologyService.class); | ||
| 147 | + | ||
| 148 | + version = directory.get(CoreService.class).version().toString(); | ||
| 141 | } | 149 | } |
| 142 | 150 | ||
| 143 | // Retrieves the payload from the specified event. | 151 | // Retrieves the payload from the specified event. |
| ... | @@ -419,6 +427,22 @@ public abstract class TopologyViewMessages { | ... | @@ -419,6 +427,22 @@ public abstract class TopologyViewMessages { |
| 419 | metaUi.put(string(payload, "id"), (ObjectNode) payload.path("memento")); | 427 | metaUi.put(string(payload, "id"), (ObjectNode) payload.path("memento")); |
| 420 | } | 428 | } |
| 421 | 429 | ||
| 430 | + // Returns summary response. | ||
| 431 | + protected ObjectNode summmaryMessage(long sid) { | ||
| 432 | + Topology topology = topologyService.currentTopology(); | ||
| 433 | + return envelope("showSummary", sid, | ||
| 434 | + json("ONOS Summary", "node", | ||
| 435 | + new Prop("Devices", format(topology.deviceCount())), | ||
| 436 | + new Prop("Links", format(topology.linkCount())), | ||
| 437 | + new Prop("Hosts", format(hostService.getHostCount())), | ||
| 438 | + new Prop("Topology SCCs", format(topology.clusterCount())), | ||
| 439 | + new Prop("Paths", format(topology.pathCount())), | ||
| 440 | + new Separator(), | ||
| 441 | + new Prop("Intents", format(intentService.getIntentCount())), | ||
| 442 | + new Prop("Flows", format(flowService.getFlowRuleCount())), | ||
| 443 | + new Prop("Version", version.replace(".SNAPSHOT", "*")))); | ||
| 444 | + } | ||
| 445 | + | ||
| 422 | // Returns device details response. | 446 | // Returns device details response. |
| 423 | protected ObjectNode deviceDetails(DeviceId deviceId, long sid) { | 447 | protected ObjectNode deviceDetails(DeviceId deviceId, long sid) { |
| 424 | Device device = deviceService.getDevice(deviceId); | 448 | Device device = deviceService.getDevice(deviceId); |
| ... | @@ -435,12 +459,12 @@ public abstract class TopologyViewMessages { | ... | @@ -435,12 +459,12 @@ public abstract class TopologyViewMessages { |
| 435 | new Prop("S/W Version", device.swVersion()), | 459 | new Prop("S/W Version", device.swVersion()), |
| 436 | new Prop("Serial Number", device.serialNumber()), | 460 | new Prop("Serial Number", device.serialNumber()), |
| 437 | new Separator(), | 461 | new Separator(), |
| 462 | + new Prop("Master", master(deviceId)), | ||
| 438 | new Prop("Latitude", annot.value("latitude")), | 463 | new Prop("Latitude", annot.value("latitude")), |
| 439 | new Prop("Longitude", annot.value("longitude")), | 464 | new Prop("Longitude", annot.value("longitude")), |
| 440 | - new Prop("Ports", Integer.toString(portCount)), | ||
| 441 | - new Prop("Flows", Integer.toString(flowCount)), | ||
| 442 | new Separator(), | 465 | new Separator(), |
| 443 | - new Prop("Master", master(deviceId)))); | 466 | + new Prop("Ports", Integer.toString(portCount)), |
| 467 | + new Prop("Flows", Integer.toString(flowCount)))); | ||
| 444 | } | 468 | } |
| 445 | 469 | ||
| 446 | protected int getFlowCount(DeviceId deviceId) { | 470 | protected int getFlowCount(DeviceId deviceId) { |
| ... | @@ -641,6 +665,12 @@ public abstract class TopologyViewMessages { | ... | @@ -641,6 +665,12 @@ public abstract class TopologyViewMessages { |
| 641 | return format.format(value) + " " + unit; | 665 | return format.format(value) + " " + unit; |
| 642 | } | 666 | } |
| 643 | 667 | ||
| 668 | + // Formats the given number into a string. | ||
| 669 | + private String format(Number number) { | ||
| 670 | + DecimalFormat format = new DecimalFormat("#,###"); | ||
| 671 | + return format.format(number); | ||
| 672 | + } | ||
| 673 | + | ||
| 644 | private boolean isInfrastructureEgress(Link link) { | 674 | private boolean isInfrastructureEgress(Link link) { |
| 645 | return link.src().elementId() instanceof DeviceId; | 675 | return link.src().elementId() instanceof DeviceId; |
| 646 | } | 676 | } | ... | ... |
| ... | @@ -42,7 +42,11 @@ import org.onlab.onos.net.link.LinkListener; | ... | @@ -42,7 +42,11 @@ import org.onlab.onos.net.link.LinkListener; |
| 42 | import org.onlab.osgi.ServiceDirectory; | 42 | import org.onlab.osgi.ServiceDirectory; |
| 43 | 43 | ||
| 44 | import java.io.IOException; | 44 | import java.io.IOException; |
| 45 | +import java.util.ArrayList; | ||
| 46 | +import java.util.Collections; | ||
| 47 | +import java.util.Comparator; | ||
| 45 | import java.util.HashSet; | 48 | import java.util.HashSet; |
| 49 | +import java.util.List; | ||
| 46 | import java.util.Set; | 50 | import java.util.Set; |
| 47 | import java.util.Timer; | 51 | import java.util.Timer; |
| 48 | import java.util.TimerTask; | 52 | import java.util.TimerTask; |
| ... | @@ -70,8 +74,17 @@ public class TopologyViewWebSocket | ... | @@ -70,8 +74,17 @@ public class TopologyViewWebSocket |
| 70 | 74 | ||
| 71 | private static final String APP_ID = "org.onlab.onos.gui"; | 75 | private static final String APP_ID = "org.onlab.onos.gui"; |
| 72 | 76 | ||
| 77 | + private static final long SUMMARY_FREQUENCY_SEC = 2000; | ||
| 73 | private static final long TRAFFIC_FREQUENCY_SEC = 1000; | 78 | private static final long TRAFFIC_FREQUENCY_SEC = 1000; |
| 74 | 79 | ||
| 80 | + private static final Comparator<? super ControllerNode> NODE_COMPARATOR = | ||
| 81 | + new Comparator<ControllerNode>() { | ||
| 82 | + @Override | ||
| 83 | + public int compare(ControllerNode o1, ControllerNode o2) { | ||
| 84 | + return o1.id().toString().compareTo(o2.id().toString()); | ||
| 85 | + } | ||
| 86 | + }; | ||
| 87 | + | ||
| 75 | private final ApplicationId appId; | 88 | private final ApplicationId appId; |
| 76 | 89 | ||
| 77 | private Connection connection; | 90 | private Connection connection; |
| ... | @@ -83,10 +96,14 @@ public class TopologyViewWebSocket | ... | @@ -83,10 +96,14 @@ public class TopologyViewWebSocket |
| 83 | private final HostListener hostListener = new InternalHostListener(); | 96 | private final HostListener hostListener = new InternalHostListener(); |
| 84 | private final IntentListener intentListener = new InternalIntentListener(); | 97 | private final IntentListener intentListener = new InternalIntentListener(); |
| 85 | 98 | ||
| 86 | - // Intents that are being monitored for the GUI | 99 | + // Timers and objects being monitored |
| 87 | - private ObjectNode monitorRequest; | 100 | + private final Timer timer = new Timer("topology-view"); |
| 88 | - private final Timer timer = new Timer("intent-traffic-monitor"); | 101 | + |
| 89 | - private final TimerTask timerTask = new IntentTrafficMonitor(); | 102 | + private TimerTask trafficTask; |
| 103 | + private ObjectNode trafficEvent; | ||
| 104 | + | ||
| 105 | + private TimerTask summaryTask; | ||
| 106 | + private ObjectNode summaryEvent; | ||
| 90 | 107 | ||
| 91 | private long lastActive = System.currentTimeMillis(); | 108 | private long lastActive = System.currentTimeMillis(); |
| 92 | private boolean listenersRemoved = false; | 109 | private boolean listenersRemoved = false; |
| ... | @@ -140,7 +157,6 @@ public class TopologyViewWebSocket | ... | @@ -140,7 +157,6 @@ public class TopologyViewWebSocket |
| 140 | this.connection = connection; | 157 | this.connection = connection; |
| 141 | this.control = (FrameConnection) connection; | 158 | this.control = (FrameConnection) connection; |
| 142 | addListeners(); | 159 | addListeners(); |
| 143 | - timer.schedule(timerTask, TRAFFIC_FREQUENCY_SEC, TRAFFIC_FREQUENCY_SEC); | ||
| 144 | 160 | ||
| 145 | sendAllInstances(); | 161 | sendAllInstances(); |
| 146 | sendAllDevices(); | 162 | sendAllDevices(); |
| ... | @@ -181,6 +197,7 @@ public class TopologyViewWebSocket | ... | @@ -181,6 +197,7 @@ public class TopologyViewWebSocket |
| 181 | updateMetaUi(event); | 197 | updateMetaUi(event); |
| 182 | } else if (type.equals("addHostIntent")) { | 198 | } else if (type.equals("addHostIntent")) { |
| 183 | createHostIntent(event); | 199 | createHostIntent(event); |
| 200 | + | ||
| 184 | } else if (type.equals("requestTraffic")) { | 201 | } else if (type.equals("requestTraffic")) { |
| 185 | requestTraffic(event); | 202 | requestTraffic(event); |
| 186 | } else if (type.equals("requestAllTraffic")) { | 203 | } else if (type.equals("requestAllTraffic")) { |
| ... | @@ -189,6 +206,11 @@ public class TopologyViewWebSocket | ... | @@ -189,6 +206,11 @@ public class TopologyViewWebSocket |
| 189 | requestDeviceLinkFlows(event); | 206 | requestDeviceLinkFlows(event); |
| 190 | } else if (type.equals("cancelTraffic")) { | 207 | } else if (type.equals("cancelTraffic")) { |
| 191 | cancelTraffic(event); | 208 | cancelTraffic(event); |
| 209 | + | ||
| 210 | + } else if (type.equals("requestSummary")) { | ||
| 211 | + requestSummary(event); | ||
| 212 | + } else if (type.equals("cancelSummary")) { | ||
| 213 | + cancelSummary(event); | ||
| 192 | } | 214 | } |
| 193 | } | 215 | } |
| 194 | 216 | ||
| ... | @@ -205,7 +227,9 @@ public class TopologyViewWebSocket | ... | @@ -205,7 +227,9 @@ public class TopologyViewWebSocket |
| 205 | 227 | ||
| 206 | // Sends all controller nodes to the client as node-added messages. | 228 | // Sends all controller nodes to the client as node-added messages. |
| 207 | private void sendAllInstances() { | 229 | private void sendAllInstances() { |
| 208 | - for (ControllerNode node : clusterService.getNodes()) { | 230 | + List<ControllerNode> nodes = new ArrayList<>(clusterService.getNodes()); |
| 231 | + Collections.sort(nodes, NODE_COMPARATOR); | ||
| 232 | + for (ControllerNode node : nodes) { | ||
| 209 | sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node))); | 233 | sendMessage(instanceMessage(new ClusterEvent(INSTANCE_ADDED, node))); |
| 210 | } | 234 | } |
| 211 | } | 235 | } |
| ... | @@ -255,22 +279,37 @@ public class TopologyViewWebSocket | ... | @@ -255,22 +279,37 @@ public class TopologyViewWebSocket |
| 255 | HostToHostIntent hostIntent = new HostToHostIntent(appId, one, two, | 279 | HostToHostIntent hostIntent = new HostToHostIntent(appId, one, two, |
| 256 | DefaultTrafficSelector.builder().build(), | 280 | DefaultTrafficSelector.builder().build(), |
| 257 | DefaultTrafficTreatment.builder().build()); | 281 | DefaultTrafficTreatment.builder().build()); |
| 258 | - monitorRequest = event; | 282 | + trafficEvent = event; |
| 259 | intentService.submit(hostIntent); | 283 | intentService.submit(hostIntent); |
| 260 | } | 284 | } |
| 261 | 285 | ||
| 286 | + private synchronized long startMonitoring(ObjectNode event) { | ||
| 287 | + if (trafficTask == null) { | ||
| 288 | + trafficEvent = event; | ||
| 289 | + trafficTask = new TrafficMonitor(); | ||
| 290 | + timer.schedule(trafficTask, TRAFFIC_FREQUENCY_SEC, TRAFFIC_FREQUENCY_SEC); | ||
| 291 | + } | ||
| 292 | + return number(event, "sid"); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + private synchronized void stopMonitoring() { | ||
| 296 | + if (trafficTask != null) { | ||
| 297 | + trafficTask.cancel(); | ||
| 298 | + trafficTask = null; | ||
| 299 | + trafficEvent = null; | ||
| 300 | + } | ||
| 301 | + } | ||
| 302 | + | ||
| 262 | // Subscribes for host traffic messages. | 303 | // Subscribes for host traffic messages. |
| 263 | private synchronized void requestAllTraffic(ObjectNode event) { | 304 | private synchronized void requestAllTraffic(ObjectNode event) { |
| 264 | ObjectNode payload = payload(event); | 305 | ObjectNode payload = payload(event); |
| 265 | - long sid = number(event, "sid"); | 306 | + long sid = startMonitoring(event); |
| 266 | - monitorRequest = event; | ||
| 267 | sendMessage(trafficSummaryMessage(sid)); | 307 | sendMessage(trafficSummaryMessage(sid)); |
| 268 | } | 308 | } |
| 269 | 309 | ||
| 270 | private void requestDeviceLinkFlows(ObjectNode event) { | 310 | private void requestDeviceLinkFlows(ObjectNode event) { |
| 271 | ObjectNode payload = payload(event); | 311 | ObjectNode payload = payload(event); |
| 272 | - long sid = number(event, "sid"); | 312 | + long sid = startMonitoring(event); |
| 273 | - monitorRequest = event; | ||
| 274 | 313 | ||
| 275 | // Get the set of selected hosts and their intents. | 314 | // Get the set of selected hosts and their intents. |
| 276 | ArrayNode ids = (ArrayNode) payload.path("ids"); | 315 | ArrayNode ids = (ArrayNode) payload.path("ids"); |
| ... | @@ -294,8 +333,7 @@ public class TopologyViewWebSocket | ... | @@ -294,8 +333,7 @@ public class TopologyViewWebSocket |
| 294 | return; | 333 | return; |
| 295 | } | 334 | } |
| 296 | 335 | ||
| 297 | - long sid = number(event, "sid"); | 336 | + long sid = startMonitoring(event); |
| 298 | - monitorRequest = event; | ||
| 299 | 337 | ||
| 300 | // Get the set of selected hosts and their intents. | 338 | // Get the set of selected hosts and their intents. |
| 301 | ArrayNode ids = (ArrayNode) payload.path("ids"); | 339 | ArrayNode ids = (ArrayNode) payload.path("ids"); |
| ... | @@ -325,9 +363,30 @@ public class TopologyViewWebSocket | ... | @@ -325,9 +363,30 @@ public class TopologyViewWebSocket |
| 325 | // Cancels sending traffic messages. | 363 | // Cancels sending traffic messages. |
| 326 | private void cancelTraffic(ObjectNode event) { | 364 | private void cancelTraffic(ObjectNode event) { |
| 327 | sendMessage(trafficMessage(number(event, "sid"))); | 365 | sendMessage(trafficMessage(number(event, "sid"))); |
| 328 | - monitorRequest = null; | 366 | + stopMonitoring(); |
| 329 | } | 367 | } |
| 330 | 368 | ||
| 369 | + | ||
| 370 | + // Subscribes for summary messages. | ||
| 371 | + private synchronized void requestSummary(ObjectNode event) { | ||
| 372 | + if (summaryTask == null) { | ||
| 373 | + summaryEvent = event; | ||
| 374 | + summaryTask = new SummaryMonitor(); | ||
| 375 | + timer.schedule(summaryTask, SUMMARY_FREQUENCY_SEC, SUMMARY_FREQUENCY_SEC); | ||
| 376 | + } | ||
| 377 | + sendMessage(summmaryMessage(number(event, "sid"))); | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + // Cancels sending summary messages. | ||
| 381 | + private synchronized void cancelSummary(ObjectNode event) { | ||
| 382 | + if (summaryTask != null) { | ||
| 383 | + summaryTask.cancel(); | ||
| 384 | + summaryTask = null; | ||
| 385 | + summaryEvent = null; | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + | ||
| 331 | // Adds all internal listeners. | 390 | // Adds all internal listeners. |
| 332 | private void addListeners() { | 391 | private void addListeners() { |
| 333 | clusterService.addListener(clusterListener); | 392 | clusterService.addListener(clusterListener); |
| ... | @@ -385,26 +444,36 @@ public class TopologyViewWebSocket | ... | @@ -385,26 +444,36 @@ public class TopologyViewWebSocket |
| 385 | private class InternalIntentListener implements IntentListener { | 444 | private class InternalIntentListener implements IntentListener { |
| 386 | @Override | 445 | @Override |
| 387 | public void event(IntentEvent event) { | 446 | public void event(IntentEvent event) { |
| 388 | - if (monitorRequest != null) { | 447 | + if (trafficEvent != null) { |
| 389 | - requestTraffic(monitorRequest); | 448 | + requestTraffic(trafficEvent); |
| 390 | } | 449 | } |
| 391 | } | 450 | } |
| 392 | } | 451 | } |
| 393 | 452 | ||
| 394 | - private class IntentTrafficMonitor extends TimerTask { | 453 | + private class TrafficMonitor extends TimerTask { |
| 395 | @Override | 454 | @Override |
| 396 | public void run() { | 455 | public void run() { |
| 397 | - if (monitorRequest != null) { | 456 | + if (trafficEvent != null) { |
| 398 | - String type = string(monitorRequest, "event", "unknown"); | 457 | + String type = string(trafficEvent, "event", "unknown"); |
| 399 | if (type.equals("requestAllTraffic")) { | 458 | if (type.equals("requestAllTraffic")) { |
| 400 | - requestAllTraffic(monitorRequest); | 459 | + requestAllTraffic(trafficEvent); |
| 401 | } else if (type.equals("requestDeviceLinkFlows")) { | 460 | } else if (type.equals("requestDeviceLinkFlows")) { |
| 402 | - requestDeviceLinkFlows(monitorRequest); | 461 | + requestDeviceLinkFlows(trafficEvent); |
| 403 | } else { | 462 | } else { |
| 404 | - requestTraffic(monitorRequest); | 463 | + requestTraffic(trafficEvent); |
| 405 | } | 464 | } |
| 406 | } | 465 | } |
| 407 | } | 466 | } |
| 408 | } | 467 | } |
| 468 | + | ||
| 469 | + private class SummaryMonitor extends TimerTask { | ||
| 470 | + @Override | ||
| 471 | + public void run() { | ||
| 472 | + if (summaryEvent != null) { | ||
| 473 | + requestSummary(summaryEvent); | ||
| 474 | + } | ||
| 475 | + } | ||
| 476 | + } | ||
| 477 | + | ||
| 409 | } | 478 | } |
| 410 | 479 | ... | ... |
| ... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
| 23 | #feedback svg { | 23 | #feedback svg { |
| 24 | position: absolute; | 24 | position: absolute; |
| 25 | bottom: 0; | 25 | bottom: 0; |
| 26 | - opacity: 0.5; | 26 | + opacity: 0.8; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | #feedback svg g.feedbackItem { | 29 | #feedback svg g.feedbackItem { |
| ... | @@ -31,14 +31,11 @@ | ... | @@ -31,14 +31,11 @@ |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | #feedback svg g.feedbackItem rect { | 33 | #feedback svg g.feedbackItem rect { |
| 34 | - fill: #888; | 34 | + fill: #ccc; |
| 35 | - stroke: #666; | ||
| 36 | - stroke-width: 3; | ||
| 37 | - opacity: 0.5 | ||
| 38 | } | 35 | } |
| 39 | 36 | ||
| 40 | #feedback svg g.feedbackItem text { | 37 | #feedback svg g.feedbackItem text { |
| 41 | - fill: #000; | 38 | + fill: #333; |
| 42 | stroke: none; | 39 | stroke: none; |
| 43 | text-anchor: middle; | 40 | text-anchor: middle; |
| 44 | alignment-baseline: middle; | 41 | alignment-baseline: middle; | ... | ... |
| ... | @@ -33,7 +33,7 @@ | ... | @@ -33,7 +33,7 @@ |
| 33 | var w = '100%', | 33 | var w = '100%', |
| 34 | h = 200, | 34 | h = 200, |
| 35 | fade = 200, | 35 | fade = 200, |
| 36 | - showFor = 500, | 36 | + showFor = 1200, |
| 37 | vb = '-200 -' + (h/2) + ' 400 ' + h, | 37 | vb = '-200 -' + (h/2) + ' 400 ' + h, |
| 38 | xpad = 20, | 38 | xpad = 20, |
| 39 | ypad = 10; | 39 | ypad = 10; | ... | ... |
| ... | @@ -24,8 +24,8 @@ | ... | @@ -24,8 +24,8 @@ |
| 24 | position: absolute; | 24 | position: absolute; |
| 25 | z-index: 100; | 25 | z-index: 100; |
| 26 | display: block; | 26 | display: block; |
| 27 | - top: 10%; | 27 | + top: 64px; |
| 28 | - width: 280px; | 28 | + width: 260px; |
| 29 | right: -300px; | 29 | right: -300px; |
| 30 | opacity: 0; | 30 | opacity: 0; |
| 31 | background-color: rgba(255,255,255,0.8); | 31 | background-color: rgba(255,255,255,0.8); | ... | ... |
| ... | @@ -31,10 +31,10 @@ | ... | @@ -31,10 +31,10 @@ |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | #keymap svg text.title { | 33 | #keymap svg text.title { |
| 34 | - font-size: 12pt; | 34 | + font-size: 10pt; |
| 35 | font-style: italic; | 35 | font-style: italic; |
| 36 | text-anchor: middle; | 36 | text-anchor: middle; |
| 37 | - fill: #444; | 37 | + fill: #999; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | #keymap svg g.keyItem { | 40 | #keymap svg g.keyItem { |
| ... | @@ -47,17 +47,17 @@ | ... | @@ -47,17 +47,17 @@ |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | #keymap svg text { | 49 | #keymap svg text { |
| 50 | - font-size: 10pt; | 50 | + font-size: 7pt; |
| 51 | alignment-baseline: middle; | 51 | alignment-baseline: middle; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | #keymap svg text.key { | 54 | #keymap svg text.key { |
| 55 | - font-size: 10pt; | 55 | + font-size: 7pt; |
| 56 | - fill: #8aa; | 56 | + fill: #add; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | #keymap svg text.desc { | 59 | #keymap svg text.desc { |
| 60 | - font-size: 10pt; | 60 | + font-size: 7pt; |
| 61 | - fill: #888; | 61 | + fill: #aaa; |
| 62 | } | 62 | } |
| 63 | 63 | ... | ... |
| ... | @@ -35,9 +35,9 @@ | ... | @@ -35,9 +35,9 @@ |
| 35 | fade = 500, | 35 | fade = 500, |
| 36 | vb = '-220 -220 440 440', | 36 | vb = '-220 -220 440 440', |
| 37 | paneW = 400, | 37 | paneW = 400, |
| 38 | - paneH = 340, | 38 | + paneH = 280, |
| 39 | offy = 65, | 39 | offy = 65, |
| 40 | - dy = 20, | 40 | + dy = 14, |
| 41 | offKey = 40, | 41 | offKey = 40, |
| 42 | offDesc = offKey + 50, | 42 | offDesc = offKey + 50, |
| 43 | lineW = paneW - (2*offKey); | 43 | lineW = paneW - (2*offKey); | ... | ... |
| ... | @@ -763,7 +763,8 @@ | ... | @@ -763,7 +763,8 @@ |
| 763 | var pos = position || 'TR', | 763 | var pos = position || 'TR', |
| 764 | cfg = fpConfig[pos], | 764 | cfg = fpConfig[pos], |
| 765 | el, | 765 | el, |
| 766 | - fp; | 766 | + fp, |
| 767 | + on = false; | ||
| 767 | 768 | ||
| 768 | if (fpanels[id]) { | 769 | if (fpanels[id]) { |
| 769 | buildError('Float panel with id "' + id + '" already exists.'); | 770 | buildError('Float panel with id "' + id + '" already exists.'); |
| ... | @@ -792,15 +793,20 @@ | ... | @@ -792,15 +793,20 @@ |
| 792 | id: id, | 793 | id: id, |
| 793 | el: el, | 794 | el: el, |
| 794 | pos: pos, | 795 | pos: pos, |
| 796 | + isVisible: function () { | ||
| 797 | + return on; | ||
| 798 | + }, | ||
| 795 | 799 | ||
| 796 | show: function () { | 800 | show: function () { |
| 797 | console.log('show pane: ' + id); | 801 | console.log('show pane: ' + id); |
| 802 | + on = true; | ||
| 798 | el.transition().duration(750) | 803 | el.transition().duration(750) |
| 799 | .style(cfg.side, pxShow()) | 804 | .style(cfg.side, pxShow()) |
| 800 | .style('opacity', 1); | 805 | .style('opacity', 1); |
| 801 | }, | 806 | }, |
| 802 | hide: function () { | 807 | hide: function () { |
| 803 | console.log('hide pane: ' + id); | 808 | console.log('hide pane: ' + id); |
| 809 | + on = false; | ||
| 804 | el.transition().duration(750) | 810 | el.transition().duration(750) |
| 805 | .style(cfg.side, pxHide()) | 811 | .style(cfg.side, pxHide()) |
| 806 | .style('opacity', 0); | 812 | .style('opacity', 0); | ... | ... |
| ... | @@ -177,10 +177,66 @@ svg .node.host circle { | ... | @@ -177,10 +177,66 @@ svg .node.host circle { |
| 177 | font-size: 9pt; | 177 | font-size: 9pt; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | +/* Fly-in summary pane */ | ||
| 181 | + | ||
| 182 | +#topo-summary { | ||
| 183 | + /* gets base CSS from .fpanel in floatPanel.css */ | ||
| 184 | + top: 64px; | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +#topo-summary svg { | ||
| 188 | + display: inline-block; | ||
| 189 | + width: 42px; | ||
| 190 | + height: 42px; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +#topo-summary svg .glyphIcon { | ||
| 194 | + fill: black; | ||
| 195 | + stroke: none; | ||
| 196 | + fill-rule: evenodd; | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +#topo-summary h2 { | ||
| 200 | + position: absolute; | ||
| 201 | + margin: 0px 4px; | ||
| 202 | + top: 20px; | ||
| 203 | + left: 50px; | ||
| 204 | + color: black; | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +#topo-summary h3 { | ||
| 208 | + margin: 0px 4px; | ||
| 209 | + top: 20px; | ||
| 210 | + left: 50px; | ||
| 211 | + color: black; | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +#topo-summary p, table { | ||
| 215 | + margin: 4px 4px; | ||
| 216 | +} | ||
| 217 | + | ||
| 218 | +#topo-summary td.label { | ||
| 219 | + font-style: italic; | ||
| 220 | + color: #777; | ||
| 221 | + padding-right: 12px; | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +#topo-summary td.value { | ||
| 225 | +} | ||
| 226 | + | ||
| 227 | +#topo-summary hr { | ||
| 228 | + height: 1px; | ||
| 229 | + color: #ccc; | ||
| 230 | + background-color: #ccc; | ||
| 231 | + border: 0; | ||
| 232 | +} | ||
| 233 | + | ||
| 180 | /* Fly-in details pane */ | 234 | /* Fly-in details pane */ |
| 181 | 235 | ||
| 182 | #topo-detail { | 236 | #topo-detail { |
| 183 | -/* gets base CSS from .fpanel in floatPanel.css */ | 237 | + /* gets base CSS from .fpanel in floatPanel.css */ |
| 238 | + top: 320px; | ||
| 239 | + | ||
| 184 | } | 240 | } |
| 185 | 241 | ||
| 186 | #topo-detail svg { | 242 | #topo-detail svg { | ... | ... |
| ... | @@ -141,6 +141,8 @@ | ... | @@ -141,6 +141,8 @@ |
| 141 | S: injectStartupEvents, | 141 | S: injectStartupEvents, |
| 142 | space: injectTestEvent, | 142 | space: injectTestEvent, |
| 143 | 143 | ||
| 144 | + O: [toggleSummary, 'Toggle ONOS summary pane'], | ||
| 145 | + I: [toggleInstances, 'Toggle ONOS instances pane'], | ||
| 144 | B: [toggleBg, 'Toggle background image'], | 146 | B: [toggleBg, 'Toggle background image'], |
| 145 | L: [cycleLabels, 'Cycle Device labels'], | 147 | L: [cycleLabels, 'Cycle Device labels'], |
| 146 | P: togglePorts, | 148 | P: togglePorts, |
| ... | @@ -182,6 +184,7 @@ | ... | @@ -182,6 +184,7 @@ |
| 182 | selections = {}, | 184 | selections = {}, |
| 183 | selectOrder = [], | 185 | selectOrder = [], |
| 184 | hovered = null, | 186 | hovered = null, |
| 187 | + summaryPane, | ||
| 185 | detailPane, | 188 | detailPane, |
| 186 | antTimer = null, | 189 | antTimer = null, |
| 187 | onosInstances = {}, | 190 | onosInstances = {}, |
| ... | @@ -329,7 +332,7 @@ | ... | @@ -329,7 +332,7 @@ |
| 329 | if (hoverMode === hoverModes.length) { | 332 | if (hoverMode === hoverModes.length) { |
| 330 | hoverMode = 0; | 333 | hoverMode = 0; |
| 331 | } | 334 | } |
| 332 | - view.flash('Hover Mode: ' + hoverModes[hoverMode]); | 335 | + view.flash('Mode: ' + hoverModes[hoverMode]); |
| 333 | } | 336 | } |
| 334 | 337 | ||
| 335 | function togglePorts(view) { | 338 | function togglePorts(view) { |
| ... | @@ -347,8 +350,12 @@ | ... | @@ -347,8 +350,12 @@ |
| 347 | function handleEscape(view) { | 350 | function handleEscape(view) { |
| 348 | if (oiShowMaster) { | 351 | if (oiShowMaster) { |
| 349 | cancelAffinity(); | 352 | cancelAffinity(); |
| 350 | - } else { | 353 | + } else if (detailPane.isVisible()) { |
| 351 | deselectAll(); | 354 | deselectAll(); |
| 355 | + } else if (oiBox.isVisible()) { | ||
| 356 | + oiBox.hide(); | ||
| 357 | + } else if (summaryPane.isVisible()) { | ||
| 358 | + cancelSummary(); | ||
| 352 | } | 359 | } |
| 353 | } | 360 | } |
| 354 | 361 | ||
| ... | @@ -585,6 +592,7 @@ | ... | @@ -585,6 +592,7 @@ |
| 585 | removeHost: removeHost, | 592 | removeHost: removeHost, |
| 586 | 593 | ||
| 587 | showDetails: showDetails, | 594 | showDetails: showDetails, |
| 595 | + showSummary: showSummary, | ||
| 588 | showTraffic: showTraffic | 596 | showTraffic: showTraffic |
| 589 | }; | 597 | }; |
| 590 | 598 | ||
| ... | @@ -737,6 +745,12 @@ | ... | @@ -737,6 +745,12 @@ |
| 737 | } | 745 | } |
| 738 | } | 746 | } |
| 739 | 747 | ||
| 748 | + function showSummary(data) { | ||
| 749 | + evTrace(data); | ||
| 750 | + populateSummary(data.payload); | ||
| 751 | + summaryPane.show(); | ||
| 752 | + } | ||
| 753 | + | ||
| 740 | function showDetails(data) { | 754 | function showDetails(data) { |
| 741 | evTrace(data); | 755 | evTrace(data); |
| 742 | populateDetails(data.payload); | 756 | populateDetails(data.payload); |
| ... | @@ -824,6 +838,33 @@ | ... | @@ -824,6 +838,33 @@ |
| 824 | return true; | 838 | return true; |
| 825 | } | 839 | } |
| 826 | 840 | ||
| 841 | + | ||
| 842 | + function toggleInstances() { | ||
| 843 | + if (!oiBox.isVisible()) { | ||
| 844 | + oiBox.show(); | ||
| 845 | + } else { | ||
| 846 | + oiBox.hide(); | ||
| 847 | + } | ||
| 848 | + } | ||
| 849 | + | ||
| 850 | + function toggleSummary() { | ||
| 851 | + if (!summaryPane.isVisible()) { | ||
| 852 | + requestSummary(); | ||
| 853 | + } else { | ||
| 854 | + cancelSummary(); | ||
| 855 | + } | ||
| 856 | + } | ||
| 857 | + | ||
| 858 | + // request overall summary data | ||
| 859 | + function requestSummary() { | ||
| 860 | + sendMessage('requestSummary', {}); | ||
| 861 | + } | ||
| 862 | + | ||
| 863 | + function cancelSummary() { | ||
| 864 | + sendMessage('cancelSummary', {}); | ||
| 865 | + summaryPane.hide(); | ||
| 866 | + } | ||
| 867 | + | ||
| 827 | // request details for the selected element | 868 | // request details for the selected element |
| 828 | // invoked from selection of a single node. | 869 | // invoked from selection of a single node. |
| 829 | function requestDetails() { | 870 | function requestDetails() { |
| ... | @@ -845,16 +886,20 @@ | ... | @@ -845,16 +886,20 @@ |
| 845 | } | 886 | } |
| 846 | 887 | ||
| 847 | function showTrafficAction() { | 888 | function showTrafficAction() { |
| 848 | - // force intents hover mode | 889 | + cancelTraffic(); |
| 849 | hoverMode = 1; | 890 | hoverMode = 1; |
| 850 | showSelectTraffic(); | 891 | showSelectTraffic(); |
| 851 | network.view.flash('Related Traffic'); | 892 | network.view.flash('Related Traffic'); |
| 852 | } | 893 | } |
| 853 | 894 | ||
| 895 | + function cancelTraffic() { | ||
| 896 | + sendMessage('cancelTraffic', {}); | ||
| 897 | + } | ||
| 898 | + | ||
| 854 | function showSelectTraffic() { | 899 | function showSelectTraffic() { |
| 855 | // if nothing is hovered over, and nothing selected, send cancel request | 900 | // if nothing is hovered over, and nothing selected, send cancel request |
| 856 | if (!hovered && nSel() === 0) { | 901 | if (!hovered && nSel() === 0) { |
| 857 | - sendMessage('cancelTraffic', {}); | 902 | + cancelTraffic(); |
| 858 | return; | 903 | return; |
| 859 | } | 904 | } |
| 860 | 905 | ||
| ... | @@ -870,12 +915,13 @@ | ... | @@ -870,12 +915,13 @@ |
| 870 | } | 915 | } |
| 871 | 916 | ||
| 872 | function showAllTrafficAction() { | 917 | function showAllTrafficAction() { |
| 918 | + cancelTraffic(); | ||
| 873 | sendMessage('requestAllTraffic', {}); | 919 | sendMessage('requestAllTraffic', {}); |
| 874 | network.view.flash('All Traffic'); | 920 | network.view.flash('All Traffic'); |
| 875 | } | 921 | } |
| 876 | 922 | ||
| 877 | function showDeviceLinkFlowsAction() { | 923 | function showDeviceLinkFlowsAction() { |
| 878 | - // force intents hover mode | 924 | + cancelTraffic(); |
| 879 | hoverMode = 2; | 925 | hoverMode = 2; |
| 880 | showDeviceLinkFlows(); | 926 | showDeviceLinkFlows(); |
| 881 | network.view.flash('Device Flows'); | 927 | network.view.flash('Device Flows'); |
| ... | @@ -884,7 +930,7 @@ | ... | @@ -884,7 +930,7 @@ |
| 884 | function showDeviceLinkFlows() { | 930 | function showDeviceLinkFlows() { |
| 885 | // if nothing is hovered over, and nothing selected, send cancel request | 931 | // if nothing is hovered over, and nothing selected, send cancel request |
| 886 | if (!hovered && nSel() === 0) { | 932 | if (!hovered && nSel() === 0) { |
| 887 | - sendMessage('cancelTraffic', {}); | 933 | + cancelTraffic(); |
| 888 | return; | 934 | return; |
| 889 | } | 935 | } |
| 890 | var hoverId = (flowsHover() && hovered && hovered.class === 'device') ? | 936 | var hoverId = (flowsHover() && hovered && hovered.class === 'device') ? |
| ... | @@ -907,7 +953,6 @@ | ... | @@ -907,7 +953,6 @@ |
| 907 | 'xlink:href': iid, | 953 | 'xlink:href': iid, |
| 908 | width: dim, | 954 | width: dim, |
| 909 | height: dim | 955 | height: dim |
| 910 | - | ||
| 911 | }); | 956 | }); |
| 912 | } | 957 | } |
| 913 | 958 | ||
| ... | @@ -940,6 +985,15 @@ | ... | @@ -940,6 +985,15 @@ |
| 940 | }); | 985 | }); |
| 941 | var dim = 30; | 986 | var dim = 30; |
| 942 | appendGlyph(svg, 2, 2, 30, '#node'); | 987 | appendGlyph(svg, 2, 2, 30, '#node'); |
| 988 | + svg.append('use') | ||
| 989 | + .attr({ | ||
| 990 | + class: 'birdBadge', | ||
| 991 | + transform: translate(8,10), | ||
| 992 | + 'xlink:href': '#bird', | ||
| 993 | + width: 18, | ||
| 994 | + height: 18, | ||
| 995 | + fill: '#fff' | ||
| 996 | + }); | ||
| 943 | 997 | ||
| 944 | $('<div>').attr('class', 'onosTitle').text(d.id).appendTo(el); | 998 | $('<div>').attr('class', 'onosTitle').text(d.id).appendTo(el); |
| 945 | 999 | ||
| ... | @@ -1720,6 +1774,8 @@ | ... | @@ -1720,6 +1774,8 @@ |
| 1720 | 1774 | ||
| 1721 | webSock.ws.onopen = function() { | 1775 | webSock.ws.onopen = function() { |
| 1722 | noWebSock(false); | 1776 | noWebSock(false); |
| 1777 | + requestSummary(); | ||
| 1778 | + oiBox.show(); | ||
| 1723 | }; | 1779 | }; |
| 1724 | 1780 | ||
| 1725 | webSock.ws.onmessage = function(m) { | 1781 | webSock.ws.onmessage = function(m) { |
| ... | @@ -1881,12 +1937,17 @@ | ... | @@ -1881,12 +1937,17 @@ |
| 1881 | updateDetailPane(); | 1937 | updateDetailPane(); |
| 1882 | } | 1938 | } |
| 1883 | 1939 | ||
| 1940 | + // update the state of the sumary pane | ||
| 1941 | + function updateSummaryPane() { | ||
| 1942 | + | ||
| 1943 | + } | ||
| 1944 | + | ||
| 1884 | // update the state of the detail pane, based on current selections | 1945 | // update the state of the detail pane, based on current selections |
| 1885 | function updateDetailPane() { | 1946 | function updateDetailPane() { |
| 1886 | var nSel = selectOrder.length; | 1947 | var nSel = selectOrder.length; |
| 1887 | if (!nSel) { | 1948 | if (!nSel) { |
| 1888 | detailPane.hide(); | 1949 | detailPane.hide(); |
| 1889 | - showTrafficAction(); // sends cancelTraffic event | 1950 | + cancelTraffic(); |
| 1890 | } else if (nSel === 1) { | 1951 | } else if (nSel === 1) { |
| 1891 | singleSelect(); | 1952 | singleSelect(); |
| 1892 | } else { | 1953 | } else { |
| ... | @@ -1936,6 +1997,40 @@ | ... | @@ -1936,6 +1997,40 @@ |
| 1936 | addMultiSelectActions(); | 1997 | addMultiSelectActions(); |
| 1937 | } | 1998 | } |
| 1938 | 1999 | ||
| 2000 | + // TODO: refactor to consolidate with populateDetails | ||
| 2001 | + function populateSummary(data) { | ||
| 2002 | + summaryPane.empty(); | ||
| 2003 | + | ||
| 2004 | + var svg = summaryPane.append('svg'), | ||
| 2005 | + iid = iconGlyphUrl(data); | ||
| 2006 | + | ||
| 2007 | + var title = summaryPane.append('h2'), | ||
| 2008 | + table = summaryPane.append('table'), | ||
| 2009 | + tbody = table.append('tbody'); | ||
| 2010 | + | ||
| 2011 | + appendGlyph(svg, 0, 0, 40, iid); | ||
| 2012 | + | ||
| 2013 | + svg.append('use') | ||
| 2014 | + .attr({ | ||
| 2015 | + class: 'birdBadge', | ||
| 2016 | + transform: translate(8,12), | ||
| 2017 | + 'xlink:href': '#bird', | ||
| 2018 | + width: 24, | ||
| 2019 | + height: 24, | ||
| 2020 | + fill: '#fff' | ||
| 2021 | + }); | ||
| 2022 | + | ||
| 2023 | + title.text('ONOS Summary'); | ||
| 2024 | + | ||
| 2025 | + data.propOrder.forEach(function(p) { | ||
| 2026 | + if (p === '-') { | ||
| 2027 | + addSep(tbody); | ||
| 2028 | + } else { | ||
| 2029 | + addProp(tbody, p, data.props[p]); | ||
| 2030 | + } | ||
| 2031 | + }); | ||
| 2032 | + } | ||
| 2033 | + | ||
| 1939 | function populateDetails(data) { | 2034 | function populateDetails(data) { |
| 1940 | detailPane.empty(); | 2035 | detailPane.empty(); |
| 1941 | 2036 | ||
| ... | @@ -2056,7 +2151,7 @@ | ... | @@ -2056,7 +2151,7 @@ |
| 2056 | // TODO: toggle button (and other widgets in the masthead) should be provided | 2151 | // TODO: toggle button (and other widgets in the masthead) should be provided |
| 2057 | // by the framework; not generated by the view. | 2152 | // by the framework; not generated by the view. |
| 2058 | 2153 | ||
| 2059 | - var showInstances; | 2154 | + //var showInstances; |
| 2060 | 2155 | ||
| 2061 | function addButtonBar(view) { | 2156 | function addButtonBar(view) { |
| 2062 | var bb = d3.select('#mast') | 2157 | var bb = d3.select('#mast') |
| ... | @@ -2069,20 +2164,20 @@ | ... | @@ -2069,20 +2164,20 @@ |
| 2069 | .on('click', cb); | 2164 | .on('click', cb); |
| 2070 | } | 2165 | } |
| 2071 | 2166 | ||
| 2072 | - showInstances = mkTogBtn('Show Instances', toggleInst); | 2167 | + //showInstances = mkTogBtn('Show Instances', toggleInst); |
| 2073 | } | 2168 | } |
| 2074 | 2169 | ||
| 2075 | - function instShown() { | 2170 | + //function instShown() { |
| 2076 | - return showInstances.classed('active'); | 2171 | + // return showInstances.classed('active'); |
| 2077 | - } | 2172 | + //} |
| 2078 | - function toggleInst() { | 2173 | + //function toggleInst() { |
| 2079 | - showInstances.classed('active', !instShown()); | 2174 | + // showInstances.classed('active', !instShown()); |
| 2080 | - if (instShown()) { | 2175 | + // if (instShown()) { |
| 2081 | - oiBox.show(); | 2176 | + // oiBox.show(); |
| 2082 | - } else { | 2177 | + // } else { |
| 2083 | - oiBox.hide(); | 2178 | + // oiBox.hide(); |
| 2084 | - } | 2179 | + // } |
| 2085 | - } | 2180 | + //} |
| 2086 | 2181 | ||
| 2087 | function panZoom() { | 2182 | function panZoom() { |
| 2088 | return false; | 2183 | return false; |
| ... | @@ -2370,6 +2465,7 @@ | ... | @@ -2370,6 +2465,7 @@ |
| 2370 | resize: resize | 2465 | resize: resize |
| 2371 | }); | 2466 | }); |
| 2372 | 2467 | ||
| 2468 | + summaryPane = onos.ui.addFloatingPanel('topo-summary'); | ||
| 2373 | detailPane = onos.ui.addFloatingPanel('topo-detail'); | 2469 | detailPane = onos.ui.addFloatingPanel('topo-detail'); |
| 2374 | oiBox = onos.ui.addFloatingPanel('topo-oibox', 'TL'); | 2470 | oiBox = onos.ui.addFloatingPanel('topo-oibox', 'TL'); |
| 2375 | 2471 | ... | ... |
-
Please register or login to post a comment