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 2018/12/10 16:59:25 UTC
[3/3] qpid-dispatch git commit: DISPATCH-1217 Treat node.fixed as
bitmap
DISPATCH-1217 Treat node.fixed as bitmap
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/81e58b46
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/81e58b46
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/81e58b46
Branch: refs/heads/master
Commit: 81e58b4628173d1392d32dcfedce0312065bea41
Parents: e9b7bd5
Author: Ernest Allen <ea...@redhat.com>
Authored: Mon Dec 10 11:58:58 2018 -0500
Committer: Ernest Allen <ea...@redhat.com>
Committed: Mon Dec 10 11:58:58 2018 -0500
----------------------------------------------------------------------
console/stand-alone/plugin/css/dispatch.css | 10 -
.../stand-alone/plugin/html/qdrTopology.html | 179 ++-
console/stand-alone/plugin/js/amqp/utilities.js | 39 +-
.../plugin/js/dlgDetailController.js | 53 +-
.../stand-alone/plugin/js/topology/legend.js | 138 +++
console/stand-alone/plugin/js/topology/links.js | 54 +-
console/stand-alone/plugin/js/topology/map.js | 69 +-
console/stand-alone/plugin/js/topology/nodes.js | 99 +-
.../plugin/js/topology/qdrTopology.js | 1086 ++++++++----------
.../stand-alone/plugin/js/topology/svgUtils.js | 249 ++++
.../stand-alone/plugin/js/topology/topoUtils.js | 242 ++--
.../stand-alone/plugin/js/topology/traffic.js | 144 ++-
console/stand-alone/test/links.js | 54 +-
13 files changed, 1359 insertions(+), 1057 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/css/dispatch.css
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/css/dispatch.css b/console/stand-alone/plugin/css/dispatch.css
index f41754b..709ce43 100644
--- a/console/stand-alone/plugin/css/dispatch.css
+++ b/console/stand-alone/plugin/css/dispatch.css
@@ -1143,12 +1143,6 @@ svg {
/*height: 100%; */
}
- div#topologyForm .ngViewport, div#topologyForm .gridStyle {
- height: auto !important;
- min-height: initial !important;
- overflow: initial;
- }
-
div#multiple_details, div#link_details {
height: 300px;
width: 700px;
@@ -1819,10 +1813,6 @@ span.logo {
top: 10px;
}
- #topologyForm > div {
- width: auto;
- }
-
div.chartContainer {
width: auto;
margin-top: 1em;
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/html/qdrTopology.html
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/html/qdrTopology.html b/console/stand-alone/plugin/html/qdrTopology.html
index 5ba514b..0057fab 100644
--- a/console/stand-alone/plugin/html/qdrTopology.html
+++ b/console/stand-alone/plugin/html/qdrTopology.html
@@ -18,7 +18,7 @@ under the License.
-->
<style>
-@media (min-width: 768px) {
+ @media (min-width: 768px) {
.showLeft {
display: block;
}
@@ -27,6 +27,9 @@ under the License.
.showLeft {
display: none;
}
+ #backgroundMap {
+ display: none;
+ }
div.qdrTopology div.legend-container.page-menu {
top: 0;
right: auto;
@@ -35,7 +38,7 @@ under the License.
}
}
-#popover-div, #fixed-popup {
+#popover-div {
position: absolute;
z-index: 200;
border-radius: 4px;
@@ -53,41 +56,6 @@ under the License.
font-size: 10px;
}
-#topologyForm {
- border-right: 1px solid lightgray;
- border-bottom: 1px solid lightgray;
- padding: 2px;
- /* position: absolute; */
- background-color: #333333;
- width: 300px;
-}
-
- #topologyForm .infoGrid span {
- display: inline-block;
- width: 50%;
- height: 28px;
- padding: 3px 6px 2px 6px;
- border-right: 1px solid #666666;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- }
-
- #topologyForm .infoGrid span:last-child {
- text-align: right;
- border-right: 0;
- }
- #topologyForm .infoGrid div {
- height: 28px;
- }
- #topologyForm .infoGrid div.odd {
- background-color: #444444;
- }
-
- #topologyForm .infoGrid div.listening-on {
- background-color: #336633;
- }
-
.legend-container {
position: absolute;
top: 1em;
@@ -135,8 +103,8 @@ under the License.
margin-bottom: 0;
padding-bottom: 0;
}
- /* the checkboxes for the addresses */
- #topo_legend ul li input[type=checkbox]:checked + label::before {
+/* the checkboxes for the addresses */
+#topo_legend ul li input[type=checkbox]:checked + label::before {
content:'\2713';
font-weight: bold;
font-size: 16px;
@@ -146,12 +114,12 @@ under the License.
position: absolute;
top: -8px;
left: -1px;
- }
- /* The aggregate addresses need a black checkbox on the white background */
- #topo_legend ul li input[type=checkbox]:checked + label.aggregate::before {
+}
+/* The aggregate addresses need a black checkbox on the white background */
+#topo_legend ul li input[type=checkbox]:checked + label.aggregate::before {
color: black;
- /* left: 1px; */
- }
+/* left: 1px; */
+}
#topo_legend ul.addresses button.btn-default {
background-image: none;
color: white;
@@ -159,8 +127,8 @@ under the License.
}
#topo_legend li.legend-sublist ul {
- margin-bottom: 0.5em;
- }
+ margin-bottom: 0.5em;
+}
#topo_legend li.legend-sublist ul.addresses{
max-height: 11.6em; /* show up to 4 addresses */
@@ -171,11 +139,11 @@ li.legend-sublist > ul ul {
margin-left: 1em;
}
-#popover-div h5, #fixed-popup h5 {
+#popover-div h5 {
margin-top: 1em;
margin-bottom: 0;
}
-#popover-div h5:first-of-type, #fixed-popup h5:first-of-type {
+#popover-div h5:first-of-type {
margin-top:0;
}
@@ -198,23 +166,23 @@ table.popupTable td {
}
.graticule {
- fill: none;
- stroke: #777;
- stroke-width: .5px;
- stroke-opacity: .5;
+ fill: none;
+ stroke: #777;
+ stroke-width: .5px;
+ stroke-opacity: .5;
}
g.geo path.land {
- fill: #dcedf7;
- stroke: #000;
- stroke-opacity: 1;
- stroke-width: 1px;
+ fill: #dcedf7;
+ stroke: #000;
+ stroke-opacity: 1;
+ stroke-width: 1px;
}
.boundary {
- fill: none;
- stroke: #333;
- stroke-width: 5px;
+ fill: none;
+ stroke: #333;
+ stroke-width: 5px;
}
.panel-group {
@@ -254,40 +222,44 @@ td.more-info {
<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">
- <ul class="options">
- <li class="legend-sublist" ng-hide="!legendOptions.showTraffic">
- <ul>
- <li><label>
- <input type='radio' ng-model="legendOptions.trafficType" value="dots" />
- Message path by address
- </label></li>
- <li>
- <ul class="addresses" ng-show="legendOptions.trafficType === 'dots'">
+ <ul class="options">
+ <li class="legend-sublist" ng-hide="!legendOptions.showTraffic">
+ <ul>
+ <li><label>
+ <input type='radio' ng-model="legendOptions.trafficType" value="dots" />
+ Message path by address
+ </label></li>
+ <li>
+ <ul class="addresses" ng-show="legendOptions.trafficType === '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]" ng-mouseenter="enterLegend(address)" ng-mouseleave="leaveLegend()"></checkbox>
- <span class="legend-text" ng-mouseenter="enterLegend(address)" ng-mouseleave="leaveLegend()" ng-click="addressClick(address)" title="{{address}}">{{address | limitTo : 15}}{{address.length>15 ? '…' : ''}}</span>
+ <checkbox style="background-color: {{addressColors[address]}};" title="{{address}}"
+ ng-change="addressFilterChanged()" ng-model="addresses[address]"
+ ng-mouseenter="enterLegend(address)" ng-mouseleave="leaveLegend()"></checkbox>
+ <span class="legend-text" ng-mouseenter="enterLegend(address)" ng-mouseleave="leaveLegend()"
+ ng-click="addressClick(address)" title="{{address}}">{{address | limitTo :
+ 15}}{{address.length>15 ? '…' : ''}}</span>
</li>
- </ul>
- </li>
- </ul>
- <ul>
- <li><label>
- <input type='radio' ng-model="legendOptions.trafficType" value="congestion" />
- Link utilization
- </label></li>
- <li>
- <ul class="congestion" ng-show="legendOptions.trafficType === 'congestion'">
+ </ul>
+ </li>
+ </ul>
+ <ul>
+ <li><label>
+ <input type='radio' ng-model="legendOptions.trafficType" value="congestion" />
+ Link utilization
+ </label></li>
+ <li>
+ <ul class="congestion" ng-show="legendOptions.trafficType === '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">
+ <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">
<defs>
- <linearGradient xmlns="http://www.w3.org/2000/svg" id="gradienta1bEihLEHL" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">
- <stop style="stop-color: #000000;stop-opacity: 1" offset="0"/>
- <stop style="stop-color: #000000;stop-opacity: 1" offset="0.06"/>
- <stop style="stop-color: #00FF00;stop-opacity: 1" offset="0.333"/>
- <stop style="stop-color: #FFA500;stop-opacity: 1" offset="0.666"/>
- <stop style="stop-color: #FF0000;stop-opacity: 1" offset="1"/></linearGradient>
+ <linearGradient xmlns="http://www.w3.org/2000/svg" id="gradienta1bEihLEHL"
+ gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">
+ <stop style="stop-color: #999999;stop-opacity: 1" offset="0" />
+ <stop style="stop-color: #00FF00;stop-opacity: 1" offset="0.333" />
+ <stop style="stop-color: #FFA500;stop-opacity: 1" offset="0.666" />
+ <stop style="stop-color: #FF0000;stop-opacity: 1" offset="1" />
+ </linearGradient>
</defs>
<g>
<rect width="140" height="20" x="0" y="0" fill="url(#gradienta1bEihLEHL)"></rect>
@@ -295,34 +267,39 @@ td.more-info {
<text x="106" y="30" class="label">Busy</text>
</g>
</svg></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
</div>
<div uib-accordion-group class="panel-default" is-open="legend.status.legendOpen" heading="Legend">
<div id="topo_svg_legend"></div>
</div>
- <div 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="legend.status.mapOpen" heading="Background map">
<div id="topo_mapOptions">
<div class="colorPicker">
<ul>
<li>
- <label><span class='map-label'>Land</span> <input id="areaColor" name="areaColor" type="color" ng-model="mapOptions.areaColor"/></label>
+ <label><span class='map-label'>Land</span> <input id="areaColor" name="areaColor" type="color"
+ ng-model="mapOptions.areaColor" /></label>
</li>
<li>
- <label><span class='map-label'>Ocean</span> <input id="oceanColor" name="oceanColor" type="color" ng-model="mapOptions.oceanColor"/></label>
+ <label><span class='map-label'>Ocean</span> <input id="oceanColor" name="oceanColor"
+ type="color" ng-model="mapOptions.oceanColor" /></label>
</li>
</ul>
</div>
</div>
</div>
- </uib-accordion>
+ </uib-accordion>
</div>
<div class="diagram">
- <div id="topology"><!-- d3 toplogy here --></div>
- <div id="crosssection"></div><div id="crosshtml" ng-bind-html="crosshtml"></div>
+ <div id="topology">
+ <!-- d3 toplogy here -->
+ </div>
+ <div id="crosssection"></div>
+ <div id="crosshtml" ng-bind-html="crosshtml"></div>
<div id="node_context_menu" class="contextMenu">
<ul>
@@ -344,4 +321,4 @@ td.more-info {
</script>
<script type="text/ng-template" id="titleCellTemplate.html">
<div title="{{row.entity.attributeValue}}" class="ui-grid-cell-contents">{{COL_FIELD CUSTOM_FILTERS | pretty}}</div>
-</script>
+</script>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/amqp/utilities.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/amqp/utilities.js b/console/stand-alone/plugin/js/amqp/utilities.js
index 517b4e1..34f1d7d 100644
--- a/console/stand-alone/plugin/js/amqp/utilities.js
+++ b/console/stand-alone/plugin/js/amqp/utilities.js
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Red Hat Inc.
+ * Copyright 2018 Red Hat Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
*/
/* global d3 */
-var ddd = typeof window === 'undefined' ? require ('d3') : d3;
+var ddd = typeof window === 'undefined' ? require('d3') : d3;
var utils = {
isAConsole: function (properties, connectionId, nodeType, key) {
@@ -40,7 +40,7 @@ var utils = {
if (!attributes || !result)
return {};
var flat = {};
- attributes.forEach(function(attr, i) {
+ attributes.forEach(function (attr, i) {
if (result && result.length > i)
flat[attr] = result[i];
});
@@ -48,9 +48,11 @@ var utils = {
},
flattenAll: function (entity, filter) {
if (!filter)
- filter = function (e) {return e;};
+ filter = function (e) {
+ return e;
+ };
let results = [];
- for (let i=0; i<entity.results.length; i++) {
+ for (let i = 0; i < entity.results.length; i++) {
let f = filter(this.flatten(entity.attributeNames, entity.results[i]));
if (f)
results.push(f);
@@ -72,7 +74,7 @@ var utils = {
addr_text: function (addr) {
if (!addr)
return '-';
- if (addr[0] === addr[0].toLowerCase())
+ if (addr[0] === addr[0].toLowerCase())
return addr;
if (addr[0] == 'M')
return addr.substring(2);
@@ -122,7 +124,7 @@ var utils = {
countsFor: function (aAr, vAr, key) {
let counts = {};
let idx = aAr.indexOf(key);
- for (let i=0; i<vAr.length; i++) {
+ for (let i = 0; i < vAr.length; i++) {
if (!counts[vAr[i][idx]])
counts[vAr[i][idx]] = 0;
counts[vAr[i][idx]]++;
@@ -139,7 +141,7 @@ var utils = {
var parts = id.split('/');
// remove $management
- parts.pop();
+ parts.pop();
// remove the area if present
if (parts[2] === '0')
@@ -171,18 +173,21 @@ var utils = {
list.shift();
}
let rates = {};
- list.push({date: new Date(), val: Object.assign({}, obj)});
+ list.push({
+ date: new Date(),
+ val: Object.assign({}, obj)
+ });
- for (let i=0; i<fields.length; i++) {
+ for (let i = 0; i < fields.length; i++) {
let cumulative = 0;
let field = fields[i];
- for (let j=0; j<list.length-1; j++) {
- let elapsed = list[j+1].date - list[j].date;
- let diff = list[j+1].val[field] - list[j].val[field];
+ for (let j = 0; j < list.length - 1; j++) {
+ let elapsed = list[j + 1].date - list[j].date;
+ let diff = list[j + 1].val[field] - list[j].val[field];
if (elapsed > 100)
- cumulative += diff/(elapsed / 1000);
+ cumulative += diff / (elapsed / 1000);
}
- rates[field] = list.length > 1 ? cumulative / (list.length-1) : 0;
+ rates[field] = list.length > 1 ? cumulative / (list.length - 1) : 0;
}
return rates;
},
@@ -216,4 +221,6 @@ var utils = {
}
};
-export { utils };
\ No newline at end of file
+export {
+ utils
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/dlgDetailController.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/dlgDetailController.js b/console/stand-alone/plugin/js/dlgDetailController.js
index 1c9b45a..dba5d3b 100644
--- a/console/stand-alone/plugin/js/dlgDetailController.js
+++ b/console/stand-alone/plugin/js/dlgDetailController.js
@@ -33,7 +33,7 @@ export class DetailDialogController {
// count the number of characters in an array of strings
let countChars = function (ar) {
let count = 0;
- ar.forEach( a => count += a.length);
+ ar.forEach(a => count += a.length);
return count;
};
@@ -110,7 +110,7 @@ export class DetailDialogController {
};
// keep an array of column sizes
let updateSizes = function (fields, sizes, obj) {
- fields.forEach( function (key) {
+ fields.forEach(function (key) {
if (!sizes[key])
sizes[key] = utils.humanify(key).length;
sizes[key] = Math.max(sizes[key], utils.pretty(obj[key]).length);
@@ -128,8 +128,8 @@ export class DetailDialogController {
// queued function to get the .router info for an edge router
let q_getEdgeInfo = function (n, infoPerId, callback) {
let nodeId = utils.idFromName(n.container, '_edge');
- QDRService.management.topology.fetchEntities(nodeId,
- [{entity: 'router', attrs: []},
+ QDRService.management.topology.fetchEntities(nodeId,
+ [{ entity: 'router', attrs: [] },
],
function (results) {
let r = results[nodeId].router;
@@ -142,21 +142,22 @@ export class DetailDialogController {
callback(null);
});
};
- return new Promise( (function (resolve) {
+ return new Promise((function (resolve) {
let infoPerId = {};
// we are getting info for an edge router
if (d.nodeType === 'edge') {
// called for each expanded row to get further details about the edge router
$scope.detail.moreInfo = function (id) {
let nodeId = utils.idFromName(id, '_edge');
- QDRService.management.topology.fetchEntities(nodeId,
- [{entity: 'router.link', attrs: []},
- {entity: 'linkRoute', attrs: $scope.fields.linkRouteFields.cols},
- {entity: 'autoLink', attrs: $scope.fields.autoLinkFields.cols},
- {entity: 'address', attrs: []},
+ QDRService.management.topology.fetchEntities(nodeId,
+ [
+ { entity: 'router.link', attrs: [] },
+ { entity: 'linkRoute', attrs: $scope.fields.linkRouteFields.cols },
+ { entity: 'autoLink', attrs: $scope.fields.autoLinkFields.cols },
+ { entity: 'address', attrs: [] },
],
function (results) {
- $timeout( function () {
+ $timeout(function () {
// save the results (and sizes) for each entity requested
infoPerId[id].linkRouteSizes = {};
infoPerId[id].linkRoutes = utils.flattenAll(results[nodeId].linkRoute,
@@ -165,13 +166,13 @@ export class DetailDialogController {
return route;
});
infoPerId[id].autoLinkSizes = {};
- infoPerId[id].autoLinks = utils.flattenAll(results[nodeId].autoLink,
+ infoPerId[id].autoLinks = utils.flattenAll(results[nodeId].autoLink,
function (link) {
updateSizes($scope.fields.autoLinkFields.cols, infoPerId[id].autoLinkSizes, link);
return link;
});
infoPerId[id].addressSizes = {};
- infoPerId[id].addresses = utils.flattenAll(results[nodeId].address,
+ infoPerId[id].addresses = utils.flattenAll(results[nodeId].address,
function (addr) {
updateSizes($scope.fields.addressFields.cols, infoPerId[id].addressSizes, addr);
return addr;
@@ -182,7 +183,7 @@ export class DetailDialogController {
// async send up to 10 requests
let q = d3.queue(10);
- for (let n=0; n<d.normals.length; n++) {
+ for (let n = 0; n < d.normals.length; n++) {
q.defer(q_getEdgeInfo, d.normals[n], infoPerId);
if (expandedRows.has(d.normals[n].container)) {
$scope.detail.moreInfo(d.normals[n].container);
@@ -200,14 +201,14 @@ export class DetailDialogController {
});
} else {
// we are getting info for a group of clients or consoles
- $scope.detail.moreInfo = function () {};
+ $scope.detail.moreInfo = function () { };
let attrs = utils.copy($scope.fields.linkFields.cols);
attrs.unshift('connectionId');
- QDRService.management.topology.fetchEntities(d.key,
- [{entity: 'router.link', attrs: attrs}],
+ QDRService.management.topology.fetchEntities(d.key,
+ [{ entity: 'router.link', attrs: attrs }],
function (results) {
let links = results[d.key]['router.link'];
- for (let i=0; i<d.normals.length; i++) {
+ for (let i = 0; i < d.normals.length; i++) {
let n = d.normals[i];
let conn = {};
infoPerId[n.container] = conn;
@@ -231,7 +232,7 @@ export class DetailDialogController {
let count = d.normals.length;
let verb = count > 1 ? 'are' : 'is';
let preposition = d.cdir === 'in' ? 'to' : d.cdir === 'both' ? 'for' : 'from';
- let plural = count > 1 ? 's': '';
+ let plural = count > 1 ? 's' : '';
$scope.detail.template = 'clients.html';
$scope.detail.title = 'for client';
resolve({
@@ -242,16 +243,16 @@ export class DetailDialogController {
}
}));
};
-
+
let updateDetail = function () {
groupDetail.call(this)
- .then( function (det) {
- $timeout( function () {
+ .then(function (det) {
+ $timeout(function () {
$scope.detail.title = `for ${d.normals.length} ${$scope.detail.title}${d.normals.length > 1 ? 's' : ''}`;
$scope.detail.description = det.description;
- $scope.detail.infoPerId = Object.keys(det.infoPerId).map( function (id) {
+ $scope.detail.infoPerId = Object.keys(det.infoPerId).map(function (id) {
return det.infoPerId[id];
- }).sort( function (a, b) {
+ }).sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
});
@@ -266,7 +267,7 @@ DetailDialogController.$inject = ['QDRService', '$scope', '$timeout', '$uibModal
// SubTable directive
export class SubTable {
- constructor () {
+ constructor() {
this.restrict = 'E';
this.scope = {
sizes: '=sizes',
@@ -275,7 +276,7 @@ export class SubTable {
};
this.templateUrl = 'sub-table.html';
}
- link (scope) {
+ link(scope) {
scope.fieldWidth = function (val, sizes) {
if (!sizes)
return '10%';
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/topology/legend.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/legend.js b/console/stand-alone/plugin/js/topology/legend.js
new file mode 100644
index 0000000..b3908c5
--- /dev/null
+++ b/console/stand-alone/plugin/js/topology/legend.js
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* global d3 */
+
+import { Nodes } from "./nodes.js";
+import { appendCircle, appendContent, appendTitle } from "./svgUtils.js";
+// for testing, window will be undefined
+var ddd = typeof window === 'undefined' ? require('d3') : d3;
+
+const lookFor = [
+ { role: "inter-router", title: "Router", text: "", cls: '' },
+ { role: "edge", title: "Router", text: "Edge", cls: 'edge' },
+ { role: "normal", title: "Console", text: "console", cls: 'console', props: { console_identifier: "Dispatch console" } },
+ { role: "normal", title: "Sender", text: "Sender", cls: 'client.in', cdir: "in" },
+ { role: "normal", title: "Receiver", text: "Receiver", cls: 'client.out', cdir: "out" },
+ { role: "normal", title: "Sender/Receiver", text: "Sender/Receiver", cls: 'client.inout', cdir: "both" },
+ { role: "route-container", title: "Qpid broker", text: "Qpid broker", cls: 'client.route-container', props: { product: "qpid-cpp" } },
+ { role: "route-container", title: "Artemis broker", text: "Artemis broker", cls: 'route-container', props: { product: "apache-activemp-artemis" } },
+ { role: "route-container", title: "Service", text: "Service", cls: 'route-container', props: { product: " External Service" } }
+];
+
+export class Legend {
+ constructor(svg, QDRLog, urlPrefix) {
+ this.svg = svg;
+ this.log = QDRLog;
+ this.urlPrefix = urlPrefix;
+ }
+
+ // create a new legend container svg
+ init() {
+ return ddd
+ .select("#topo_svg_legend")
+ .append("svg")
+ .attr("id", "svglegend")
+ .append("svg:g")
+ .attr(
+ "transform",
+ `translate(${Nodes.maxRadius()}, ${Nodes.maxRadius()})`
+ )
+ .selectAll("g");
+ }
+
+ // create or update the legend
+ update() {
+ let lsvg;
+ if (ddd.select("#topo_svg_legend svg").empty()) {
+ lsvg = this.init();
+ } else {
+ lsvg = ddd.select("#topo_svg_legend svg g").selectAll("g");
+ }
+ // add a node to legendNodes for each node type that is currently in the svg
+ let legendNodes = new Nodes(this.log);
+ lookFor.forEach(function (node, i) {
+ if (!node.cls || !this.svg.selectAll(`circle.${node.cls}`).empty()) {
+ let lnode = legendNodes.addUsing(
+ node.title,
+ node.text,
+ node.role,
+ undefined,
+ 0, 0, i, 0,
+ false,
+ node.props ? node.props : {}
+ );
+ if (node.cdir)
+ lnode.cdir = node.cdir;
+ }
+ }, this);
+
+ // determine the y coordinate of the last existing node in the legend
+ let cury = 0;
+ lsvg.each(function (d) {
+ cury += Nodes.radius(d.nodeType) * 2 + 10;
+ });
+
+ // associate the legendNodes with lsvg
+ lsvg = lsvg.data(legendNodes.nodes, function (d) {
+ return d.uid();
+ });
+
+ // add any new nodes
+ let legendEnter = lsvg
+ .enter()
+ .append("svg:g")
+ .attr("transform", function (d) {
+ let t = `translate(0, ${cury})`;
+ cury += Nodes.radius(d.nodeType) * 2 + 10;
+ return t;
+ });
+ appendCircle(legendEnter, this.urlPrefix);
+ appendContent(legendEnter);
+ appendTitle(legendEnter);
+ legendEnter.append("svg:text")
+ .attr("x", 35)
+ .attr("y", 6)
+ .attr("class", "label")
+ .text(function (d) {
+ return d.key;
+ });
+
+ // remove any nodes that dropped out of legendNodes
+ lsvg.exit().remove();
+
+ // position the legend based on it's size
+ let svgEl = document.getElementById("svglegend");
+ if (svgEl) {
+ let bb;
+ // firefox can throw an exception on getBBox on an svg element
+ try {
+ bb = svgEl.getBBox();
+ } catch (e) {
+ bb = {
+ y: 0,
+ height: 200,
+ x: 0,
+ width: 200
+ };
+ }
+ svgEl.style.height = bb.y + bb.height + "px";
+ svgEl.style.width = bb.x + bb.width + "px";
+ }
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/topology/links.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/links.js b/console/stand-alone/plugin/js/topology/links.js
index 16b086c..1260415 100644
--- a/console/stand-alone/plugin/js/topology/links.js
+++ b/console/stand-alone/plugin/js/topology/links.js
@@ -17,7 +17,9 @@ specific language governing permissions and limitations
under the License.
*/
-import { utils } from "../amqp/utilities.js";
+import {
+ utils
+} from "../amqp/utilities.js";
class Link {
constructor(source, target, dir, cls, uid) {
@@ -29,15 +31,13 @@ class Link {
this.uid = uid;
}
markerId(end) {
- let selhigh = this.highlighted
- ? "highlighted"
- : this.selected
- ? "selected"
- : "";
+ let selhigh = this.highlighted ?
+ "highlighted" :
+ (this.selected ?
+ "selected" :
+ "");
if (selhigh === "" && (!this.left && !this.right)) selhigh = "unknown";
- return `-${selhigh}-${
- end === "end" ? this.target.radius() : this.source.radius()
- }`;
+ return `-${selhigh}-${end === "end" ? this.target.radius() : this.source.radius()}`;
}
}
@@ -46,6 +46,9 @@ export class Links {
this.links = [];
this.logger = logger;
}
+ reset() {
+ this.links.length = 0;
+ }
getLinkSource(nodesIndex) {
for (let i = 0; i < this.links.length; ++i) {
if (this.links[i].target === nodesIndex) return i;
@@ -70,7 +73,7 @@ export class Links {
}
//this.logger.debug("creating new link (" + (links.length) + ") between " + nodes[_source].name + " and " + nodes[_target].name);
if (
- this.links.some(function(l) {
+ this.links.some(function (l) {
return l.uid === uid;
})
)
@@ -88,10 +91,8 @@ export class Links {
return null;
}
- getPosition(name, nodes, source, client, localStorage, height) {
- let position = localStorage[name]
- ? JSON.parse(localStorage[name])
- : undefined;
+ getPosition(name, nodes, source, client, height, localStorage) {
+ let position = localStorage[name] ? JSON.parse(localStorage[name]) : undefined;
if (typeof position == "undefined") {
position = {
x: Math.round(
@@ -109,10 +110,12 @@ export class Links {
nodes.get(source).y + 40 + Math.cos(client / (Math.PI * 2.0))
);
}
+ position.fixed = position.fixed ? true : false;
return position;
}
- initialize(nodeInfo, nodes, unknowns, localStorage, height) {
+ initialize(nodeInfo, nodes, unknowns, height, localStorage) {
+ this.reset();
let connectionsPerContainer = {};
let nodeIds = Object.keys(nodeInfo);
// collect connection info for each router
@@ -158,7 +161,10 @@ export class Links {
// create map of type:id:dir to [containers]
for (let container in connectionsPerContainer) {
let key = getKey(connectionsPerContainer[container]);
- if (!unique[key]) unique[key] = { c: [], nodes: [] };
+ if (!unique[key]) unique[key] = {
+ c: [],
+ nodes: []
+ };
unique[key].c.push(container);
}
for (let key in unique) {
@@ -176,8 +182,8 @@ export class Links {
nodes,
container.source,
container.resultsIndex,
- localStorage,
- height
+ height,
+ localStorage
);
let node = nodes.getOrCreateNode(
@@ -242,7 +248,7 @@ export class Links {
}
}
-var getContainerIndex = function(_id, nodeInfo) {
+var getContainerIndex = function (_id, nodeInfo) {
let nodeIndex = 0;
for (let id in nodeInfo) {
if (utils.nameFromId(id) === _id) return nodeIndex;
@@ -251,7 +257,7 @@ var getContainerIndex = function(_id, nodeInfo) {
return -1;
};
-var getLinkDir = function(connection, onode) {
+var getLinkDir = function (connection, onode) {
let links = onode["router.link"];
if (!links) {
return "unknown";
@@ -261,12 +267,12 @@ var getLinkDir = function(connection, onode) {
let typeIndex = links.attributeNames.indexOf("linkType");
let connectionIdIndex = links.attributeNames.indexOf("connectionId");
let dirIndex = links.attributeNames.indexOf("linkDir");
- links.results.forEach(function(linkResult) {
+ links.results.forEach(function (linkResult) {
if (
linkResult[typeIndex] === "endpoint" &&
linkResult[connectionIdIndex] === connection.identity
)
- if (linkResult[dirIndex] === "in") ++inCount;
+ if (linkResult[dirIndex] === "in")++inCount;
else ++outCount;
});
if (inCount > 0 && outCount > 0) return "both";
@@ -274,7 +280,7 @@ var getLinkDir = function(connection, onode) {
if (outCount > 0) return "out";
return "unknown";
};
-var getKey = function(containers) {
+var getKey = function (containers) {
let parts = [];
let connection = containers[0].connection;
let d = {
@@ -291,4 +297,4 @@ var getKey = function(containers) {
parts.push(`${container.source}-${container.linksDir}`);
}
return `${connectionType}:${parts.join(":")}`;
-};
+};
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/topology/map.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/map.js b/console/stand-alone/plugin/js/topology/map.js
index 972d894..c03cfa5 100644
--- a/console/stand-alone/plugin/js/topology/map.js
+++ b/console/stand-alone/plugin/js/topology/map.js
@@ -30,8 +30,14 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
this.$scope = $scope;
this.initialized = false;
this.notify = notifyFn;
- $scope.mapOptions = angular.fromJson(localStorage[MAPOPTIONSKEY]) || {areaColor: defaultLandColor, oceanColor: defaultOceanColor};
- this.last = {translate: [0,0], scale: null};
+ $scope.mapOptions = angular.fromJson(localStorage[MAPOPTIONSKEY]) || {
+ areaColor: defaultLandColor,
+ oceanColor: defaultOceanColor
+ };
+ this.last = {
+ translate: [0, 0],
+ scale: null
+ };
}
updateLandColor(color) {
localStorage[MAPOPTIONSKEY] = JSON.stringify(this.$scope.mapOptions);
@@ -55,7 +61,7 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
}
init($scope, svg, width, height) {
- return new Promise( (function (resolve, reject) {
+ return new Promise((function (resolve, reject) {
if (this.initialized) {
resolve();
@@ -82,9 +88,9 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
// setup the projection with some defaults
this.projection = d3.geo.mercator()
- .rotate([this.rotate,0])
+ .rotate([this.rotate, 0])
.scale(1)
- .translate([width/2, height/2]);
+ .translate([width / 2, height / 2]);
// this path will hold the land coordinates once they are loaded
this.geoPath = d3.geo.path()
@@ -92,22 +98,26 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
// set up the scale extent and initial scale for the projection
var b = getMapBounds(this.projection, Math.max(maxnorth, maxsouth)),
- s = width/(b[1][0]-b[0][0]);
- this.scaleExtent = [s, 15*s];
+ s = width / (b[1][0] - b[0][0]);
+ this.scaleExtent = [s, 15 * s];
this.projection
.scale(this.scaleExtent[0]);
- this.lastProjection = angular.fromJson(localStorage[MAPPOSITIONKEY]) || {rotate: 20, scale: this.scaleExtent[0], translate: [width/2, height/2]};
+ this.lastProjection = angular.fromJson(localStorage[MAPPOSITIONKEY]) || {
+ rotate: 20,
+ scale: this.scaleExtent[0],
+ translate: [width / 2, height / 2]
+ };
this.zoom = d3.behavior.zoom()
.scaleExtent(this.scaleExtent)
.scale(this.projection.scale())
- .translate([0,0]) // not linked directly to projection
+ .translate([0, 0]) // not linked directly to projection
.on('zoom', this.zoomed.bind(this));
this.geo = svg.append('g')
.attr('class', 'geo')
- .style('opacity', this.$scope.legend.status.mapOpen ? '1': '0');
+ .style('opacity', this.$scope.legend.status.mapOpen ? '1' : '0');
this.geo.append('rect')
.attr('class', 'ocean')
@@ -115,13 +125,14 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
.attr('height', height)
.attr('fill', '#FFF');
- if (this.$scope.legend.status.mapOpen)
+ if (this.$scope.legend.status.mapOpen) {
this.svg.call(this.zoom)
.on('dblclick.zoom', null);
+ }
// async load of data file. calls resolve when this completes to let caller know
- d3.json('plugin/data/countries.json', function(error, world) {
- if (error)
+ d3.json('plugin/data/countries.json', function (error, world) {
+ if (error)
reject(error);
this.geo.append('path')
@@ -148,6 +159,8 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
setMapOpacity(opacity) {
opacity = opacity ? 1 : 0;
+ if (this.width && this.width < 768)
+ opacity = 0;
if (this.geo)
this.geo.style('opacity', opacity);
}
@@ -180,11 +193,11 @@ 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.legend.status.mapOpen) {
let scale = d3.event.scale,
t = d3.event.translate,
- dx = t[0]-this.last.translate[0],
- dy = t[1]-this.last.translate[1],
+ dx = t[0] - this.last.translate[0],
+ dy = t[1] - this.last.translate[1],
yaw = this.projection.rotate()[0],
tp = this.projection.translate();
// zoomed
@@ -209,21 +222,21 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
dy = my - this.projection([0, lonlat[1]])[1];
// rotate the map so that the longitude under the mouse is where it was before the scale
- this.projection.rotate([yaw+dx ,0, 0]);
+ this.projection.rotate([yaw + dx, 0, 0]);
// translate the map so that the lattitude under the mouse is where it was before the scale
- this.projection.translate([tp[0], tp[1]+dy]);
+ this.projection.translate([tp[0], tp[1] + dy]);
} else {
// rotate instead of translate in the x direction
- this.projection.rotate([yaw+360.0*dx/this.width*this.scaleExtent[0]/scale, 0, 0]);
+ this.projection.rotate([yaw + 360.0 * dx / this.width * this.scaleExtent[0] / scale, 0, 0]);
// translate only in the y direction. don't translate beyond the max lattitude north or south
var bnorth = getMapBounds(this.projection, maxnorth),
bsouth = getMapBounds(this.projection, maxsouth);
- if (bnorth[0][1] + dy > 0)
+ if (bnorth[0][1] + dy > 0)
dy = -bnorth[0][1];
- else if (bsouth[1][1] + dy < this.height)
- dy = this.height-bsouth[1][1];
- this.projection.translate([tp[0],tp[1]+dy]);
+ else if (bsouth[1][1] + dy < this.height)
+ dy = this.height - bsouth[1][1];
+ this.projection.translate([tp[0], tp[1] + dy]);
}
this.last.scale = scale;
this.last.translate = t;
@@ -247,8 +260,8 @@ export class BackgroundMap { // eslint-disable-line no-unused-vars
// find the top left and bottom right of current projection
function getMapBounds(projection, maxlat) {
var yaw = projection.rotate()[0],
- xymax = projection([-yaw+180-1e-6,-maxlat]),
- xymin = projection([-yaw-180+1e-6, maxlat]);
-
- return [xymin,xymax];
-}
+ xymax = projection([-yaw + 180 - 1e-6, -maxlat]),
+ xymin = projection([-yaw - 180 + 1e-6, maxlat]);
+
+ return [xymin, xymax];
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/81e58b46/console/stand-alone/plugin/js/topology/nodes.js
----------------------------------------------------------------------
diff --git a/console/stand-alone/plugin/js/topology/nodes.js b/console/stand-alone/plugin/js/topology/nodes.js
index 50c9a37..26ac9bc 100644
--- a/console/stand-alone/plugin/js/topology/nodes.js
+++ b/console/stand-alone/plugin/js/topology/nodes.js
@@ -17,7 +17,9 @@ specific language governing permissions and limitations
under the License.
*/
-import { utils } from "../amqp/utilities.js";
+import {
+ utils
+} from "../amqp/utilities.js";
/* global d3 Promise */
export class Node {
@@ -43,7 +45,7 @@ export class Node {
this.y = y;
this.id = nodeIndex;
this.resultIndex = resultIndex;
- this.fixed = !!+fixed;
+ this.fixed = fixed ? true : false;
this.cls = "";
this.container = connectionContainer;
this.isConsole = utils.isConsole(this);
@@ -71,11 +73,11 @@ export class Node {
}
toolTip(topology) {
return new Promise(
- function(resolve) {
+ function (resolve) {
if (this.nodeType === "normal" || this.nodeType === "edge") {
resolve(this.clientTooltip());
} else
- this.routerTooltip(topology).then(function(toolTip) {
+ this.routerTooltip(topology).then(function (toolTip) {
resolve(toolTip);
});
}.bind(this)
@@ -99,19 +101,23 @@ export class Node {
routerTooltip(topology) {
return new Promise(
- function(resolve) {
+ function (resolve) {
topology.ensureEntities(
this.key,
- [
- { entity: "listener", attrs: ["role", "port", "http"] },
- { entity: "router", attrs: ["name", "version", "hostName"] }
+ [{
+ entity: "listener",
+ attrs: ["role", "port", "http"]
+ },
+ {
+ entity: "router",
+ attrs: ["name", "version", "hostName"]
+ }
],
- function(foo, nodes) {
+ function (foo, nodes) {
// update all the router title text
let node = nodes[this.key];
const err = `<table class="popupTable"><tr><td>Error</td><td>Unable to get router info for ${
- this.key
- }</td></tr></table>`;
+ this.key}</td></tr></table>`;
if (!node) {
resolve(err);
return;
@@ -154,32 +160,43 @@ export class Node {
return nodeProperties[this.nodeType].radius;
}
uid() {
- if (!this.uuid) this.uuid = this.container;
+ if (!this.uuid)
+ this.uuid = `${this.container}`;
return this.normals ? `${this.uuid}-${this.normals.length}` : this.uuid;
}
setFixed(fixed) {
- if (!fixed) this.lat = this.lon = null;
- this.fixed = fixed;
+ if (!fixed & 1)
+ this.lat = this.lon = null;
+ this.fixed = fixed & 1 ? true : false;
}
}
const nodeProperties = {
// router types
"inter-router": {
radius: 28,
- refX: { end: 32, start: -19 },
+ refX: {
+ end: 32,
+ start: -19
+ },
linkDistance: [150, 70],
charge: [-1800, -900]
},
edge: {
radius: 20,
- refX: { end: 24, start: -12 },
+ refX: {
+ end: 24,
+ start: -12
+ },
linkDistance: [110, 55],
charge: [-1350, -900]
},
// generated nodes from connections. key is from connection.role
normal: {
radius: 15,
- refX: { end: 20, start: -7 },
+ refX: {
+ end: 20,
+ start: -7
+ },
linkDistance: [75, 40],
charge: [-900, -900]
}
@@ -240,7 +257,13 @@ export class Nodes {
gravity(d, nodeCount) {
return Nodes.forceScale(nodeCount, [0.0001, 0.1]);
}
-
+ setFixed(d, fixed) {
+ let n = this.find(d.container, d.properties, d.name);
+ if (n) {
+ n.fixed = fixed;
+ }
+ d.setFixed(fixed);
+ }
getLength() {
return this.nodes.length;
}
@@ -253,14 +276,6 @@ export class Nodes {
);
return undefined;
}
- setNodesFixed(name, b) {
- this.nodes.some(function(n) {
- if (n.name === name) {
- n.fixed(b);
- return true;
- }
- });
- }
nodeFor(name) {
for (let i = 0; i < this.nodes.length; ++i) {
if (this.nodes[i].name == name) return this.nodes[i];
@@ -268,7 +283,7 @@ export class Nodes {
return null;
}
nodeExists(connectionContainer) {
- return this.nodes.findIndex(function(node) {
+ return this.nodes.findIndex(function (node) {
return node.container === connectionContainer;
});
}
@@ -277,9 +292,12 @@ export class Nodes {
for (let i = 0; i < this.nodes.length; ++i) {
if (this.nodes[i].normals) {
if (
- this.nodes[i].normals.some(function(normal, j) {
+ this.nodes[i].normals.some(function (normal, j) {
if (normal.container === connectionContainer && i !== j) {
- normalInfo = { nodesIndex: i, normalsIndex: j };
+ normalInfo = {
+ nodesIndex: i,
+ normalsIndex: j
+ };
return true;
}
return false;
@@ -295,11 +313,11 @@ export class Nodes {
if (Object.prototype.toString.call(nodes) !== "[object Array]") {
nodes = [nodes];
}
- this.nodes.forEach(function(d) {
+ this.nodes.forEach(function (d) {
localStorage[d.name] = JSON.stringify({
x: Math.round(d.x),
y: Math.round(d.y),
- fixed: d.fixed & 1 ? 1 : 0
+ fixed: d.fixed
});
});
}
@@ -413,24 +431,23 @@ export class Nodes {
fixed,
properties
);
- this.nodes.push(obj);
- return obj;
+ return this.add(obj);
}
clearHighlighted() {
for (let i = 0; i < this.nodes.length; ++i) {
this.nodes[i].highlighted = false;
}
}
- initialize(nodeInfo, localStorage, width, height) {
+
+ initialize(nodeInfo, width, height, localStorage) {
+ this.nodes.length = 0;
let nodeCount = Object.keys(nodeInfo).length;
let yInit = 50;
let animate = false;
for (let id in nodeInfo) {
let name = utils.nameFromId(id);
// if we have any new nodes, animate the force graph to position them
- let position = localStorage[name]
- ? JSON.parse(localStorage[name])
- : undefined;
+ let position = localStorage[name] ? JSON.parse(localStorage[name]) : undefined;
if (!position) {
animate = true;
position = {
@@ -439,7 +456,7 @@ export class Nodes {
),
y: Math.round(
height / 2 +
- (Math.sin(this.nodes.length / (Math.PI * 2.0)) * height) / 4
+ (Math.sin(this.nodes.length / (Math.PI * 2.0)) * height) / 4
),
fixed: false
};
@@ -448,6 +465,7 @@ export class Nodes {
position.y = 200 - yInit;
yInit *= -1;
}
+ position.fixed = position.fixed ? true : false;
let parts = id.split("/");
this.addUsing(
id,
@@ -458,10 +476,9 @@ export class Nodes {
position.y,
name,
undefined,
- position.fixed,
- {}
+ position.fixed, {}
);
}
return animate;
}
-}
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org