Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 06296ba31 -> 5240adc14


DISPATCH-318: Prevent dragging nodes off edge of screen. Also minor visual 
fixes for displaying multiple client.


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/5240adc1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/5240adc1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/5240adc1

Branch: refs/heads/master
Commit: 5240adc14e33533b56fc8a79af7fde036bdb5a26
Parents: 06296ba
Author: Ernest Allen <[email protected]>
Authored: Fri Jun 10 13:16:08 2016 -0400
Committer: Ernest Allen <[email protected]>
Committed: Fri Jun 10 13:16:08 2016 -0400

----------------------------------------------------------------------
 .../src/main/webapp/plugin/css/dispatch.css     |  2 +-
 .../src/main/webapp/plugin/js/qdrService.js     | 38 +++++++++
 .../src/main/webapp/plugin/js/qdrTopology.js    | 83 +++++++++++++-------
 3 files changed, 92 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/5240adc1/console/hawtio/src/main/webapp/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/css/dispatch.css 
b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
index bc7ccfc..4b6e159 100644
--- a/console/hawtio/src/main/webapp/plugin/css/dispatch.css
+++ b/console/hawtio/src/main/webapp/plugin/css/dispatch.css
@@ -514,7 +514,7 @@ circle.subcircle {
     stroke-width: 1px;
     /* stroke-dasharray: 2; */
     fill-opacity: 0;
-    stroke: black;
+    stroke: darkgray;
 }
 
 .leaf circle {

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/5240adc1/console/hawtio/src/main/webapp/plugin/js/qdrService.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrService.js 
b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
index c46e7ad..5dcd3f4 100644
--- a/console/hawtio/src/main/webapp/plugin/js/qdrService.js
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrService.js
@@ -255,6 +255,44 @@ var QDR = (function(QDR) {
                        return d.nodeType ==='on-demand' && (d.properties && 
d.properties.product === 'qpid-cpp');
                },
 
+               isAConsole: function (properties, connectionId, nodeType, key) {
+                       return self.isConsole({properties: properties, 
connectionId: connectionId, nodeType: nodeType, key: key})
+               },
+               isConsole: function (d) {
+                       // TODO: use connection properties when available
+                       if (d.properties.console_identifier == 'Dispatch 
console')
+                               return true;
+                       // until connection properties can difinitively 
identify consoles:
+                       var connid = d.connectionId;
+                       if (connid && d.nodeType === 'normal') {
+                               // find all the endpoint links for this router 
that have this connid
+                               var linkInfo = 
self.topology.nodeInfo()[d.key]['.router.link']
+                               var outs = 0, ins = 0;
+                               var outaddr, inaddr;
+                               linkInfo.results.forEach( function (link) {
+                                       if 
(self.valFor(linkInfo.attributeNames, link, 'connectionId') == connid &&
+                                               
self.valFor(linkInfo.attributeNames, link, 'linkType') == 'endpoint') {
+                                               if 
(self.valFor(linkInfo.attributeNames, link, 'linkDir') == 'in') {
+                                                       ++ins;
+                                                       inaddr = 
self.valFor(linkInfo.attributeNames, link, 'owningAddr')
+                                               }
+                                               if 
(self.valFor(linkInfo.attributeNames, link, 'linkDir') == 'out') {
+                                                       ++outs;
+                                                       outaddr = 
self.valFor(linkInfo.attributeNames, link, 'owningAddr')
+                                               }
+                                               return true;
+                                       }
+                               })
+                               // consoles have 1 out link with an address 
that starts with Ltemp. and
+                               // 1 in link with no address
+                               if (outs == 1 && ins == 1 &&
+                                       inaddr == null && 
outaddr.startsWith('Ltemp.')) {
+                                       return true;
+                               }
+                       }
+                       return false;
+               },
+
       /*
        * send the management messages that build up the topology
        *

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/5240adc1/console/hawtio/src/main/webapp/plugin/js/qdrTopology.js
----------------------------------------------------------------------
diff --git a/console/hawtio/src/main/webapp/plugin/js/qdrTopology.js 
b/console/hawtio/src/main/webapp/plugin/js/qdrTopology.js
index 162af05..e612df4 100644
--- a/console/hawtio/src/main/webapp/plugin/js/qdrTopology.js
+++ b/console/hawtio/src/main/webapp/plugin/js/qdrTopology.js
@@ -48,9 +48,9 @@ var QDR = (function (QDR) {
                $scope.$on('showEntityForm', function (event, args) {
                        var attributes = args.attributes;
                        var entityTypes = 
QDRService.schema.entityTypes[args.entity].attributes;
-                       Object.keys(attributes).forEach( function (attr) {
-                               if (entityTypes[attr])
-                                       attributes[attr].description = 
entityTypes[attr]
+                       attributes.forEach( function (attr) {
+                               if (entityTypes[attr.attributeName] && 
entityTypes[attr.attributeName].description)
+                                       attr.description = 
entityTypes[attr.attributeName].description
                        })
                        $scope.attributes = attributes;
                        $scope.form = args.entity;
@@ -467,11 +467,13 @@ var QDR = (function (QDR) {
                                                if (position.y > height)
                                                        position.y = 
nodes[parent].y + 40 + Math.cos(Math.PI/2 * client)
                                                var node = aNode(id, name, 
role, nodeInfo, nodes.length, position.x, position.y, j, position.fixed, 
properties)
-                                               var nodeType = role === 
'normal' ? (properties.console_identifier == 'Dispatch console' ? 'console' : 
'client') : 'broker';
+                                               var nodeType = 
QDRService.isAConsole(properties, QDRService.valFor(attrs, conns[j], 
"identity"), role, node.key)
+
                                                if (role === 'normal') {
                                                        node.user = 
QDRService.valFor(attrs, conns[j], "user")
                                                        node.isEncrypted = 
QDRService.valFor(attrs, conns[j], "isEncrypted")
                                                        node.host = 
QDRService.valFor(attrs, conns[j], "host")
+                                                       node.connectionId = 
QDRService.valFor(attrs, conns[j], "identity")
 
                                                        if 
(!normalsParent[nodeType]) {
                                                                
normalsParent[nodeType] = node;
@@ -675,9 +677,13 @@ var QDR = (function (QDR) {
                path.attr('d', function (d) {
                                //QDR.log.debug("in tick for d");
                                //console.dump(d);
+                               var dtx = Math.max(0, Math.min(width, 
d.target.x)),
+                                   dty = Math.max(0, Math.min(height, 
d.target.y)),
+                                   dsx = Math.max(0, Math.min(width, 
d.source.x)),
+                                       dsy = Math.max(0, Math.min(height, 
d.source.y));
 
-                   var deltaX = d.target.x - d.source.x,
-                       deltaY = d.target.y - d.source.y,
+                   var deltaX = dtx - dsx,
+                       deltaY = dty - dsy,
                        dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
                        normX = deltaX / dist,
                        normY = deltaY / dist;
@@ -691,16 +697,23 @@ var QDR = (function (QDR) {
                                                sourcePadding = d.left ? 
radiusNormal + 18  : radiusNormal;
                                                targetPadding = d.right ? 
radiusNormal + 16 : radiusNormal;
                        }
-                       var sourceX = d.source.x + (sourcePadding * normX),
-                       sourceY = d.source.y + (sourcePadding * normY),
-                       targetX = d.target.x - (targetPadding * normX),
-                       targetY = d.target.y - (targetPadding * normY);
+                       var sourceX = dsx + (sourcePadding * normX),
+                       sourceY = dsy + (sourcePadding * normY),
+                       targetX = dtx - (targetPadding * normX),
+                       targetY = dty - (targetPadding * normY);
+                                       sourceX = Math.max(0, Math.min(width, 
sourceX))
+                                       sourceY = Math.max(0, Math.min(width, 
sourceY))
+                                       targetX = Math.max(0, Math.min(width, 
targetX))
+                                       targetY = Math.max(0, Math.min(width, 
targetY))
+
                    return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' 
+ targetY;
                });
 
                circle.attr('transform', function (d) {
                    d.x = Math.max(d.x, radiusNormal * 2);
                    d.y = Math.max(d.y, radiusNormal * 2);
+                               d.x = Math.max(0, Math.min(width, d.x))
+                               d.y = Math.max(0, Math.min(height, d.y))
                    return 'translate(' + d.x + ',' + d.y + ')';
                });
                if (!animate) {
@@ -767,6 +780,14 @@ var QDR = (function (QDR) {
             return null;
         }
 
+               function clearPopups() {
+            d3.select("#crosssection").style("display", "none");
+                       $('.hastip').empty();
+            d3.select("#multiple_details").style("display", "none")
+            d3.select("#link_details").style("display", "none")
+                       d3.select('#node_context_menu').style('display', 
'none');
+
+               }
                function removeCrosssection() {
                        setTimeout(function () {
                                d3.select("[id^=tooltipsy]").remove()
@@ -884,6 +905,7 @@ var QDR = (function (QDR) {
                 .on("click", function (d) {
                     dblckickPos = d3.mouse(this);
                     d3.event.stopPropagation();
+                    clearPopups();
                     var diameter = 400;
                     var format = d3.format(",d");
                     var pack = d3.layout.pack()
@@ -891,16 +913,13 @@ var QDR = (function (QDR) {
                         .padding(-10)
                         .value(function(d) { return d.size; });
 
+                    d3.select("#crosssection svg").remove();
                     var svg = d3.select("#crosssection").append("svg")
                         .attr("width", diameter)
                         .attr("height", diameter)
                     var svgg = svg.append("g")
                         .attr("transform", "translate(2,2)");
 
-                                       svg.on('click', function (d) {
-                                               removeCrosssection();
-                                       })
-
                                        var root = {
                                                name: "links between " + 
d.source.name + " and " + d.target.name,
                                                children: []
@@ -1002,15 +1021,13 @@ var QDR = (function (QDR) {
                                // add new circles and set their 
attr/class/behavior
                        return g.append('svg:circle')
                            .attr('class', 'node')
-                           .attr('r', function (d) {
-                               return radii[d.nodeType];
-                           })
+                           .attr('r', function (d) { return radii[d.nodeType] 
} )
                            .classed('fixed', function (d) {return d.fixed})
                        .classed('temp', function(d) { return 
QDRService.nameFromId(d.key) == '__internal__'; } )
                        .classed('normal', function(d) { return d.nodeType == 
'normal' } )
                        .classed('inter-router', function(d) { return 
d.nodeType == 'inter-router' } )
                        .classed('on-demand', function(d) { return d.nodeType 
== 'on-demand' } )
-                       .classed('console', function(d) { return 
d.properties.console_identifier == 'Dispatch console' } )
+                       .classed('console', function(d) { return 
QDRService.isConsole(d) } )
                        .classed('artemis', function(d) { return 
QDRService.isArtemis(d) } )
                        .classed('qpid-cpp', function(d) { return 
QDRService.isQpid(d) } )
                        .classed('client', function(d) { return d.nodeType === 
'normal' && !d.properties.console_identifier } )
@@ -1104,8 +1121,7 @@ var QDR = (function (QDR) {
                         selected_node = null;
                     }
                     else {
-                                               // don't select nodes that 
represent multiple clients/consoles
-                        if (!d.normals || d.normals.length < 2)
+                        if (d.nodeType !== 'normal' && d.nodeType !== 
'on-demand')
                             selected_node = mousedown_node;
                     }
                     for (var i=0; i<links.length; ++i) {
@@ -1138,7 +1154,10 @@ var QDR = (function (QDR) {
 
                 })
                 .on("click", function (d) {
-                                       if (!d.normals || d.normals.length < 2) 
{
+                    // clicked on a circle
+                    clearPopups();
+                                       if (!d.normals) {
+                                               // circle was a router or a 
broker
                                    if ( QDRService.isArtemis(d) && 
Core.ConnectionName === 'Artemis' ) {
                                                        
$location.path('/jmx/attributes?tab=artemis&con=Artemis')
                                                }
@@ -1175,13 +1194,13 @@ var QDR = (function (QDR) {
                                    y = 4;
                                return y;})
                            .attr('class', 'id')
-                       .classed('console', function(d) { return 
d.properties.console_identifier == 'Dispatch console' } )
+                       .classed('console', function(d) { return 
QDRService.isConsole(d) } )
                        .classed('normal', function(d) { return d.nodeType === 
'normal' } )
                        .classed('on-demand', function(d) { return d.nodeType 
=== 'on-demand' } )
                        .classed('artemis', function(d) { return 
QDRService.isArtemis(d) } )
                        .classed('qpid-cpp', function(d) { return 
QDRService.isQpid(d) } )
                            .text(function (d) {
-                               if (d.properties.console_identifier == 
'Dispatch console') {
+                               if (QDRService.isConsole(d)) {
                                    return '\uf108'; // icon-desktop for this 
console
                                }
                                                if (QDRService.isArtemis(d)) {
@@ -1202,7 +1221,7 @@ var QDR = (function (QDR) {
                        var x = '';
                        if (d.normals && d.normals.length > 1)
                            x = " x " + d.normals.length;
-                           if (d.properties.console_identifier == 'Dispatch 
console') {
+                           if (QDRService.isConsole(d)) {
                            return 'Dispatch console' + x
                        }
                            if (d.properties.product == 'qpid-cpp') {
@@ -1221,12 +1240,16 @@ var QDR = (function (QDR) {
 
                        // add subcircles
                        svg.selectAll('.subcircle').remove();
-
-                       svg.selectAll('.multiple')
-                               .insert('svg:circle', '.normal')
-                                       .attr('class', 'subcircle')
-                                       .attr('r', 18)
-
+                       var multiples = svg.selectAll('.multiple')
+                       multiples.each( function (d) {
+                               d.normals.forEach( function (n, i) {
+                                       if (i<d.normals.length-1 && i<3) // 
only show a few shadow circles
+                                               this.insert('svg:circle', 
":first-child")
+                                               .attr('class', 'subcircle node')
+                                               .attr('r', 15 - i)
+                                               .attr('transform', 
"translate("+ 4 * (i+1) +", 0)")
+                               }, d3.select(this))
+                       })
 
                        // dynamically create the legend based on which node 
types are present
                        var legendNodes = [];


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to