You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ea...@apache.org on 2019/01/23 14:03:34 UTC

[qpid-dispatch] branch master updated: DISPATCH-1251 Allow traffic animations to run simultaneously

This is an automated email from the ASF dual-hosted git repository.

eallen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 1914ebe  DISPATCH-1251 Allow traffic animations to run simultaneously
1914ebe is described below

commit 1914ebec448906500393722fbb542a2d82c077ed
Author: Ernest Allen <ea...@redhat.com>
AuthorDate: Wed Jan 23 09:03:19 2019 -0500

    DISPATCH-1251 Allow traffic animations to run simultaneously
---
 console/stand-alone/plugin/html/qdrTopology.html   | 16 ++--
 console/stand-alone/plugin/js/topology/map.js      |  8 +-
 .../stand-alone/plugin/js/topology/qdrTopology.js  | 93 +++++++++++-----------
 console/stand-alone/plugin/js/topology/traffic.js  | 46 +++++++----
 4 files changed, 88 insertions(+), 75 deletions(-)

diff --git a/console/stand-alone/plugin/html/qdrTopology.html b/console/stand-alone/plugin/html/qdrTopology.html
index 0057fab..14b5c8b 100644
--- a/console/stand-alone/plugin/html/qdrTopology.html
+++ b/console/stand-alone/plugin/html/qdrTopology.html
@@ -221,16 +221,16 @@ td.more-info {
 <div class="qdrTopology" ng-controller="QDR.TopologyController">
     <div class="legend-container page-menu navbar-collapse collapse">
         <uib-accordion id="topo_legend" close-others="false">
-            <div uib-accordion-group class="panel-default" is-open="legend.status.optionsOpen" heading="Show Traffic">
+            <div uib-accordion-group class="panel-default" is-open="legendOptions.traffic.open" heading="Show Traffic">
                 <ul class="options">
-                    <li class="legend-sublist" ng-hide="!legendOptions.showTraffic">
+                    <li class="legend-sublist" ng-hide="!legendOptions.traffic.open">
                         <ul>
                             <li><label>
-                                    <input type='radio' ng-model="legendOptions.trafficType" value="dots" />
+                                    <input type='checkbox' ng-model="legendOptions.traffic.dots" value="dots" />
                                     Message path by address
                                 </label></li>
                             <li>
-                                <ul class="addresses" ng-show="legendOptions.trafficType === 'dots'">
+                                <ul class="addresses" ng-show="legendOptions.traffic.dots">
                                     <li ng-repeat="(address, color) in addresses" class="legend-line">
                                         <checkbox style="background-color: {{addressColors[address]}};" title="{{address}}"
                                             ng-change="addressFilterChanged()" ng-model="addresses[address]"
@@ -244,11 +244,11 @@ td.more-info {
                         </ul>
                         <ul>
                             <li><label>
-                                    <input type='radio' ng-model="legendOptions.trafficType" value="congestion" />
+                                    <input type='checkbox' ng-model="legendOptions.traffic.congestion" value="congestion" />
                                     Link utilization
                                 </label></li>
                             <li>
-                                <ul class="congestion" ng-show="legendOptions.trafficType === 'congestion'">
+                                <ul class="congestion" ng-show="legendOptions.traffic.congestion">
                                     <li>
                                         <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
                                             version="1.1" preserveAspectRatio="xMidYMid meet" width="140" height="40">
@@ -273,10 +273,10 @@ td.more-info {
                     </li>
                 </ul>
             </div>
-            <div uib-accordion-group class="panel-default" is-open="legend.status.legendOpen" heading="Legend">
+            <div uib-accordion-group class="panel-default" is-open="legendOptions.legend.open" heading="Legend">
                 <div id="topo_svg_legend"></div>
             </div>
-            <div id="backgroundMap" uib-accordion-group class="panel-default" is-open="legend.status.mapOpen" heading="Background map">
+            <div id="backgroundMap" uib-accordion-group class="panel-default" is-open="legendOptions.map.open" heading="Background map">
                 <div id="topo_mapOptions">
                     <div class="colorPicker">
                         <ul>
diff --git a/console/stand-alone/plugin/js/topology/map.js b/console/stand-alone/plugin/js/topology/map.js
index c03cfa5..989ada4 100644
--- a/console/stand-alone/plugin/js/topology/map.js
+++ b/console/stand-alone/plugin/js/topology/map.js
@@ -51,7 +51,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
       color = this.$scope.mapOptions.oceanColor;
     d3.select('g.geo rect.ocean')
       .style('fill', color);
-    if (this.$scope.legend.status.mapOpen) {
+    if (this.$scope.legendOptions.map.open) {
       d3.select('#main_container')
         .style('background-color', color);
     } else {
@@ -117,7 +117,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
 
       this.geo = svg.append('g')
         .attr('class', 'geo')
-        .style('opacity', this.$scope.legend.status.mapOpen ? '1' : '0');
+        .style('opacity', this.$scope.legendOptions.map.open ? '1' : '0');
 
       this.geo.append('rect')
         .attr('class', 'ocean')
@@ -125,7 +125,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
         .attr('height', height)
         .attr('fill', '#FFF');
 
-      if (this.$scope.legend.status.mapOpen) {
+      if (this.$scope.legendOptions.map.open) {
         this.svg.call(this.zoom)
           .on('dblclick.zoom', null);
       }
@@ -193,7 +193,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
   }
 
   zoomed() {
-    if (d3.event && !this.$scope.current_node && !this.$scope.mousedown_node && this.$scope.legend.status.mapOpen) {
+    if (d3.event && !this.$scope.current_node && !this.$scope.mousedown_node && this.$scope.legendOptions.map.open) {
       let scale = d3.event.scale,
         t = d3.event.translate,
         dx = t[0] - this.last.translate[0],
diff --git a/console/stand-alone/plugin/js/topology/qdrTopology.js b/console/stand-alone/plugin/js/topology/qdrTopology.js
index a1e8580..9b75668 100644
--- a/console/stand-alone/plugin/js/topology/qdrTopology.js
+++ b/console/stand-alone/plugin/js/topology/qdrTopology.js
@@ -48,7 +48,7 @@ export class TopologyController {
     this.controllerName = "QDR.TopologyController";
 
     let QDRLog = new QDRLogger($log, "TopologyController");
-    const TOPOOPTIONSKEY = "topoOptions";
+    const TOPOOPTIONSKEY = "topoLegendOptions";
 
     //  - nodes is an array of router/client info. these are the circles
     //  - links is an array of connections between the routers. these are the lines with arrows
@@ -59,20 +59,23 @@ export class TopologyController {
 
     // restore the state of the legend sections
     $scope.legendOptions = angular.fromJson(localStorage[TOPOOPTIONSKEY]) || {
-      showTraffic: false,
-      trafficType: "dots",
-      mapOpen: false,
-      legendOpen: true
+      traffic: {
+        open: false,
+        dots: false,
+        congestion: false
+      },
+      legend: {
+        open: true
+      },
+      map: {
+        open: false
+      }
     };
-    if (typeof $scope.legendOptions.mapOpen == "undefined")
-      $scope.legendOptions.mapOpen = false;
-    if (typeof $scope.legendOptions.legendOpen == "undefined")
-      $scope.legendOptions.legendOpen = false;
     let backgroundMap = new BackgroundMap(
       $scope,
       // notify: called each time a pan/zoom is performed
       function () {
-        if ($scope.legend.status.mapOpen) {
+        if ($scope.legendOptions.map.open) {
           // set all the nodes' x,y position based on their saved lon,lat
           forceData.nodes.setXY(backgroundMap);
           forceData.nodes.savePositions();
@@ -86,17 +89,6 @@ export class TopologyController {
     let urlPrefix = $location.absUrl();
     urlPrefix = urlPrefix.split("#")[0];
 
-    if (!$scope.legendOptions.trafficType)
-      $scope.legendOptions.trafficType = "dots";
-    $scope.legend = {
-      status: {
-        legendOpen: true,
-        optionsOpen: true,
-        mapOpen: false
-      }
-    };
-    $scope.legend.status.optionsOpen = $scope.legendOptions.showTraffic;
-    $scope.legend.status.mapOpen = $scope.legendOptions.mapOpen;
     let traffic = new Traffic(
       $scope,
       $timeout,
@@ -104,41 +96,46 @@ export class TopologyController {
       separateAddresses,
       Nodes.radius("inter-router"),
       forceData,
-      $scope.legendOptions.trafficType,
+      ["dots", "congestion"].filter(t => $scope.legendOptions.traffic[t]),
       urlPrefix
     );
 
-    // the showTraaffic checkbox was just toggled (or initialized)
-    $scope.$watch("legend.status.optionsOpen", function () {
-      $scope.legendOptions.showTraffic = $scope.legend.status.optionsOpen;
+    let changeTraffic = function (checked, type) {
       localStorage[TOPOOPTIONSKEY] = JSON.stringify($scope.legendOptions);
-      if ($scope.legend.status.optionsOpen) {
-        traffic.start();
-      } else {
-        traffic.stop();
-        traffic.remove();
-        restart();
+      if ($scope.legendOptions.traffic.open) {
+        if (checked) {
+          traffic.addAnimationType(type, separateAddresses, Nodes.radius("inter-router"));
+        } else {
+          traffic.remove(type);
+        }
       }
+      restart();
+    };
+    // the dots animation was checked/unchecked
+    $scope.$watch("legendOptions.traffic.dots", function (newValue) {
+      changeTraffic(newValue, "dots");
     });
-    // the traffic type was just changed or initialized
-    $scope.$watch("legendOptions.trafficType", function () {
+    // the congestion animation was checked/unchecked
+    $scope.$watch("legendOptions.traffic.congestion", function (newValue) {
+      changeTraffic(newValue, "congestion");
+    });
+    // the traffic section was opened/closed
+    $scope.$watch("legendOptions.traffic.open", function () {
       localStorage[TOPOOPTIONSKEY] = JSON.stringify($scope.legendOptions);
-      if ($scope.legendOptions.showTraffic) {
-        restart();
-        traffic.setAnimationType(
-          $scope.legendOptions.trafficType,
-          separateAddresses,
-          Nodes.radius("inter-router")
-        );
-        traffic.start();
+      if ($scope.legendOptions.traffic.open) {
+        // opened the traffic area
+        changeTraffic($scope.legendOptions.traffic.dots, "dots");
+        changeTraffic($scope.legendOptions.traffic.congestion, "congestion");
+      } else {
+        traffic.remove();
       }
+      restart();
     });
     // the background map was shown or hidden
-    $scope.$watch("legend.status.mapOpen", function (newvalue, oldvalue) {
-      $scope.legendOptions.mapOpen = $scope.legend.status.mapOpen;
+    $scope.$watch("legendOptions.map.open", function (newvalue, oldvalue) {
       localStorage[TOPOOPTIONSKEY] = JSON.stringify($scope.legendOptions);
       // map was shown
-      if ($scope.legend.status.mapOpen && backgroundMap.initialized) {
+      if ($scope.legendOptions.map.open && backgroundMap.initialized) {
         // respond to pan/zoom events
         backgroundMap.restartZoom();
         // set the main_container div's background color to the ocean color
@@ -260,7 +257,7 @@ export class TopologyController {
     // initialize the nodes and links array from the QDRService.topology._nodeInfo object
     var initForceGraph = function () {
       if (width < 768) {
-        $scope.legend.status.mapOpen = false;
+        $scope.legendOptions.map.open = false;
       }
       let nodeInfo = QDRService.management.topology.nodeInfo();
       let nodeCount = Object.keys(nodeInfo).length;
@@ -283,7 +280,7 @@ export class TopologyController {
         // read the map data from the data file and build the map layer
         backgroundMap.init($scope, svg, width, height).then(function () {
           forceData.nodes.saveLonLat(backgroundMap);
-          backgroundMap.setMapOpacity($scope.legend.status.mapOpen);
+          backgroundMap.setMapOpacity($scope.legendOptions.map.open);
         });
         addDefs(svg);
         addGradient(svg);
@@ -512,8 +509,8 @@ export class TopologyController {
 
       // reset the markers based on current highlighted/selected
       if (
-        !$scope.legend.status.optionsOpen ||
-        $scope.legendOptions.trafficType === "dots"
+        !$scope.legendOptions.traffic.open ||
+        !$scope.legendOptions.traffic.congestion
       ) {
         path
           .select(".link")
diff --git a/console/stand-alone/plugin/js/topology/traffic.js b/console/stand-alone/plugin/js/topology/traffic.js
index 9a1d2e0..e192374 100644
--- a/console/stand-alone/plugin/js/topology/traffic.js
+++ b/console/stand-alone/plugin/js/topology/traffic.js
@@ -44,19 +44,22 @@ export class Traffic {
     converter,
     radius,
     topology,
-    type,
+    types,
     prefix
   ) {
     $scope.addressColors = {};
     this.QDRService = QDRService;
-    this.type = type; // moving dots or colored path
     this.prefix = prefix; // url prefix used in svg url()s
+    this.types = [];
+    this.viss = [];
     this.topology = topology; // contains the list of router nodes
     this.$scope = $scope;
     this.$timeout = $timeout;
     // internal variables
     this.interval = null; // setInterval handle
-    this.setAnimationType(type, converter, radius);
+    types.forEach(function (t) {
+      this.addAnimationType(t, converter, radius);
+    }.bind(this));
   }
   // stop updating the traffic data
   stop() {
@@ -67,26 +70,37 @@ export class Traffic {
   }
   // start updating the traffic data
   start() {
+    this.stop();
     this.doUpdate();
     this.interval = setInterval(this.doUpdate.bind(this), transitionDuration);
   }
-  // remove any animations that are in progress
-  remove() {
-    if (this.vis) this.vis.remove();
+  // remove animations that are in progress
+  remove(type) {
+    let all = !(type);
+    let i = this.viss.length - 1;
+    while (i >= 0) {
+      if (all || this.viss[i].type === type) {
+        this.viss[i].remove();
+        this.viss.splice(i, 1);
+      }
+      i--;
+    }
+    if (this.viss.length === 0) {
+      this.stop();
+    }
   }
-  // called when one of the address checkboxes is toggled
-  setAnimationType(type, converter, radius) {
-    this.stop();
-    this.remove();
-    this.type = type;
-    this.vis =
-      type === "dots" ?
+  // called when one of the address checkboxes is toggled on
+  addAnimationType(type, converter, radius) {
+    if (!this.viss.some(v => v.type === type)) {
+      this.viss.push(type === "dots" ?
         new Dots(this, converter, radius) :
-        new Congestion(this);
+        new Congestion(this));
+    }
+    this.start();
   }
   // called periodically to refresh the traffic flow
   doUpdate() {
-    this.vis.doUpdate();
+    this.viss.forEach(v => v.doUpdate());
   }
 }
 
@@ -118,6 +132,7 @@ class TrafficAnimation {
 class Congestion extends TrafficAnimation {
   constructor(traffic) {
     super(traffic);
+    this.type = "congestion";
     this.init_markerDef();
   }
   init_markerDef() {
@@ -304,6 +319,7 @@ class Congestion extends TrafficAnimation {
 class Dots extends TrafficAnimation {
   constructor(traffic, converter, radius) {
     super(traffic);
+    this.type = "dots";
     this.excludedAddresses = localStorage[CHORDFILTERKEY] ?
       JSON.parse(localStorage[CHORDFILTERKEY]) :
       [];


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org