CSS Added fill-mode for nodes
Amends based on Simons Comments ESLinted The whole project Topo2Link - Added Labels for PortA and PortB on mouseover Updated breadcrumbs Topo2.js - commented out a line causing error on panning Topo2 Navigation between regions Change-Id: I9cc0f4499ab68a14e246bba192f6528258471b35
Showing
21 changed files
with
311 additions
and
503 deletions
| 1 | +module.exports = { | ||
| 2 | + "extends": "google", | ||
| 3 | + "installedESLint": true, | ||
| 4 | + "globals": { | ||
| 5 | + "angular": true, | ||
| 6 | + "d3": true | ||
| 7 | + }, | ||
| 8 | + "rules": { | ||
| 9 | + "brace-style": 0, | ||
| 10 | + "no-void": 0, | ||
| 11 | + "require-jsdoc": 0, | ||
| 12 | + "padded-blocks": 0, | ||
| 13 | + "quote-props": 0, | ||
| 14 | + "no-warning-comments": 0, | ||
| 15 | + "object-curly-spacing": ["error", "always"], | ||
| 16 | + "indent": ["error", 4], | ||
| 17 | + "one-var": 0, | ||
| 18 | + "space-before-function-paren": ["error", { "anonymous": "always", "named": "never" }] | ||
| 19 | + } | ||
| 20 | +}; |
| 1 | +{ | ||
| 2 | + "name": "topo2", | ||
| 3 | + "version": "1.0.0", | ||
| 4 | + "description": "ONOS Topo2", | ||
| 5 | + "main": "topo2.js", | ||
| 6 | + "scripts": { | ||
| 7 | + "test": "echo \"Error: no test specified\" && exit 1", | ||
| 8 | + "lint": "./node_modules/.bin/eslint ./**/*.js" | ||
| 9 | + }, | ||
| 10 | + "author": "", | ||
| 11 | + "license": "ISC", | ||
| 12 | + "devDependencies": { | ||
| 13 | + "eslint": "^3.4.0", | ||
| 14 | + "eslint-config-google": "^0.6.0" | ||
| 15 | + } | ||
| 16 | +} |
| ... | @@ -66,3 +66,10 @@ | ... | @@ -66,3 +66,10 @@ |
| 66 | .floatpanel { | 66 | .floatpanel { |
| 67 | top: 104px; | 67 | top: 104px; |
| 68 | } | 68 | } |
| 69 | + | ||
| 70 | + | ||
| 71 | +/* -- Base Device Styles -- */ | ||
| 72 | +#ov-topo2 svg .node { | ||
| 73 | + cursor: pointer; | ||
| 74 | + fill-rule: evenodd; | ||
| 75 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -24,18 +24,14 @@ | ... | @@ -24,18 +24,14 @@ |
| 24 | 'use strict'; | 24 | 'use strict'; |
| 25 | 25 | ||
| 26 | // references to injected services | 26 | // references to injected services |
| 27 | - var $scope, $log, $loc, | 27 | + var $scope, $log, fs, mast, ks, zs, |
| 28 | - fs, mast, ks, zs, | 28 | + gs, sus, ps, t2es, t2fs, t2is, t2bcs; |
| 29 | - gs, ms, sus, flash, | ||
| 30 | - wss, ps, th, | ||
| 31 | - t2es, t2fs, t2is, t2bcs; | ||
| 32 | 29 | ||
| 33 | // DOM elements | 30 | // DOM elements |
| 34 | - var ovtopo2, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; | 31 | + var ovtopo2, svg, defs, zoomLayer, forceG; |
| 35 | 32 | ||
| 36 | // Internal state | 33 | // Internal state |
| 37 | - var zoomer, actionMap; | 34 | + var zoomer; |
| 38 | - | ||
| 39 | 35 | ||
| 40 | // --- Glyphs, Icons, and the like ----------------------------------- | 36 | // --- Glyphs, Icons, and the like ----------------------------------- |
| 41 | 37 | ||
| ... | @@ -66,10 +62,10 @@ | ... | @@ -66,10 +62,10 @@ |
| 66 | var sc = zoomer.scale(), | 62 | var sc = zoomer.scale(), |
| 67 | tr = zoomer.translate(); | 63 | tr = zoomer.translate(); |
| 68 | 64 | ||
| 69 | - ps.setPrefs('topo_zoom', {tx:tr[0], ty:tr[1], sc:sc}); | 65 | + ps.setPrefs('topo_zoom', { tx: tr[0], ty: tr[1], sc: sc }); |
| 70 | 66 | ||
| 71 | // keep the map lines constant width while zooming | 67 | // keep the map lines constant width while zooming |
| 72 | - mapG.style('stroke-width', (2.0 / sc) + 'px'); | 68 | + // mapG.style('stroke-width', (2.0 / sc) + 'px'); |
| 73 | } | 69 | } |
| 74 | 70 | ||
| 75 | function setUpZoom() { | 71 | function setUpZoom() { |
| ... | @@ -82,7 +78,6 @@ | ... | @@ -82,7 +78,6 @@ |
| 82 | }); | 78 | }); |
| 83 | } | 79 | } |
| 84 | 80 | ||
| 85 | - | ||
| 86 | // === Controller Definition ----------------------------------------- | 81 | // === Controller Definition ----------------------------------------- |
| 87 | 82 | ||
| 88 | angular.module('ovTopo2', ['onosUtil', 'onosSvg', 'onosRemote']) | 83 | angular.module('ovTopo2', ['onosUtil', 'onosSvg', 'onosRemote']) |
| ... | @@ -101,7 +96,6 @@ | ... | @@ -101,7 +96,6 @@ |
| 101 | _t2es_, _t2fs_, _t2is_, _t2bcs_) { | 96 | _t2es_, _t2fs_, _t2is_, _t2bcs_) { |
| 102 | 97 | ||
| 103 | var params = _$loc_.search(), | 98 | var params = _$loc_.search(), |
| 104 | - projection, | ||
| 105 | dim, | 99 | dim, |
| 106 | wh, | 100 | wh, |
| 107 | uplink = { | 101 | uplink = { |
| ... | @@ -109,14 +103,13 @@ | ... | @@ -109,14 +103,13 @@ |
| 109 | // showNoDevs: showNoDevs, | 103 | // showNoDevs: showNoDevs, |
| 110 | // projection: function () { return projection; }, | 104 | // projection: function () { return projection; }, |
| 111 | zoomLayer: function () { return zoomLayer; }, | 105 | zoomLayer: function () { return zoomLayer; }, |
| 112 | - zoomer: function () { return zoomer; }, | 106 | + zoomer: function () { return zoomer; } |
| 113 | // opacifyMap: opacifyMap, | 107 | // opacifyMap: opacifyMap, |
| 114 | // topoStartDone: topoStartDone | 108 | // topoStartDone: topoStartDone |
| 115 | }; | 109 | }; |
| 116 | 110 | ||
| 117 | $scope = _$scope_; | 111 | $scope = _$scope_; |
| 118 | $log = _$log_; | 112 | $log = _$log_; |
| 119 | - $loc = _$loc_; | ||
| 120 | 113 | ||
| 121 | fs = _fs_; | 114 | fs = _fs_; |
| 122 | mast = _mast_; | 115 | mast = _mast_; |
| ... | @@ -124,13 +117,9 @@ | ... | @@ -124,13 +117,9 @@ |
| 124 | zs = _zs_; | 117 | zs = _zs_; |
| 125 | 118 | ||
| 126 | gs = _gs_; | 119 | gs = _gs_; |
| 127 | - ms = _ms_; | ||
| 128 | sus = _sus_; | 120 | sus = _sus_; |
| 129 | - flash = _flash_; | ||
| 130 | 121 | ||
| 131 | - wss = _wss_; | ||
| 132 | ps = _ps_; | 122 | ps = _ps_; |
| 133 | - th = _th_; | ||
| 134 | 123 | ||
| 135 | t2es = _t2es_; | 124 | t2es = _t2es_; |
| 136 | t2fs = _t2fs_; | 125 | t2fs = _t2fs_; |
| ... | @@ -140,7 +129,10 @@ | ... | @@ -140,7 +129,10 @@ |
| 140 | // capture selected intent parameters (if they are set in the | 129 | // capture selected intent parameters (if they are set in the |
| 141 | // query string) so that the traffic overlay can highlight | 130 | // query string) so that the traffic overlay can highlight |
| 142 | // the path for that intent | 131 | // the path for that intent |
| 143 | - if (params.intentKey && params.intentAppId && params.intentAppName) { | 132 | + if (params.intentKey && |
| 133 | + params.intentAppId && | ||
| 134 | + params.intentAppName) { | ||
| 135 | + | ||
| 144 | $scope.intentData = { | 136 | $scope.intentData = { |
| 145 | key: params.intentKey, | 137 | key: params.intentKey, |
| 146 | appId: params.intentAppId, | 138 | appId: params.intentAppId, |
| ... | @@ -169,7 +161,6 @@ | ... | @@ -169,7 +161,6 @@ |
| 169 | svg.attr(wh); | 161 | svg.attr(wh); |
| 170 | dim = [wh.width, wh.height]; | 162 | dim = [wh.width, wh.height]; |
| 171 | 163 | ||
| 172 | - | ||
| 173 | // set up our keyboard shortcut bindings | 164 | // set up our keyboard shortcut bindings |
| 174 | setUpKeys(); | 165 | setUpKeys(); |
| 175 | setUpZoom(); | 166 | setUpZoom(); |
| ... | @@ -183,7 +174,6 @@ | ... | @@ -183,7 +174,6 @@ |
| 183 | t2fs.init(svg, forceG, uplink, dim); | 174 | t2fs.init(svg, forceG, uplink, dim); |
| 184 | t2bcs.init(); | 175 | t2bcs.init(); |
| 185 | 176 | ||
| 186 | - | ||
| 187 | // =-=-=-=-=-=-=-=- | 177 | // =-=-=-=-=-=-=-=- |
| 188 | // TODO: in future, we will load background map data | 178 | // TODO: in future, we will load background map data |
| 189 | // asynchronously (hence the promise) and then chain off | 179 | // asynchronously (hence the promise) and then chain off |
| ... | @@ -191,12 +181,8 @@ | ... | @@ -191,12 +181,8 @@ |
| 191 | // For now, we'll send the event inline... | 181 | // For now, we'll send the event inline... |
| 192 | t2es.start(); | 182 | t2es.start(); |
| 193 | 183 | ||
| 194 | - | ||
| 195 | - | ||
| 196 | t2is.initInst({ showMastership: t2fs.showMastership }); | 184 | t2is.initInst({ showMastership: t2fs.showMastership }); |
| 197 | 185 | ||
| 198 | - | ||
| 199 | - | ||
| 200 | // === ORIGINAL CODE === | 186 | // === ORIGINAL CODE === |
| 201 | 187 | ||
| 202 | // setUpKeys(); | 188 | // setUpKeys(); |
| ... | @@ -242,4 +228,4 @@ | ... | @@ -242,4 +228,4 @@ |
| 242 | 228 | ||
| 243 | $log.log('OvTopo2Ctrl has been created'); | 229 | $log.log('OvTopo2Ctrl has been created'); |
| 244 | }]); | 230 | }]); |
| 245 | -}()); | 231 | +})(); | ... | ... |
| ... | @@ -19,16 +19,18 @@ | ... | @@ -19,16 +19,18 @@ |
| 19 | Module that renders the breadcrumbs for regions | 19 | Module that renders the breadcrumbs for regions |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | - (function () { | 22 | +(function () { |
| 23 | + | ||
| 23 | 'use strict'; | 24 | 'use strict'; |
| 24 | 25 | ||
| 25 | var $log, wss; | 26 | var $log, wss; |
| 26 | 27 | ||
| 28 | + // Internal | ||
| 27 | var breadcrumbContainer, | 29 | var breadcrumbContainer, |
| 28 | breadcrumbs; | 30 | breadcrumbs; |
| 29 | 31 | ||
| 30 | function init() { | 32 | function init() { |
| 31 | - | 33 | + $log.debug("Topo2BreadcrumbService Initiated"); |
| 32 | breadcrumbs = []; | 34 | breadcrumbs = []; |
| 33 | breadcrumbContainer = d3.select('#breadcrumbs'); | 35 | breadcrumbContainer = d3.select('#breadcrumbs'); |
| 34 | render(); | 36 | render(); |
| ... | @@ -36,13 +38,8 @@ | ... | @@ -36,13 +38,8 @@ |
| 36 | 38 | ||
| 37 | function addBreadcrumb(crumbs) { | 39 | function addBreadcrumb(crumbs) { |
| 38 | 40 | ||
| 39 | - // If `crumbs` is an array, merge with breadcrumbs; | 41 | + breadcrumbContainer.selectAll('.breadcrumb').remove(); |
| 40 | - if (crumbs.length) { | 42 | + breadcrumbs = crumbs.reverse(); |
| 41 | - breadcrumbs = breadcrumbs.concat(crumbs); | ||
| 42 | - } else { | ||
| 43 | - breadcrumbs.push(crumbs); | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | render(); | 43 | render(); |
| 47 | } | 44 | } |
| 48 | 45 | ... | ... |
| ... | @@ -26,12 +26,14 @@ | ... | @@ -26,12 +26,14 @@ |
| 26 | 26 | ||
| 27 | function Collection(models, options) { | 27 | function Collection(models, options) { |
| 28 | 28 | ||
| 29 | - options || (options = {}); | 29 | + var opts = options || (options = {}); |
| 30 | 30 | ||
| 31 | this.models = []; | 31 | this.models = []; |
| 32 | this._reset(); | 32 | this._reset(); |
| 33 | 33 | ||
| 34 | - if (options.comparator !== void 0) this.comparator = options.comparator; | 34 | + if (opts.comparator) { |
| 35 | + this.comparator = opts.comparator; | ||
| 36 | + } | ||
| 35 | 37 | ||
| 36 | if (models) { | 38 | if (models) { |
| 37 | this.add(models); | 39 | this.add(models); |
| ... | @@ -48,7 +50,8 @@ | ... | @@ -48,7 +50,8 @@ |
| 48 | 50 | ||
| 49 | data.forEach(function (d) { | 51 | data.forEach(function (d) { |
| 50 | 52 | ||
| 51 | - var model = new _this.model(d); | 53 | + var CollectionModel = _this.model; |
| 54 | + var model = new CollectionModel(d); | ||
| 52 | model.collection = _this; | 55 | model.collection = _this; |
| 53 | 56 | ||
| 54 | _this.models.push(model); | 57 | _this.models.push(model); |
| ... | @@ -57,9 +60,11 @@ | ... | @@ -57,9 +60,11 @@ |
| 57 | } | 60 | } |
| 58 | }, | 61 | }, |
| 59 | get: function (id) { | 62 | get: function (id) { |
| 63 | + | ||
| 60 | if (!id) { | 64 | if (!id) { |
| 61 | - return void 0; | 65 | + return null; |
| 62 | } | 66 | } |
| 67 | + | ||
| 63 | return this._byId[id] || null; | 68 | return this._byId[id] || null; |
| 64 | }, | 69 | }, |
| 65 | sort: function () { | 70 | sort: function () { |
| ... | @@ -76,9 +81,11 @@ | ... | @@ -76,9 +81,11 @@ |
| 76 | this._byId = []; | 81 | this._byId = []; |
| 77 | this.models = []; | 82 | this.models = []; |
| 78 | }, | 83 | }, |
| 79 | - toJSON: function(options) { | 84 | + toJSON: function (options) { |
| 80 | - return this.models.map(function(model) { return model.toJSON(options); }); | 85 | + return this.models.map(function (model) { |
| 81 | - }, | 86 | + return model.toJSON(options); |
| 87 | + }); | ||
| 88 | + } | ||
| 82 | }; | 89 | }; |
| 83 | 90 | ||
| 84 | Collection.extend = function (protoProps, staticProps) { | 91 | Collection.extend = function (protoProps, staticProps) { | ... | ... |
| ... | @@ -22,99 +22,21 @@ Module that contains the d3.force.layout logic | ... | @@ -22,99 +22,21 @@ Module that contains the d3.force.layout logic |
| 22 | (function () { | 22 | (function () { |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | - var sus, is, ts; | 25 | + var is; |
| 26 | - | ||
| 27 | - // internal state | ||
| 28 | - var deviceLabelIndex = 0, | ||
| 29 | - hostLabelIndex = 0; | ||
| 30 | - | ||
| 31 | - // configuration | ||
| 32 | - var devIconDim = 36, | ||
| 33 | - labelPad = 4, | ||
| 34 | - hostRadius = 14, | ||
| 35 | - badgeConfig = { | ||
| 36 | - radius: 12, | ||
| 37 | - yoff: 5, | ||
| 38 | - gdelta: 10 | ||
| 39 | - }, | ||
| 40 | - halfDevIcon = devIconDim / 2, | ||
| 41 | - devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon }, | ||
| 42 | - hostBadgeOff = { dx: -hostRadius, dy: -hostRadius }, | ||
| 43 | - status = { | ||
| 44 | - i: 'badgeInfo', | ||
| 45 | - w: 'badgeWarn', | ||
| 46 | - e: 'badgeError' | ||
| 47 | - }; | ||
| 48 | - | ||
| 49 | - // note: these are the device icon colors without affinity (no master) | ||
| 50 | - var dColTheme = { | ||
| 51 | - light: { | ||
| 52 | - online: '#444444', | ||
| 53 | - offline: '#cccccc' | ||
| 54 | - }, | ||
| 55 | - dark: { | ||
| 56 | - // TODO: theme | ||
| 57 | - online: '#444444', | ||
| 58 | - offline: '#cccccc' | ||
| 59 | - } | ||
| 60 | - }; | ||
| 61 | - | ||
| 62 | - function init() {} | ||
| 63 | - | ||
| 64 | - function renderBadge(node, bdg, boff) { | ||
| 65 | - var bsel, | ||
| 66 | - bcr = badgeConfig.radius, | ||
| 67 | - bcgd = badgeConfig.gdelta; | ||
| 68 | - | ||
| 69 | - node.select('g.badge').remove(); | ||
| 70 | - | ||
| 71 | - bsel = node.append('g') | ||
| 72 | - .classed('badge', true) | ||
| 73 | - .classed(badgeStatus(bdg), true) | ||
| 74 | - .attr('transform', sus.translate(boff.dx, boff.dy)); | ||
| 75 | - | ||
| 76 | - bsel.append('circle') | ||
| 77 | - .attr('r', bcr); | ||
| 78 | - | ||
| 79 | - if (bdg.txt) { | ||
| 80 | - bsel.append('text') | ||
| 81 | - .attr('dy', badgeConfig.yoff) | ||
| 82 | - .attr('text-anchor', 'middle') | ||
| 83 | - .text(bdg.txt); | ||
| 84 | - } else if (bdg.gid) { | ||
| 85 | - bsel.append('use') | ||
| 86 | - .attr({ | ||
| 87 | - width: bcgd * 2, | ||
| 88 | - height: bcgd * 2, | ||
| 89 | - transform: sus.translate(-bcgd, -bcgd), | ||
| 90 | - 'xlink:href': '#' + bdg.gid | ||
| 91 | - }); | ||
| 92 | - } | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - // TODO: Move to Device Model when working on the Exit Devices | ||
| 96 | - function updateDeviceRendering(d) { | ||
| 97 | - var node = d.el, | ||
| 98 | - bdg = d.badge, | ||
| 99 | - label = trimLabel(deviceLabel(d)), | ||
| 100 | - labelWidth; | ||
| 101 | 26 | ||
| 102 | - node.select('text').text(label); | 27 | + // Configuration |
| 103 | - labelWidth = label ? computeLabelWidth(node) : 0; | 28 | + var hostRadius = 14; |
| 104 | 29 | ||
| 105 | - node.select('rect') | 30 | + function init() {} |
| 106 | - .transition() | ||
| 107 | - .attr(iconBox(devIconDim, labelWidth)); | ||
| 108 | - | ||
| 109 | - if (bdg) { | ||
| 110 | - renderBadge(node, bdg, devBadgeOff); | ||
| 111 | - } | ||
| 112 | - } | ||
| 113 | 31 | ||
| 114 | function nodeEnter(node) { | 32 | function nodeEnter(node) { |
| 115 | node.onEnter(this, node); | 33 | node.onEnter(this, node); |
| 116 | } | 34 | } |
| 117 | 35 | ||
| 36 | + function nodeExit(node) { | ||
| 37 | + node.onExit(this, node); | ||
| 38 | + } | ||
| 39 | + | ||
| 118 | function hostLabel(d) { | 40 | function hostLabel(d) { |
| 119 | return d.get('id'); | 41 | return d.get('id'); |
| 120 | 42 | ||
| ... | @@ -144,19 +66,18 @@ Module that contains the d3.force.layout logic | ... | @@ -144,19 +66,18 @@ Module that contains the d3.force.layout logic |
| 144 | 66 | ||
| 145 | angular.module('ovTopo2') | 67 | angular.module('ovTopo2') |
| 146 | .factory('Topo2D3Service', | 68 | .factory('Topo2D3Service', |
| 147 | - ['SvgUtilService', 'IconService', 'ThemeService', | 69 | + ['IconService', |
| 148 | 70 | ||
| 149 | - function (_sus_, _is_, _ts_) { | 71 | + function (_is_) { |
| 150 | - sus = _sus_; | ||
| 151 | is = _is_; | 72 | is = _is_; |
| 152 | - ts = _ts_; | ||
| 153 | 73 | ||
| 154 | return { | 74 | return { |
| 155 | init: init, | 75 | init: init, |
| 156 | nodeEnter: nodeEnter, | 76 | nodeEnter: nodeEnter, |
| 77 | + nodeExit: nodeExit, | ||
| 157 | hostEnter: hostEnter, | 78 | hostEnter: hostEnter, |
| 158 | linkEntering: linkEntering | 79 | linkEntering: linkEntering |
| 159 | - } | 80 | + }; |
| 160 | } | 81 | } |
| 161 | ] | 82 | ] |
| 162 | ); | 83 | ); | ... | ... |
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | (function () { | 22 | (function () { |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | - var Collection, Model, is, sus, ts, t2vs; | 25 | + var Collection, Model, is, sus, ts; |
| 26 | 26 | ||
| 27 | var remappedDeviceTypes = { | 27 | var remappedDeviceTypes = { |
| 28 | virtual: 'cord' | 28 | virtual: 'cord' |
| ... | @@ -30,30 +30,17 @@ | ... | @@ -30,30 +30,17 @@ |
| 30 | 30 | ||
| 31 | // configuration | 31 | // configuration |
| 32 | var devIconDim = 36, | 32 | var devIconDim = 36, |
| 33 | - labelPad = 10, | 33 | + halfDevIcon = devIconDim / 2; |
| 34 | - hostRadius = 14, | ||
| 35 | - badgeConfig = { | ||
| 36 | - radius: 12, | ||
| 37 | - yoff: 5, | ||
| 38 | - gdelta: 10 | ||
| 39 | - }, | ||
| 40 | - halfDevIcon = devIconDim / 2, | ||
| 41 | - devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon }, | ||
| 42 | - hostBadgeOff = { dx: -hostRadius, dy: -hostRadius }, | ||
| 43 | - status = { | ||
| 44 | - i: 'badgeInfo', | ||
| 45 | - w: 'badgeWarn', | ||
| 46 | - e: 'badgeError' | ||
| 47 | - }, | ||
| 48 | - deviceLabelIndex = 0; | ||
| 49 | 34 | ||
| 50 | function createDeviceCollection(data, region) { | 35 | function createDeviceCollection(data, region) { |
| 51 | 36 | ||
| 52 | var DeviceCollection = Collection.extend({ | 37 | var DeviceCollection = Collection.extend({ |
| 53 | model: Model, | 38 | model: Model, |
| 54 | - comparator: function(a, b) { | 39 | + comparator: function (a, b) { |
| 55 | - var order = region.get('layerOrder'); | 40 | + var order = region.get('layerOrder'), |
| 56 | - return order.indexOf(a.get('layer')) - order.indexOf(b.get('layer')); | 41 | + aLayer = a.get('layer'), |
| 42 | + bLayer = b.get('layer'); | ||
| 43 | + return order.indexOf(aLayer - order.indexOf(bLayer)); | ||
| 57 | } | 44 | } |
| 58 | }); | 45 | }); |
| 59 | 46 | ||
| ... | @@ -80,7 +67,7 @@ | ... | @@ -80,7 +67,7 @@ |
| 80 | y: -dim / 2, | 67 | y: -dim / 2, |
| 81 | width: dim + labelWidth, | 68 | width: dim + labelWidth, |
| 82 | height: dim | 69 | height: dim |
| 83 | - } | 70 | + }; |
| 84 | } | 71 | } |
| 85 | 72 | ||
| 86 | // note: these are the device icon colors without affinity (no master) | 73 | // note: these are the device icon colors without affinity (no master) |
| ... | @@ -100,8 +87,9 @@ | ... | @@ -100,8 +87,9 @@ |
| 100 | var o = this.node.online, | 87 | var o = this.node.online, |
| 101 | id = this.node.master, // TODO: This should be from node.master | 88 | id = this.node.master, // TODO: This should be from node.master |
| 102 | otag = o ? 'online' : 'offline'; | 89 | otag = o ? 'online' : 'offline'; |
| 103 | - return o ? sus.cat7().getColor(id, 0, ts.theme()) | 90 | + |
| 104 | - : dColTheme[ts.theme()][otag]; | 91 | + return o ? sus.cat7().getColor(id, 0, ts.theme()) : |
| 92 | + dColTheme[ts.theme()][otag]; | ||
| 105 | } | 93 | } |
| 106 | 94 | ||
| 107 | function setDeviceColor() { | 95 | function setDeviceColor() { |
| ... | @@ -111,18 +99,17 @@ | ... | @@ -111,18 +99,17 @@ |
| 111 | 99 | ||
| 112 | angular.module('ovTopo2') | 100 | angular.module('ovTopo2') |
| 113 | .factory('Topo2DeviceService', | 101 | .factory('Topo2DeviceService', |
| 114 | - ['Topo2Collection', 'Topo2NodeModel', 'IconService', 'SvgUtilService', | 102 | + ['Topo2Collection', 'Topo2NodeModel', 'IconService', |
| 115 | - 'ThemeService', 'Topo2ViewService', | 103 | + 'SvgUtilService', 'ThemeService', |
| 116 | 104 | ||
| 117 | - function (_Collection_, _NodeModel_, _is_, _sus_, _ts_, classnames, _t2vs_) { | 105 | + function (_c_, _nm_, _is_, _sus_, _ts_, classnames) { |
| 118 | 106 | ||
| 119 | - t2vs = _t2vs_; | ||
| 120 | is = _is_; | 107 | is = _is_; |
| 121 | sus = _sus_; | 108 | sus = _sus_; |
| 122 | ts = _ts_; | 109 | ts = _ts_; |
| 123 | - Collection = _Collection_; | 110 | + Collection = _c_; |
| 124 | 111 | ||
| 125 | - Model = _NodeModel_.extend({ | 112 | + Model = _nm_.extend({ |
| 126 | initialize: function () { | 113 | initialize: function () { |
| 127 | this.set('weight', 0); | 114 | this.set('weight', 0); |
| 128 | this.constructor.__super__.initialize.apply(this, arguments); | 115 | this.constructor.__super__.initialize.apply(this, arguments); |
| ... | @@ -152,7 +139,19 @@ | ... | @@ -152,7 +139,19 @@ |
| 152 | node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon)); | 139 | node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon)); |
| 153 | this.render(); | 140 | this.render(); |
| 154 | }, | 141 | }, |
| 155 | - onExit: function () {}, | 142 | + onExit: function () { |
| 143 | + var node = this.el; | ||
| 144 | + node.select('use') | ||
| 145 | + .style('opacity', 0.5) | ||
| 146 | + .transition() | ||
| 147 | + .duration(800) | ||
| 148 | + .style('opacity', 0); | ||
| 149 | + | ||
| 150 | + node.selectAll('rect') | ||
| 151 | + .style('stroke-fill', '#555') | ||
| 152 | + .style('fill', '#888') | ||
| 153 | + .style('opacity', 0.5); | ||
| 154 | + }, | ||
| 156 | render: function () { | 155 | render: function () { |
| 157 | this.setDeviceColor(); | 156 | this.setDeviceColor(); |
| 158 | } | 157 | } | ... | ... |
| ... | @@ -34,7 +34,6 @@ | ... | @@ -34,7 +34,6 @@ |
| 34 | openListener; | 34 | openListener; |
| 35 | 35 | ||
| 36 | // TODO: only add heartbeat timer etc. if we really need to be doing that.. | 36 | // TODO: only add heartbeat timer etc. if we really need to be doing that.. |
| 37 | - | ||
| 38 | // ========================== Helper Functions | 37 | // ========================== Helper Functions |
| 39 | 38 | ||
| 40 | function createHandlerMap() { | 39 | function createHandlerMap() { |
| ... | @@ -100,4 +99,4 @@ | ... | @@ -100,4 +99,4 @@ |
| 100 | stop: stop | 99 | stop: stop |
| 101 | }; | 100 | }; |
| 102 | }]); | 101 | }]); |
| 103 | -}()); | 102 | +})(); | ... | ... |
| ... | @@ -26,43 +26,12 @@ | ... | @@ -26,43 +26,12 @@ |
| 26 | var $log, | 26 | var $log, |
| 27 | wss; | 27 | wss; |
| 28 | 28 | ||
| 29 | - // SVG elements; | 29 | + var t2is, t2rs, t2ls, t2vs, t2bcs; |
| 30 | - var linkG, | ||
| 31 | - linkLabelG, | ||
| 32 | - numLinkLblsG, | ||
| 33 | - portLabelG, | ||
| 34 | - nodeG; | ||
| 35 | - | ||
| 36 | - // internal state | ||
| 37 | - var settings, // merged default settings and options | ||
| 38 | - force, // force layout object | ||
| 39 | - drag, // drag behavior handler | ||
| 40 | - network = { | ||
| 41 | - nodes: [], | ||
| 42 | - links: [], | ||
| 43 | - linksByDevice: {}, | ||
| 44 | - lookup: {}, | ||
| 45 | - revLinkToKey: {} | ||
| 46 | - }, | ||
| 47 | - lu, // shorthand for lookup | ||
| 48 | - rlk, // shorthand for revLinktoKey | ||
| 49 | - showHosts = false, // whether hosts are displayed | ||
| 50 | - showOffline = true, // whether offline devices are displayed | ||
| 51 | - nodeLock = false, // whether nodes can be dragged or not (locked) | ||
| 52 | - fTimer, // timer for delayed force layout | ||
| 53 | - fNodesTimer, // timer for delayed nodes update | ||
| 54 | - fLinksTimer, // timer for delayed links update | ||
| 55 | - dim, // the dimensions of the force layout [w,h] | ||
| 56 | - linkNums = []; // array of link number labels | ||
| 57 | - | ||
| 58 | - // D3 selections; | ||
| 59 | - var link, | ||
| 60 | - linkLabel, | ||
| 61 | - node; | ||
| 62 | - | ||
| 63 | - var $log, wss, t2is, t2rs, t2ls, t2vs, t2bcs; | ||
| 64 | var svg, forceG, uplink, dim, opts; | 30 | var svg, forceG, uplink, dim, opts; |
| 65 | 31 | ||
| 32 | + // D3 Selections | ||
| 33 | + var node; | ||
| 34 | + | ||
| 66 | // ========================== Helper Functions | 35 | // ========================== Helper Functions |
| 67 | 36 | ||
| 68 | function init(_svg_, _forceG_, _uplink_, _dim_, _opts_) { | 37 | function init(_svg_, _forceG_, _uplink_, _dim_, _opts_) { |
| ... | @@ -70,7 +39,9 @@ | ... | @@ -70,7 +39,9 @@ |
| 70 | forceG = _forceG_; | 39 | forceG = _forceG_; |
| 71 | uplink = _uplink_; | 40 | uplink = _uplink_; |
| 72 | dim = _dim_; | 41 | dim = _dim_; |
| 73 | - opts = _opts_ | 42 | + opts = _opts_; |
| 43 | + | ||
| 44 | + t2ls.init(svg, forceG, uplink, dim, opts); | ||
| 74 | } | 45 | } |
| 75 | 46 | ||
| 76 | function destroy() { | 47 | function destroy() { |
| ... | @@ -91,7 +62,7 @@ | ... | @@ -91,7 +62,7 @@ |
| 91 | var parentRegion = data.parent; | 62 | var parentRegion = data.parent; |
| 92 | var span = topdiv.select('.parentRegion').select('span'); | 63 | var span = topdiv.select('.parentRegion').select('span'); |
| 93 | span.text(parentRegion || '[no parent]'); | 64 | span.text(parentRegion || '[no parent]'); |
| 94 | - span.classed('nav-me', !!parentRegion); | 65 | + span.classed('nav-me', Boolean(parentRegion)); |
| 95 | } | 66 | } |
| 96 | 67 | ||
| 97 | function doTmpCurrentRegion(data) { | 68 | function doTmpCurrentRegion(data) { |
| ... | @@ -162,30 +133,23 @@ | ... | @@ -162,30 +133,23 @@ |
| 162 | $log.debug('>> topo2CurrentRegion event:', data); | 133 | $log.debug('>> topo2CurrentRegion event:', data); |
| 163 | doTmpCurrentRegion(data); | 134 | doTmpCurrentRegion(data); |
| 164 | t2rs.addRegion(data); | 135 | t2rs.addRegion(data); |
| 165 | - t2ls.init(svg, forceG, uplink, dim, opts); | 136 | + t2ls.createForceLayout(); |
| 166 | - t2ls.update(); | ||
| 167 | - t2ls.start(); | ||
| 168 | } | 137 | } |
| 169 | 138 | ||
| 170 | function topo2PeerRegions(data) { | 139 | function topo2PeerRegions(data) { |
| 171 | - $log.debug('>> topo2PeerRegions event:', data) | 140 | + $log.debug('>> topo2PeerRegions event:', data); |
| 172 | doTmpPeerRegions(data); | 141 | doTmpPeerRegions(data); |
| 173 | } | 142 | } |
| 174 | 143 | ||
| 175 | - function topo2PeerRegions(data) { | ||
| 176 | - $log.debug('>> topo2PeerRegions event:', data) | ||
| 177 | - } | ||
| 178 | - | ||
| 179 | function startDone(data) { | 144 | function startDone(data) { |
| 180 | $log.debug('>> topo2StartDone event:', data); | 145 | $log.debug('>> topo2StartDone event:', data); |
| 181 | } | 146 | } |
| 182 | 147 | ||
| 183 | - | ||
| 184 | function showMastership(masterId) { | 148 | function showMastership(masterId) { |
| 185 | - if (!masterId) { | 149 | + if (masterId) { |
| 186 | - restoreLayerState(); | ||
| 187 | - } else { | ||
| 188 | showMastershipFor(masterId); | 150 | showMastershipFor(masterId); |
| 151 | + } else { | ||
| 152 | + restoreLayerState(); | ||
| 189 | } | 153 | } |
| 190 | } | 154 | } |
| 191 | 155 | ||
| ... | @@ -224,10 +188,6 @@ | ... | @@ -224,10 +188,6 @@ |
| 224 | t2ls.setDimensions(); | 188 | t2ls.setDimensions(); |
| 225 | } | 189 | } |
| 226 | 190 | ||
| 227 | - function getDim() { | ||
| 228 | - return dim; | ||
| 229 | - } | ||
| 230 | - | ||
| 231 | // ========================== Main Service Definition | 191 | // ========================== Main Service Definition |
| 232 | 192 | ||
| 233 | angular.module('ovTopo2') | 193 | angular.module('ovTopo2') |
| ... | @@ -259,4 +219,4 @@ | ... | @@ -259,4 +219,4 @@ |
| 259 | topo2PeerRegions: topo2PeerRegions | 219 | topo2PeerRegions: topo2PeerRegions |
| 260 | }; | 220 | }; |
| 261 | }]); | 221 | }]); |
| 262 | -}()); | 222 | +})(); | ... | ... |
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | (function () { | 22 | (function () { |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | - var Collection, Model, t2vs; | 25 | + var Collection, Model; |
| 26 | 26 | ||
| 27 | function createHostCollection(data, region) { | 27 | function createHostCollection(data, region) { |
| 28 | 28 | ||
| ... | @@ -41,12 +41,10 @@ | ... | @@ -41,12 +41,10 @@ |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | angular.module('ovTopo2') | 43 | angular.module('ovTopo2') |
| 44 | - .factory('Topo2HostService', | 44 | + .factory('Topo2HostService', [ |
| 45 | - [ | ||
| 46 | 'Topo2Collection', 'Topo2NodeModel', 'Topo2ViewService', | 45 | 'Topo2Collection', 'Topo2NodeModel', 'Topo2ViewService', |
| 47 | function (_Collection_, _NodeModel_, classnames, _t2vs_) { | 46 | function (_Collection_, _NodeModel_, classnames, _t2vs_) { |
| 48 | 47 | ||
| 49 | - t2vs = _t2vs_; | ||
| 50 | Collection = _Collection_; | 48 | Collection = _Collection_; |
| 51 | 49 | ||
| 52 | Model = _NodeModel_.extend({ | 50 | Model = _NodeModel_.extend({ | ... | ... |
| ... | @@ -2,13 +2,7 @@ | ... | @@ -2,13 +2,7 @@ |
| 2 | 'use strict'; | 2 | 'use strict'; |
| 3 | 3 | ||
| 4 | // injected refs | 4 | // injected refs |
| 5 | - var $log, | 5 | + var $log, ps, sus, gs, ts; |
| 6 | - ps, | ||
| 7 | - sus, | ||
| 8 | - gs, | ||
| 9 | - ts, | ||
| 10 | - fs, | ||
| 11 | - flash; | ||
| 12 | 6 | ||
| 13 | // api from topo | 7 | // api from topo |
| 14 | var api; | 8 | var api; |
| ... | @@ -24,10 +18,8 @@ | ... | @@ -24,10 +18,8 @@ |
| 24 | // internal state | 18 | // internal state |
| 25 | var onosInstances, | 19 | var onosInstances, |
| 26 | onosOrder, | 20 | onosOrder, |
| 27 | - oiShowMaster, | ||
| 28 | oiBox; | 21 | oiBox; |
| 29 | 22 | ||
| 30 | - | ||
| 31 | function addInstance(data) { | 23 | function addInstance(data) { |
| 32 | var id = data.id; | 24 | var id = data.id; |
| 33 | 25 | ||
| ... | @@ -51,30 +43,15 @@ | ... | @@ -51,30 +43,15 @@ |
| 51 | } | 43 | } |
| 52 | } | 44 | } |
| 53 | 45 | ||
| 54 | - function removeInstance(data) { | ||
| 55 | - var id = data.id, | ||
| 56 | - d = onosInstances[id]; | ||
| 57 | - if (d) { | ||
| 58 | - var idx = fs.find(id, onosOrder); | ||
| 59 | - if (idx >= 0) { | ||
| 60 | - onosOrder.splice(idx, 1); | ||
| 61 | - } | ||
| 62 | - delete onosInstances[id]; | ||
| 63 | - updateInstances(); | ||
| 64 | - } else { | ||
| 65 | - logicError('removeInstance lookup fail. ID = "' + id + '"'); | ||
| 66 | - } | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | // ========================== | 46 | // ========================== |
| 70 | 47 | ||
| 71 | function clickInst(d) { | 48 | function clickInst(d) { |
| 72 | var el = d3.select(this), | 49 | var el = d3.select(this), |
| 73 | aff = el.classed('affinity'); | 50 | aff = el.classed('affinity'); |
| 74 | - if (!aff) { | 51 | + if (aff) { |
| 75 | - setAffinity(el, d); | ||
| 76 | - } else { | ||
| 77 | cancelAffinity(); | 52 | cancelAffinity(); |
| 53 | + } else { | ||
| 54 | + setAffinity(el, d); | ||
| 78 | } | 55 | } |
| 79 | } | 56 | } |
| 80 | 57 | ||
| ... | @@ -86,7 +63,6 @@ | ... | @@ -86,7 +63,6 @@ |
| 86 | 63 | ||
| 87 | // suppress all elements except nodes whose master is this instance | 64 | // suppress all elements except nodes whose master is this instance |
| 88 | api.showMastership(d.id); | 65 | api.showMastership(d.id); |
| 89 | - oiShowMaster = true; | ||
| 90 | } | 66 | } |
| 91 | 67 | ||
| 92 | function cancelAffinity() { | 68 | function cancelAffinity() { |
| ... | @@ -94,7 +70,6 @@ | ... | @@ -94,7 +70,6 @@ |
| 94 | .classed('mastership affinity', false); | 70 | .classed('mastership affinity', false); |
| 95 | 71 | ||
| 96 | api.showMastership(null); | 72 | api.showMastership(null); |
| 97 | - oiShowMaster = false; | ||
| 98 | } | 73 | } |
| 99 | 74 | ||
| 100 | function attachUiBadge(svg) { | 75 | function attachUiBadge(svg) { |
| ... | @@ -173,7 +148,6 @@ | ... | @@ -173,7 +148,6 @@ |
| 173 | updAttr('ns', nSw(d.switches)); | 148 | updAttr('ns', nSw(d.switches)); |
| 174 | }); | 149 | }); |
| 175 | 150 | ||
| 176 | - | ||
| 177 | // operate on new onos instances | 151 | // operate on new onos instances |
| 178 | var entering = onoses.enter() | 152 | var entering = onoses.enter() |
| 179 | .append('div') | 153 | .append('div') |
| ... | @@ -235,9 +209,7 @@ | ... | @@ -235,9 +209,7 @@ |
| 235 | onoses.exit().remove(); | 209 | onoses.exit().remove(); |
| 236 | } | 210 | } |
| 237 | 211 | ||
| 238 | - | ||
| 239 | // ========================== | 212 | // ========================== |
| 240 | - | ||
| 241 | function logicError(msg) { | 213 | function logicError(msg) { |
| 242 | if (showLogicErrors) { | 214 | if (showLogicErrors) { |
| 243 | $log.warn('TopoInstService: ' + msg); | 215 | $log.warn('TopoInstService: ' + msg); |
| ... | @@ -251,23 +223,11 @@ | ... | @@ -251,23 +223,11 @@ |
| 251 | 223 | ||
| 252 | onosInstances = {}; | 224 | onosInstances = {}; |
| 253 | onosOrder = []; | 225 | onosOrder = []; |
| 254 | - oiShowMaster = false; | ||
| 255 | 226 | ||
| 256 | // we want to update the instances, each time the theme changes | 227 | // we want to update the instances, each time the theme changes |
| 257 | ts.addListener(updateInstances); | 228 | ts.addListener(updateInstances); |
| 258 | } | 229 | } |
| 259 | 230 | ||
| 260 | - function destroyInst() { | ||
| 261 | - ts.removeListener(updateInstances); | ||
| 262 | - | ||
| 263 | - ps.destroyPanel(idIns); | ||
| 264 | - oiBox = null; | ||
| 265 | - | ||
| 266 | - onosInstances = {}; | ||
| 267 | - onosOrder = []; | ||
| 268 | - oiShowMaster = false; | ||
| 269 | - } | ||
| 270 | - | ||
| 271 | function allInstances(data) { | 231 | function allInstances(data) { |
| 272 | $log.debug('Update all instances', data); | 232 | $log.debug('Update all instances', data); |
| 273 | 233 | ||
| ... | @@ -281,16 +241,14 @@ | ... | @@ -281,16 +241,14 @@ |
| 281 | angular.module('ovTopo2') | 241 | angular.module('ovTopo2') |
| 282 | .factory('Topo2InstanceService', | 242 | .factory('Topo2InstanceService', |
| 283 | ['$log', 'PanelService', 'SvgUtilService', 'GlyphService', | 243 | ['$log', 'PanelService', 'SvgUtilService', 'GlyphService', |
| 284 | - 'ThemeService', 'FnService', 'FlashService', | 244 | + 'ThemeService', |
| 285 | 245 | ||
| 286 | - function (_$log_, _ps_, _sus_, _gs_, _ts_, _fs_, _flash_) { | 246 | + function (_$log_, _ps_, _sus_, _gs_, _ts_) { |
| 287 | $log = _$log_; | 247 | $log = _$log_; |
| 288 | ps = _ps_; | 248 | ps = _ps_; |
| 289 | sus = _sus_; | 249 | sus = _sus_; |
| 290 | gs = _gs_; | 250 | gs = _gs_; |
| 291 | ts = _ts_; | 251 | ts = _ts_; |
| 292 | - fs = _fs_; | ||
| 293 | - flash = _flash_; | ||
| 294 | 252 | ||
| 295 | return { | 253 | return { |
| 296 | initInst: initInst, | 254 | initInst: initInst, |
| ... | @@ -298,4 +256,4 @@ | ... | @@ -298,4 +256,4 @@ |
| 298 | }; | 256 | }; |
| 299 | }]); | 257 | }]); |
| 300 | 258 | ||
| 301 | -}()); | 259 | +})(); | ... | ... |
| ... | @@ -24,12 +24,10 @@ | ... | @@ -24,12 +24,10 @@ |
| 24 | 24 | ||
| 25 | var $log, sus, t2rs, t2d3, t2vs, t2ss; | 25 | var $log, sus, t2rs, t2d3, t2vs, t2ss; |
| 26 | 26 | ||
| 27 | - var uplink, linkG, linkLabelG, numLinkLabelsG, nodeG, portLabelG; | 27 | + var uplink, linkG, linkLabelG, nodeG; |
| 28 | - var link, linkLabel, node; | 28 | + var link, node; |
| 29 | 29 | ||
| 30 | - var nodes, links, highlightedLink; | 30 | + var highlightedLink; |
| 31 | - | ||
| 32 | - var force; | ||
| 33 | 31 | ||
| 34 | // default settings for force layout | 32 | // default settings for force layout |
| 35 | var defaultSettings = { | 33 | var defaultSettings = { |
| ... | @@ -51,9 +49,9 @@ | ... | @@ -51,9 +49,9 @@ |
| 51 | linkStrength: { | 49 | linkStrength: { |
| 52 | // note: key is link.type | 50 | // note: key is link.type |
| 53 | // range: {0.0 ... 1.0} | 51 | // range: {0.0 ... 1.0} |
| 54 | - //direct: 1.0, | 52 | + direct: 1.0, |
| 55 | - //optical: 1.0, | 53 | + optical: 1.0, |
| 56 | - //hostLink: 1.0, | 54 | + hostLink: 1.0, |
| 57 | _def_: 1.0 | 55 | _def_: 1.0 |
| 58 | } | 56 | } |
| 59 | }; | 57 | }; |
| ... | @@ -79,23 +77,7 @@ | ... | @@ -79,23 +77,7 @@ |
| 79 | var settings, // merged default settings and options | 77 | var settings, // merged default settings and options |
| 80 | force, // force layout object | 78 | force, // force layout object |
| 81 | drag, // drag behavior handler | 79 | drag, // drag behavior handler |
| 82 | - network = { | 80 | + nodeLock = false; // whether nodes can be dragged or not (locked) |
| 83 | - nodes: [], | ||
| 84 | - links: [], | ||
| 85 | - linksByDevice: {}, | ||
| 86 | - lookup: {}, | ||
| 87 | - revLinkToKey: {} | ||
| 88 | - }, | ||
| 89 | - lu, // shorthand for lookup | ||
| 90 | - rlk, // shorthand for revLinktoKey | ||
| 91 | - showHosts = false, // whether hosts are displayed | ||
| 92 | - showOffline = true, // whether offline devices are displayed | ||
| 93 | - nodeLock = false, // whether nodes can be dragged or not (locked) | ||
| 94 | - fTimer, // timer for delayed force layout | ||
| 95 | - fNodesTimer, // timer for delayed nodes update | ||
| 96 | - fLinksTimer, // timer for delayed links update | ||
| 97 | - dim, // the dimensions of the force layout [w,h] | ||
| 98 | - linkNums = []; // array of link number labels | ||
| 99 | 81 | ||
| 100 | var tickStuff = { | 82 | var tickStuff = { |
| 101 | nodeAttr: { | 83 | nodeAttr: { |
| ... | @@ -110,14 +92,6 @@ | ... | @@ -110,14 +92,6 @@ |
| 110 | y1: function (d) { return d.get('position').y1; }, | 92 | y1: function (d) { return d.get('position').y1; }, |
| 111 | x2: function (d) { return d.get('position').x2; }, | 93 | x2: function (d) { return d.get('position').x2; }, |
| 112 | y2: function (d) { return d.get('position').y2; } | 94 | y2: function (d) { return d.get('position').y2; } |
| 113 | - }, | ||
| 114 | - linkLabelAttr: { | ||
| 115 | - transform: function (d) { | ||
| 116 | - var lnk = tms.findLinkById(d.get('key')); | ||
| 117 | - if (lnk) { | ||
| 118 | - return t2d3.transformLabel(lnk.get('position')); | ||
| 119 | - } | ||
| 120 | - } | ||
| 121 | } | 95 | } |
| 122 | }; | 96 | }; |
| 123 | 97 | ||
| ... | @@ -129,14 +103,19 @@ | ... | @@ -129,14 +103,19 @@ |
| 129 | 103 | ||
| 130 | linkG = forceG.append('g').attr('id', 'topo-links'); | 104 | linkG = forceG.append('g').attr('id', 'topo-links'); |
| 131 | linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels'); | 105 | linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels'); |
| 132 | - numLinkLabelsG = forceG.append('g').attr('id', 'topo-numLinkLabels'); | 106 | + forceG.append('g').attr('id', 'topo-numLinkLabels'); |
| 133 | nodeG = forceG.append('g').attr('id', 'topo-nodes'); | 107 | nodeG = forceG.append('g').attr('id', 'topo-nodes'); |
| 134 | - portLabelG = forceG.append('g').attr('id', 'topo-portLabels'); | 108 | + forceG.append('g').attr('id', 'topo-portLabels'); |
| 135 | 109 | ||
| 136 | link = linkG.selectAll('.link'); | 110 | link = linkG.selectAll('.link'); |
| 137 | - linkLabel = linkLabelG.selectAll('.linkLabel'); | 111 | + linkLabelG.selectAll('.linkLabel'); |
| 138 | node = nodeG.selectAll('.node'); | 112 | node = nodeG.selectAll('.node'); |
| 139 | 113 | ||
| 114 | + _svg_.on('mousemove', mouseMoveHandler); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + function createForceLayout() { | ||
| 118 | + | ||
| 140 | force = d3.layout.force() | 119 | force = d3.layout.force() |
| 141 | .size(t2vs.getDimensions()) | 120 | .size(t2vs.getDimensions()) |
| 142 | .nodes(t2rs.regionNodes()) | 121 | .nodes(t2rs.regionNodes()) |
| ... | @@ -148,10 +127,11 @@ | ... | @@ -148,10 +127,11 @@ |
| 148 | .linkStrength(settings.linkStrength._def_) | 127 | .linkStrength(settings.linkStrength._def_) |
| 149 | .on('tick', tick); | 128 | .on('tick', tick); |
| 150 | 129 | ||
| 151 | - drag = sus.createDragBehavior(force, | 130 | + drag = sus.createDragBehavior(force, |
| 152 | - t2ss.selectObject, atDragEnd, dragEnabled, clickEnabled); | 131 | + t2ss.selectObject, atDragEnd, dragEnabled, clickEnabled); |
| 153 | 132 | ||
| 154 | - _svg_.on('mousemove', mouseMoveHandler) | 133 | + start(); |
| 134 | + update(); | ||
| 155 | } | 135 | } |
| 156 | 136 | ||
| 157 | function zoomingOrPanning(ev) { | 137 | function zoomingOrPanning(ev) { |
| ... | @@ -188,9 +168,6 @@ | ... | @@ -188,9 +168,6 @@ |
| 188 | .attr(tickStuff.linkAttr); | 168 | .attr(tickStuff.linkAttr); |
| 189 | // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG); | 169 | // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG); |
| 190 | } | 170 | } |
| 191 | - if (linkLabel && linkLabel.size()) { | ||
| 192 | - linkLabel.attr(tickStuff.linkLabelAttr); | ||
| 193 | - } | ||
| 194 | } | 171 | } |
| 195 | 172 | ||
| 196 | function update() { | 173 | function update() { |
| ... | @@ -210,7 +187,7 @@ | ... | @@ -210,7 +187,7 @@ |
| 210 | .append('g') | 187 | .append('g') |
| 211 | .attr({ | 188 | .attr({ |
| 212 | id: function (d) { return sus.safeId(d.get('id')); }, | 189 | id: function (d) { return sus.safeId(d.get('id')); }, |
| 213 | - class: function (d) { return d.svgClassName() }, | 190 | + class: function (d) { return d.svgClassName(); }, |
| 214 | transform: function (d) { | 191 | transform: function (d) { |
| 215 | // Need to guard against NaN here ?? | 192 | // Need to guard against NaN here ?? |
| 216 | return sus.translate(d.node.x, d.node.y); | 193 | return sus.translate(d.node.x, d.node.y); |
| ... | @@ -227,10 +204,18 @@ | ... | @@ -227,10 +204,18 @@ |
| 227 | entering.filter('.sub-region').each(t2d3.nodeEnter); | 204 | entering.filter('.sub-region').each(t2d3.nodeEnter); |
| 228 | entering.filter('.host').each(t2d3.hostEnter); | 205 | entering.filter('.host').each(t2d3.hostEnter); |
| 229 | 206 | ||
| 230 | - // operate on both existing and new nodes: | 207 | + // operate on exiting nodes: |
| 231 | - // node.filter('.device').each(function (device) { | 208 | + // Note that the node is removed after 2 seconds. |
| 232 | - // t2d3.updateDeviceColors(device); | 209 | + // Sub element animations should be shorter than 2 seconds. |
| 233 | - // }); | 210 | + var exiting = node.exit() |
| 211 | + .transition() | ||
| 212 | + .duration(2000) | ||
| 213 | + .style('opacity', 0) | ||
| 214 | + .remove(); | ||
| 215 | + | ||
| 216 | + // exiting node specifics: | ||
| 217 | + // exiting.filter('.host').each(t2d3.hostExit); | ||
| 218 | + exiting.filter('.device').each(t2d3.nodeExit); | ||
| 234 | } | 219 | } |
| 235 | 220 | ||
| 236 | function _updateLinks() { | 221 | function _updateLinks() { |
| ... | @@ -241,16 +226,6 @@ | ... | @@ -241,16 +226,6 @@ |
| 241 | link = linkG.selectAll('.link') | 226 | link = linkG.selectAll('.link') |
| 242 | .data(regionLinks, function (d) { return d.get('key'); }); | 227 | .data(regionLinks, function (d) { return d.get('key'); }); |
| 243 | 228 | ||
| 244 | - // operate on existing links: | ||
| 245 | - link.each(function (d) { | ||
| 246 | - // this is supposed to be an existing link, but we have observed | ||
| 247 | - // occasions (where links are deleted and added rapidly?) where | ||
| 248 | - // the DOM element has not been defined. So protect against that... | ||
| 249 | - if (d.el) { | ||
| 250 | - restyleLinkElement(d, true); | ||
| 251 | - } | ||
| 252 | - }); | ||
| 253 | - | ||
| 254 | // operate on entering links: | 229 | // operate on entering links: |
| 255 | var entering = link.enter() | 230 | var entering = link.enter() |
| 256 | .append('line') | 231 | .append('line') |
| ... | @@ -260,14 +235,14 @@ | ... | @@ -260,14 +235,14 @@ |
| 260 | y1: function (d) { return d.get('position').y1; }, | 235 | y1: function (d) { return d.get('position').y1; }, |
| 261 | x2: function (d) { return d.get('position').x2; }, | 236 | x2: function (d) { return d.get('position').x2; }, |
| 262 | y2: function (d) { return d.get('position').y2; }, | 237 | y2: function (d) { return d.get('position').y2; }, |
| 263 | - stroke: linkConfig['light'].inColor, | 238 | + stroke: linkConfig.light.inColor, |
| 264 | 'stroke-width': linkConfig.inWidth | 239 | 'stroke-width': linkConfig.inWidth |
| 265 | }); | 240 | }); |
| 266 | 241 | ||
| 267 | entering.each(t2d3.linkEntering); | 242 | entering.each(t2d3.linkEntering); |
| 268 | 243 | ||
| 269 | // operate on both existing and new links: | 244 | // operate on both existing and new links: |
| 270 | - //link.each(...) | 245 | + // link.each(...) |
| 271 | 246 | ||
| 272 | // add labels for how many links are in a thick line | 247 | // add labels for how many links are in a thick line |
| 273 | // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG); | 248 | // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG); |
| ... | @@ -278,7 +253,7 @@ | ... | @@ -278,7 +253,7 @@ |
| 278 | // operate on exiting links: | 253 | // operate on exiting links: |
| 279 | link.exit() | 254 | link.exit() |
| 280 | .attr('stroke-dasharray', '3 3') | 255 | .attr('stroke-dasharray', '3 3') |
| 281 | - .attr('stroke', linkConfig['light'].outColor) | 256 | + .attr('stroke', linkConfig.light.outColor) |
| 282 | .style('opacity', 0.5) | 257 | .style('opacity', 0.5) |
| 283 | .transition() | 258 | .transition() |
| 284 | .duration(1500) | 259 | .duration(1500) |
| ... | @@ -291,33 +266,20 @@ | ... | @@ -291,33 +266,20 @@ |
| 291 | } | 266 | } |
| 292 | 267 | ||
| 293 | function calcPosition() { | 268 | function calcPosition() { |
| 294 | - var lines = this, | 269 | + var lines = this; |
| 295 | - linkSrcId, | ||
| 296 | - linkNums = []; | ||
| 297 | 270 | ||
| 298 | - lines.each(function (d) { | 271 | + lines.each(function (d) { |
| 299 | if (d.get('type') === 'hostLink') { | 272 | if (d.get('type') === 'hostLink') { |
| 300 | d.set('position', getDefaultPos(d)); | 273 | d.set('position', getDefaultPos(d)); |
| 301 | } | 274 | } |
| 302 | }); | 275 | }); |
| 303 | 276 | ||
| 304 | - function normalizeLinkSrc(link) { | ||
| 305 | - // ensure source device is consistent across set of links | ||
| 306 | - // temporary measure until link modeling is refactored | ||
| 307 | - if (!linkSrcId) { | ||
| 308 | - linkSrcId = link.source.id; | ||
| 309 | - return false; | ||
| 310 | - } | ||
| 311 | - | ||
| 312 | - return link.source.id !== linkSrcId; | ||
| 313 | - } | ||
| 314 | - | ||
| 315 | lines.each(function (d) { | 277 | lines.each(function (d) { |
| 316 | d.set('position', getDefaultPos(d)); | 278 | d.set('position', getDefaultPos(d)); |
| 317 | }); | 279 | }); |
| 318 | } | 280 | } |
| 319 | 281 | ||
| 320 | - function getDefaultPos(link) { | 282 | + function getDefaultPos(link) { |
| 321 | 283 | ||
| 322 | return { | 284 | return { |
| 323 | x1: link.get('source').x, | 285 | x1: link.get('source').x, |
| ... | @@ -333,7 +295,6 @@ | ... | @@ -333,7 +295,6 @@ |
| 333 | } | 295 | } |
| 334 | } | 296 | } |
| 335 | 297 | ||
| 336 | - | ||
| 337 | function start() { | 298 | function start() { |
| 338 | force.start(); | 299 | force.start(); |
| 339 | } | 300 | } |
| ... | @@ -343,7 +304,6 @@ | ... | @@ -343,7 +304,6 @@ |
| 343 | var mp = getLogicalMousePosition(this), | 304 | var mp = getLogicalMousePosition(this), |
| 344 | link = computeNearestLink(mp); | 305 | link = computeNearestLink(mp); |
| 345 | 306 | ||
| 346 | - | ||
| 347 | if (highlightedLink) { | 307 | if (highlightedLink) { |
| 348 | highlightedLink.unenhance(); | 308 | highlightedLink.unenhance(); |
| 349 | highlightedLink = null; | 309 | highlightedLink = null; |
| ... | @@ -363,11 +323,12 @@ | ... | @@ -363,11 +323,12 @@ |
| 363 | tr = uplink.zoomer().translate(), | 323 | tr = uplink.zoomer().translate(), |
| 364 | mx = (m[0] - tr[0]) / sc, | 324 | mx = (m[0] - tr[0]) / sc, |
| 365 | my = (m[1] - tr[1]) / sc; | 325 | my = (m[1] - tr[1]) / sc; |
| 366 | - return {x: mx, y: my}; | 326 | + return { x: mx, y: my }; |
| 367 | } | 327 | } |
| 368 | 328 | ||
| 369 | - | 329 | + function sq(x) { |
| 370 | - function sq(x) { return x * x; } | 330 | + return x * x; |
| 331 | + } | ||
| 371 | 332 | ||
| 372 | function mdist(p, m) { | 333 | function mdist(p, m) { |
| 373 | return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y)); | 334 | return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y)); |
| ... | @@ -377,33 +338,6 @@ | ... | @@ -377,33 +338,6 @@ |
| 377 | return dist / uplink.zoomer().scale(); | 338 | return dist / uplink.zoomer().scale(); |
| 378 | } | 339 | } |
| 379 | 340 | ||
| 380 | - function computeNearestNode(mouse) { | ||
| 381 | - var proximity = prox(30), | ||
| 382 | - nearest = null, | ||
| 383 | - minDist, | ||
| 384 | - regionNodes = t2rs.regionNodes(); | ||
| 385 | - | ||
| 386 | - if (regionNodes.length) { | ||
| 387 | - minDist = proximity * 2; | ||
| 388 | - | ||
| 389 | - regionNodes.forEach(function (d) { | ||
| 390 | - var dist; | ||
| 391 | - | ||
| 392 | - if (!api.showHosts() && d.class === 'host') { | ||
| 393 | - return; // skip hidden hosts | ||
| 394 | - } | ||
| 395 | - | ||
| 396 | - dist = mdist({x: d.x, y: d.y}, mouse); | ||
| 397 | - if (dist < minDist && dist < proximity) { | ||
| 398 | - minDist = dist; | ||
| 399 | - nearest = d; | ||
| 400 | - } | ||
| 401 | - }); | ||
| 402 | - } | ||
| 403 | - return nearest; | ||
| 404 | - } | ||
| 405 | - | ||
| 406 | - | ||
| 407 | function computeNearestLink(mouse) { | 341 | function computeNearestLink(mouse) { |
| 408 | var proximity = prox(30), | 342 | var proximity = prox(30), |
| 409 | nearest = null, | 343 | nearest = null, |
| ... | @@ -418,11 +352,11 @@ | ... | @@ -418,11 +352,11 @@ |
| 418 | y2 = line.y2, | 352 | y2 = line.y2, |
| 419 | x3 = mouse.x, | 353 | x3 = mouse.x, |
| 420 | y3 = mouse.y, | 354 | y3 = mouse.y, |
| 421 | - k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / | 355 | + k = ((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) / |
| 422 | - (sq(y2-y1) + sq(x2-x1)), | 356 | + (sq(y2 - y1) + sq(x2 - x1)), |
| 423 | - x4 = x3 - k * (y2-y1), | 357 | + x4 = x3 - k * (y2 - y1), |
| 424 | - y4 = y3 + k * (x2-x1); | 358 | + y4 = y3 + k * (x2 - x1); |
| 425 | - return {x:x4, y:y4}; | 359 | + return { x: x4, y: y4 }; |
| 426 | } | 360 | } |
| 427 | 361 | ||
| 428 | function lineHit(line, p, m) { | 362 | function lineHit(line, p, m) { |
| ... | @@ -476,11 +410,12 @@ | ... | @@ -476,11 +410,12 @@ |
| 476 | 410 | ||
| 477 | return { | 411 | return { |
| 478 | init: init, | 412 | init: init, |
| 413 | + createForceLayout: createForceLayout, | ||
| 479 | update: update, | 414 | update: update, |
| 480 | start: start, | 415 | start: start, |
| 481 | 416 | ||
| 482 | setDimensions: setDimensions | 417 | setDimensions: setDimensions |
| 483 | - } | 418 | + }; |
| 484 | } | 419 | } |
| 485 | ] | 420 | ] |
| 486 | ); | 421 | ); | ... | ... |
| ... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | var $log; | 25 | var $log; |
| 26 | - var Collection, Model, region, ts, sus; | 26 | + var Collection, Model, ts, sus; |
| 27 | 27 | ||
| 28 | var linkLabelOffset = '0.35em'; | 28 | var linkLabelOffset = '0.35em'; |
| 29 | 29 | ||
| ... | @@ -52,9 +52,6 @@ | ... | @@ -52,9 +52,6 @@ |
| 52 | outWidth: 10 | 52 | outWidth: 10 |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | - var defaultLinkType = 'direct', | ||
| 56 | - nearDist = 15; | ||
| 57 | - | ||
| 58 | function createLink() { | 55 | function createLink() { |
| 59 | 56 | ||
| 60 | var linkPoints = this.linkEndPoints(this.get('epA'), this.get('epB')); | 57 | var linkPoints = this.linkEndPoints(this.get('epA'), this.get('epB')); |
| ... | @@ -92,14 +89,18 @@ | ... | @@ -92,14 +89,18 @@ |
| 92 | return box; | 89 | return box; |
| 93 | } | 90 | } |
| 94 | 91 | ||
| 92 | + function isLinkOnline(node) { | ||
| 93 | + return (node.get('nodeType') === 'region') ? true : node.get('online'); | ||
| 94 | + } | ||
| 95 | + | ||
| 95 | function linkEndPoints(srcId, dstId) { | 96 | function linkEndPoints(srcId, dstId) { |
| 96 | 97 | ||
| 97 | - var sourceNode = this.region.findNodeById(srcId) | 98 | + var sourceNode = this.region.findNodeById(srcId); |
| 98 | - var targetNode = this.region.findNodeById(dstId) | 99 | + var targetNode = this.region.findNodeById(dstId); |
| 99 | 100 | ||
| 100 | if (!sourceNode || !targetNode) { | 101 | if (!sourceNode || !targetNode) { |
| 101 | $log.error('Node(s) not on map for link:' + srcId + ':' + dstId); | 102 | $log.error('Node(s) not on map for link:' + srcId + ':' + dstId); |
| 102 | - //logicError('Node(s) not on map for link:\n' + sMiss + dMiss); | 103 | + // logicError('Node(s) not on map for link:\n' + sMiss + dMiss); |
| 103 | return null; | 104 | return null; |
| 104 | } | 105 | } |
| 105 | 106 | ||
| ... | @@ -126,10 +127,13 @@ | ... | @@ -126,10 +127,13 @@ |
| 126 | return true; | 127 | return true; |
| 127 | }, | 128 | }, |
| 128 | online: function () { | 129 | online: function () { |
| 129 | - // TODO: remove next line | ||
| 130 | - return true; | ||
| 131 | 130 | ||
| 132 | - return both && (s && s.online) && (t && t.online); | 131 | + var source = this.get('source'), |
| 132 | + target = this.get('target'), | ||
| 133 | + sourceOnline = isLinkOnline(source), | ||
| 134 | + targetOnline = isLinkOnline(target); | ||
| 135 | + | ||
| 136 | + return (sourceOnline) && (targetOnline); | ||
| 133 | }, | 137 | }, |
| 134 | enhance: function () { | 138 | enhance: function () { |
| 135 | var data = [], | 139 | var data = [], |
| ... | @@ -147,7 +151,17 @@ | ... | @@ -147,7 +151,17 @@ |
| 147 | }); | 151 | }); |
| 148 | data.push(point); | 152 | data.push(point); |
| 149 | 153 | ||
| 150 | - var entering = d3.select('#topo-portLabels').selectAll('.portLabel') | 154 | + if (this.get('portA')) { |
| 155 | + point = this.locatePortLabel(1); | ||
| 156 | + angular.extend(point, { | ||
| 157 | + id: 'topo-port-src', | ||
| 158 | + num: this.get('portA') | ||
| 159 | + }); | ||
| 160 | + data.push(point); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + var entering = d3.select('#topo-portLabels') | ||
| 164 | + .selectAll('.portLabel') | ||
| 151 | .data(data).enter().append('g') | 165 | .data(data).enter().append('g') |
| 152 | .classed('portLabel', true) | 166 | .classed('portLabel', true) |
| 153 | .attr('id', function (d) { return d.id; }); | 167 | .attr('id', function (d) { return d.id; }); |
| ... | @@ -171,7 +185,7 @@ | ... | @@ -171,7 +185,7 @@ |
| 171 | this.el.classed('enhanced', false); | 185 | this.el.classed('enhanced', false); |
| 172 | d3.select('#topo-portLabels').selectAll('.portLabel').remove(); | 186 | d3.select('#topo-portLabels').selectAll('.portLabel').remove(); |
| 173 | }, | 187 | }, |
| 174 | - locatePortLabel: function (link, src) { | 188 | + locatePortLabel: function (src) { |
| 175 | var offset = 32, | 189 | var offset = 32, |
| 176 | pos = this.get('position'), | 190 | pos = this.get('position'), |
| 177 | nearX = src ? pos.x1 : pos.x2, | 191 | nearX = src ? pos.x1 : pos.x2, |
| ... | @@ -179,13 +193,15 @@ | ... | @@ -179,13 +193,15 @@ |
| 179 | farX = src ? pos.x2 : pos.x1, | 193 | farX = src ? pos.x2 : pos.x1, |
| 180 | farY = src ? pos.y2 : pos.y1; | 194 | farY = src ? pos.y2 : pos.y1; |
| 181 | 195 | ||
| 182 | - function dist(x, y) { return Math.sqrt(x*x + y*y); } | 196 | + function dist(x, y) { |
| 197 | + return Math.sqrt(x * x + y * y); | ||
| 198 | + } | ||
| 183 | 199 | ||
| 184 | var dx = farX - nearX, | 200 | var dx = farX - nearX, |
| 185 | dy = farY - nearY, | 201 | dy = farY - nearY, |
| 186 | k = offset / dist(dx, dy); | 202 | k = offset / dist(dx, dy); |
| 187 | 203 | ||
| 188 | - return {x: k * dx + nearX, y: k * dy + nearY}; | 204 | + return { x: k * dx + nearX, y: k * dy + nearY }; |
| 189 | }, | 205 | }, |
| 190 | restyleLinkElement: function (immediate) { | 206 | restyleLinkElement: function (immediate) { |
| 191 | // this fn's job is to look at raw links and decide what svg classes | 207 | // this fn's job is to look at raw links and decide what svg classes |
| ... | @@ -219,21 +235,19 @@ | ... | @@ -219,21 +235,19 @@ |
| 219 | } | 235 | } |
| 220 | }, | 236 | }, |
| 221 | onEnter: function (el) { | 237 | onEnter: function (el) { |
| 222 | - var _this = this, | 238 | + var link = d3.select(el); |
| 223 | - link = d3.select(el); | ||
| 224 | 239 | ||
| 225 | this.el = link; | 240 | this.el = link; |
| 226 | - | ||
| 227 | this.restyleLinkElement(); | 241 | this.restyleLinkElement(); |
| 228 | 242 | ||
| 229 | if (this.get('type') === 'hostLink') { | 243 | if (this.get('type') === 'hostLink') { |
| 230 | - sus.visible(link, api.showHosts()); | 244 | + // sus.visible(link, api.showHosts()); |
| 231 | } | 245 | } |
| 232 | } | 246 | } |
| 233 | }); | 247 | }); |
| 234 | 248 | ||
| 235 | var LinkCollection = Collection.extend({ | 249 | var LinkCollection = Collection.extend({ |
| 236 | - model: LinkModel, | 250 | + model: LinkModel |
| 237 | }); | 251 | }); |
| 238 | 252 | ||
| 239 | return new LinkCollection(data); | 253 | return new LinkCollection(data); |
| ... | @@ -241,7 +255,8 @@ | ... | @@ -241,7 +255,8 @@ |
| 241 | 255 | ||
| 242 | angular.module('ovTopo2') | 256 | angular.module('ovTopo2') |
| 243 | .factory('Topo2LinkService', | 257 | .factory('Topo2LinkService', |
| 244 | - ['$log', 'Topo2Collection', 'Topo2Model', 'ThemeService', 'SvgUtilService', | 258 | + ['$log', 'Topo2Collection', 'Topo2Model', |
| 259 | + 'ThemeService', 'SvgUtilService', | ||
| 245 | 260 | ||
| 246 | function (_$log_, _Collection_, _Model_, _ts_, _sus_) { | 261 | function (_$log_, _Collection_, _Model_, _ts_, _sus_) { |
| 247 | 262 | ... | ... |
| ... | @@ -42,7 +42,7 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -42,7 +42,7 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. |
| 42 | return this.attributes[attr]; | 42 | return this.attributes[attr]; |
| 43 | }, | 43 | }, |
| 44 | 44 | ||
| 45 | - set: function(key, val, options) { | 45 | + set: function (key, val, options) { |
| 46 | 46 | ||
| 47 | if (!key) { | 47 | if (!key) { |
| 48 | return this; | 48 | return this; |
| ... | @@ -56,19 +56,21 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -56,19 +56,21 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. |
| 56 | (attributes = {})[key] = val; | 56 | (attributes = {})[key] = val; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | - options || (options = {}); | 59 | + var opts = options || (options = {}); |
| 60 | 60 | ||
| 61 | - var unset = options.unset, | 61 | + var unset = opts.unset, |
| 62 | - silent = options.silent, | 62 | + silent = opts.silent, |
| 63 | changes = [], | 63 | changes = [], |
| 64 | - changing = this._changing; | 64 | + changing = this._changing; |
| 65 | 65 | ||
| 66 | this._changing = true; | 66 | this._changing = true; |
| 67 | 67 | ||
| 68 | if (!changing) { | 68 | if (!changing) { |
| 69 | 69 | ||
| 70 | // NOTE: angular.copy causes issues in chrome | 70 | // NOTE: angular.copy causes issues in chrome |
| 71 | - this._previousAttributes = Object.create(Object.getPrototypeOf(this.attributes)); | 71 | + this._previousAttributes = Object.create( |
| 72 | + Object.getPrototypeOf(this.attributes) | ||
| 73 | + ); | ||
| 72 | this.changed = {}; | 74 | this.changed = {}; |
| 73 | } | 75 | } |
| 74 | 76 | ||
| ... | @@ -84,34 +86,38 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -84,34 +86,38 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. |
| 84 | changes.push(index); | 86 | changes.push(index); |
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | - if (!angular.equals(previous[index], val)) { | 89 | + if (angular.equals(previous[index], val)) { |
| 88 | - changed[index] = val; | ||
| 89 | - } else { | ||
| 90 | delete changed[index]; | 90 | delete changed[index]; |
| 91 | + } else { | ||
| 92 | + changed[index] = val; | ||
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | - unset ? delete current[index] : current[index] = val; | 95 | + if (unset) { |
| 96 | + delete current[index]; | ||
| 97 | + } else { | ||
| 98 | + current[index] = val; | ||
| 99 | + } | ||
| 94 | }); | 100 | }); |
| 95 | 101 | ||
| 96 | // Trigger all relevant attribute changes. | 102 | // Trigger all relevant attribute changes. |
| 97 | if (!silent) { | 103 | if (!silent) { |
| 98 | if (changes.length) { | 104 | if (changes.length) { |
| 99 | - this._pending = options; | 105 | + this._pending = opts; |
| 100 | } | 106 | } |
| 101 | for (var i = 0; i < changes.length; i++) { | 107 | for (var i = 0; i < changes.length; i++) { |
| 102 | - this.onChange(changes[i], this, current[changes[i]], options); | 108 | + this.onChange(changes[i], this, |
| 109 | + current[changes[i]], opts); | ||
| 103 | } | 110 | } |
| 104 | } | 111 | } |
| 105 | 112 | ||
| 106 | this._changing = false; | 113 | this._changing = false; |
| 107 | return this; | 114 | return this; |
| 108 | }, | 115 | }, |
| 109 | - toJSON: function(options) { | 116 | + toJSON: function (options) { |
| 110 | - return angular.copy(this.attributes) | 117 | + return angular.copy(this.attributes); |
| 111 | - }, | 118 | + } |
| 112 | }; | 119 | }; |
| 113 | 120 | ||
| 114 | - | ||
| 115 | Model.extend = function (protoProps, staticProps) { | 121 | Model.extend = function (protoProps, staticProps) { |
| 116 | 122 | ||
| 117 | var parent = this; | 123 | var parent = this; |
| ... | @@ -136,8 +142,7 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -136,8 +142,7 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. |
| 136 | }; | 142 | }; |
| 137 | 143 | ||
| 138 | angular.module('ovTopo2') | 144 | angular.module('ovTopo2') |
| 139 | - .factory('Topo2Model', | 145 | + .factory('Topo2Model', [ |
| 140 | - [ | ||
| 141 | function () { | 146 | function () { |
| 142 | return Model; | 147 | return Model; |
| 143 | } | 148 | } | ... | ... |
| ... | @@ -25,9 +25,8 @@ | ... | @@ -25,9 +25,8 @@ |
| 25 | var randomService; | 25 | var randomService; |
| 26 | var fn; | 26 | var fn; |
| 27 | 27 | ||
| 28 | - //internal state; | 28 | + // Internal state; |
| 29 | - var defaultLinkType = 'direct', | 29 | + var nearDist = 15; |
| 30 | - nearDist = 15; | ||
| 31 | 30 | ||
| 32 | var devIconDim = 36, | 31 | var devIconDim = 36, |
| 33 | labelPad = 10, | 32 | labelPad = 10, |
| ... | @@ -42,9 +41,9 @@ | ... | @@ -42,9 +41,9 @@ |
| 42 | dim = [800, 600], | 41 | dim = [800, 600], |
| 43 | xy; | 42 | xy; |
| 44 | 43 | ||
| 45 | - // if the device contains explicit LONG/LAT data, use that to position | 44 | + // If the device contains explicit LONG/LAT data, use that to position |
| 46 | if (setLongLat(node)) { | 45 | if (setLongLat(node)) { |
| 47 | - //indicate we want to update cached meta data... | 46 | + // Indicate we want to update cached meta data... |
| 48 | return true; | 47 | return true; |
| 49 | } | 48 | } |
| 50 | 49 | ||
| ... | @@ -108,7 +107,7 @@ | ... | @@ -108,7 +107,7 @@ |
| 108 | 107 | ||
| 109 | angular.module('ovTopo2') | 108 | angular.module('ovTopo2') |
| 110 | .factory('Topo2NodeModel', | 109 | .factory('Topo2NodeModel', |
| 111 | - ['Topo2Model', 'FnService', 'RandomService', | 110 | + ['Topo2Model', 'FnService', 'RandomService', |
| 112 | function (Model, _fn_, _RandomService_) { | 111 | function (Model, _fn_, _RandomService_) { |
| 113 | 112 | ||
| 114 | randomService = _RandomService_; | 113 | randomService = _RandomService_; |
| ... | @@ -118,25 +117,28 @@ | ... | @@ -118,25 +117,28 @@ |
| 118 | initialize: function () { | 117 | initialize: function () { |
| 119 | this.node = this.createNode(); | 118 | this.node = this.createNode(); |
| 120 | }, | 119 | }, |
| 120 | + onEnter: function () {}, // To be overridden by sub-class | ||
| 121 | + onExit: function () {}, // To be overridden by sub-class | ||
| 121 | label: function () { | 122 | label: function () { |
| 122 | 123 | ||
| 123 | var props = this.get('props'), | 124 | var props = this.get('props'), |
| 124 | id = this.get('id'), | 125 | id = this.get('id'), |
| 125 | friendlyName = props ? props.name : id, | 126 | friendlyName = props ? props.name : id, |
| 126 | labels = ['', friendlyName, id], | 127 | labels = ['', friendlyName, id], |
| 127 | - idx = (nodeLabelIndex < labels.length) ? nodeLabelIndex : 0; | 128 | + nli = nodeLabelIndex, |
| 129 | + idx = (nli < labels.length) ? nli : 0; | ||
| 128 | 130 | ||
| 129 | return labels[idx]; | 131 | return labels[idx]; |
| 130 | }, | 132 | }, |
| 131 | - trimLabel: function(label) { | 133 | + trimLabel: function (label) { |
| 132 | return (label && label.trim()) || ''; | 134 | return (label && label.trim()) || ''; |
| 133 | }, | 135 | }, |
| 134 | - computeLabelWidth: function(el) { | 136 | + computeLabelWidth: function (el) { |
| 135 | var text = el.select('text'), | 137 | var text = el.select('text'), |
| 136 | - box = text.node().getBBox(); | 138 | + box = text.node().getBBox(); |
| 137 | return box.width + labelPad * 2; | 139 | return box.width + labelPad * 2; |
| 138 | }, | 140 | }, |
| 139 | - addLabelElements: function(label) { | 141 | + addLabelElements: function (label) { |
| 140 | var rect = this.el.append('rect'); | 142 | var rect = this.el.append('rect'); |
| 141 | var text = this.el.append('text').text(label) | 143 | var text = this.el.append('text').text(label) |
| 142 | .attr('text-anchor', 'left') | 144 | .attr('text-anchor', 'left') |
| ... | @@ -146,12 +148,16 @@ | ... | @@ -146,12 +148,16 @@ |
| 146 | return { | 148 | return { |
| 147 | rect: rect, | 149 | rect: rect, |
| 148 | text: text | 150 | text: text |
| 149 | - } | 151 | + }; |
| 150 | }, | 152 | }, |
| 151 | svgClassName: function () { | 153 | svgClassName: function () { |
| 152 | - return fn.classNames('node', this.nodeType, this.get('type'), { | 154 | + return fn.classNames('node', |
| 153 | - online: this.get('online') | 155 | + this.nodeType, |
| 154 | - }); | 156 | + this.get('type'), |
| 157 | + { | ||
| 158 | + online: this.get('online') | ||
| 159 | + } | ||
| 160 | + ); | ||
| 155 | }, | 161 | }, |
| 156 | createNode: function () { | 162 | createNode: function () { |
| 157 | 163 | ... | ... |
| ... | @@ -23,32 +23,30 @@ | ... | @@ -23,32 +23,30 @@ |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | // Injected Services | 25 | // Injected Services |
| 26 | - var $log, wss, t2sr, t2ds, t2hs, t2ls; | 26 | + var $log, t2sr, t2ds, t2hs, t2ls; |
| 27 | - var Collection, Model; | 27 | + var Model; |
| 28 | 28 | ||
| 29 | - //Internal | 29 | + // Internal |
| 30 | var region; | 30 | var region; |
| 31 | 31 | ||
| 32 | - function init() { | 32 | + function init() {} |
| 33 | - regions = {}; | ||
| 34 | - } | ||
| 35 | 33 | ||
| 36 | function addRegion(data) { | 34 | function addRegion(data) { |
| 37 | 35 | ||
| 38 | var RegionModel = Model.extend({ | 36 | var RegionModel = Model.extend({ |
| 39 | findNodeById: findNodeById | 37 | findNodeById: findNodeById |
| 40 | - }) | 38 | + }); |
| 41 | 39 | ||
| 42 | region = new RegionModel({ | 40 | region = new RegionModel({ |
| 43 | id: data.id, | 41 | id: data.id, |
| 44 | - layerOrder: data.layerOrder, | 42 | + layerOrder: data.layerOrder |
| 45 | }); | 43 | }); |
| 46 | 44 | ||
| 47 | region.set({ | 45 | region.set({ |
| 48 | subregions: t2sr.createSubRegionCollection(data.subregions, region), | 46 | subregions: t2sr.createSubRegionCollection(data.subregions, region), |
| 49 | devices: t2ds.createDeviceCollection(data.devices, region), | 47 | devices: t2ds.createDeviceCollection(data.devices, region), |
| 50 | hosts: t2hs.createHostCollection(data.hosts, region), | 48 | hosts: t2hs.createHostCollection(data.hosts, region), |
| 51 | - links: t2ls.createLinkCollection(data.links, region), | 49 | + links: t2ls.createLinkCollection(data.links, region) |
| 52 | }); | 50 | }); |
| 53 | 51 | ||
| 54 | angular.forEach(region.get('links').models, function (link) { | 52 | angular.forEach(region.get('links').models, function (link) { |
| ... | @@ -58,18 +56,10 @@ | ... | @@ -58,18 +56,10 @@ |
| 58 | $log.debug('Region: ', region); | 56 | $log.debug('Region: ', region); |
| 59 | } | 57 | } |
| 60 | 58 | ||
| 61 | - function regionNodes() { | ||
| 62 | - return [].concat( | ||
| 63 | - region.get('devices').models, | ||
| 64 | - region.get('hosts').models, | ||
| 65 | - region.get('subregions').models | ||
| 66 | - ); | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | function findNodeById(id) { | 59 | function findNodeById(id) { |
| 70 | 60 | ||
| 71 | // Remove /{port} from id if needed | 61 | // Remove /{port} from id if needed |
| 72 | - var regex = new RegExp('^[^\/]*'); | 62 | + var regex = new RegExp('^[^/]*'); |
| 73 | id = regex.exec(id)[0]; | 63 | id = regex.exec(id)[0]; |
| 74 | 64 | ||
| 75 | return region.get('devices').get(id) || | 65 | return region.get('devices').get(id) || |
| ... | @@ -77,25 +67,37 @@ | ... | @@ -77,25 +67,37 @@ |
| 77 | region.get('subregions').get(id); | 67 | region.get('subregions').get(id); |
| 78 | } | 68 | } |
| 79 | 69 | ||
| 70 | + function regionNodes() { | ||
| 71 | + | ||
| 72 | + if (region) { | ||
| 73 | + return [].concat( | ||
| 74 | + region.get('devices').models, | ||
| 75 | + region.get('hosts').models, | ||
| 76 | + region.get('subregions').models | ||
| 77 | + ); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + return []; | ||
| 81 | + } | ||
| 82 | + | ||
| 80 | function regionLinks() { | 83 | function regionLinks() { |
| 81 | - return region.get('links').models; | 84 | + return (region) ? region.get('links').models : []; |
| 82 | } | 85 | } |
| 83 | 86 | ||
| 84 | angular.module('ovTopo2') | 87 | angular.module('ovTopo2') |
| 85 | .factory('Topo2RegionService', | 88 | .factory('Topo2RegionService', |
| 86 | - ['$log', 'WebSocketService', 'Topo2Model', 'Topo2SubRegionService', 'Topo2DeviceService', | 89 | + ['$log', 'Topo2Model', |
| 87 | - 'Topo2HostService', 'Topo2LinkService', 'Topo2Collection', | 90 | + 'Topo2SubRegionService', 'Topo2DeviceService', |
| 91 | + 'Topo2HostService', 'Topo2LinkService', | ||
| 88 | 92 | ||
| 89 | - function (_$log_, _wss_, _Model_, _t2sr_, _t2ds_, _t2hs_, _t2ls_, _Collection_) { | 93 | + function (_$log_, _Model_, _t2sr_, _t2ds_, _t2hs_, _t2ls_) { |
| 90 | 94 | ||
| 91 | $log = _$log_; | 95 | $log = _$log_; |
| 92 | - wss = _wss_; | 96 | + Model = _Model_; |
| 93 | - Model = _Model_ | ||
| 94 | t2sr = _t2sr_; | 97 | t2sr = _t2sr_; |
| 95 | t2ds = _t2ds_; | 98 | t2ds = _t2ds_; |
| 96 | t2hs = _t2hs_; | 99 | t2hs = _t2hs_; |
| 97 | t2ls = _t2ls_; | 100 | t2ls = _t2ls_; |
| 98 | - Collection = _Collection_; | ||
| 99 | 101 | ||
| 100 | return { | 102 | return { |
| 101 | init: init, | 103 | init: init, | ... | ... |
| ... | @@ -22,26 +22,18 @@ | ... | @@ -22,26 +22,18 @@ |
| 22 | 'use strict'; | 22 | 'use strict'; |
| 23 | 23 | ||
| 24 | // internal state | 24 | // internal state |
| 25 | - var hovered, selections, selectOrder, consumeClick; | 25 | + var consumeClick; |
| 26 | 26 | ||
| 27 | - function selectObject(obj) { | 27 | + function selectObject(obj) {} |
| 28 | - var el = this, | ||
| 29 | - nodeEv = el && el.tagName === 'g', | ||
| 30 | - ev = d3.event.sourceEvent || {}, | ||
| 31 | - n; | ||
| 32 | - | ||
| 33 | - console.log(el, nodeEv, ev, n); | ||
| 34 | - } | ||
| 35 | 28 | ||
| 36 | function clickConsumed(x) { | 29 | function clickConsumed(x) { |
| 37 | var cc = consumeClick; | 30 | var cc = consumeClick; |
| 38 | - consumeClick = !!x; | 31 | + consumeClick = Boolean(x); |
| 39 | return cc; | 32 | return cc; |
| 40 | } | 33 | } |
| 41 | 34 | ||
| 42 | angular.module('ovTopo2') | 35 | angular.module('ovTopo2') |
| 43 | - .factory('Topo2SelectService', | 36 | + .factory('Topo2SelectService', [ |
| 44 | - [ | ||
| 45 | function () { | 37 | function () { |
| 46 | 38 | ||
| 47 | return { | 39 | return { | ... | ... |
| ... | @@ -22,7 +22,7 @@ | ... | @@ -22,7 +22,7 @@ |
| 22 | (function () { | 22 | (function () { |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | - var wss, is, sus, ts, t2vs; | 25 | + var wss, is, sus; |
| 26 | var Collection, Model; | 26 | var Collection, Model; |
| 27 | 27 | ||
| 28 | var remappedDeviceTypes = { | 28 | var remappedDeviceTypes = { |
| ... | @@ -31,22 +31,7 @@ | ... | @@ -31,22 +31,7 @@ |
| 31 | 31 | ||
| 32 | // configuration | 32 | // configuration |
| 33 | var devIconDim = 36, | 33 | var devIconDim = 36, |
| 34 | - labelPad = 10, | 34 | + halfDevIcon = devIconDim / 2; |
| 35 | - hostRadius = 14, | ||
| 36 | - badgeConfig = { | ||
| 37 | - radius: 12, | ||
| 38 | - yoff: 5, | ||
| 39 | - gdelta: 10 | ||
| 40 | - }, | ||
| 41 | - halfDevIcon = devIconDim / 2, | ||
| 42 | - devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon }, | ||
| 43 | - hostBadgeOff = { dx: -hostRadius, dy: -hostRadius }, | ||
| 44 | - status = { | ||
| 45 | - i: 'badgeInfo', | ||
| 46 | - w: 'badgeWarn', | ||
| 47 | - e: 'badgeError' | ||
| 48 | - }, | ||
| 49 | - deviceLabelIndex = 0; | ||
| 50 | 35 | ||
| 51 | function createSubRegionCollection(data, region) { | 36 | function createSubRegionCollection(data, region) { |
| 52 | 37 | ||
| ... | @@ -67,22 +52,20 @@ | ... | @@ -67,22 +52,20 @@ |
| 67 | y: -dim / 2, | 52 | y: -dim / 2, |
| 68 | width: dim + labelWidth, | 53 | width: dim + labelWidth, |
| 69 | height: dim | 54 | height: dim |
| 70 | - } | 55 | + }; |
| 71 | } | 56 | } |
| 72 | 57 | ||
| 73 | angular.module('ovTopo2') | 58 | angular.module('ovTopo2') |
| 74 | .factory('Topo2SubRegionService', | 59 | .factory('Topo2SubRegionService', |
| 75 | - ['WebSocketService', 'Topo2Collection', 'Topo2NodeModel', 'IconService', 'SvgUtilService', | 60 | + ['WebSocketService', 'Topo2Collection', 'Topo2NodeModel', |
| 76 | - 'ThemeService', 'Topo2ViewService', | 61 | + 'IconService', 'SvgUtilService', 'ThemeService', 'Topo2ViewService', |
| 77 | 62 | ||
| 78 | - function (_wss_, _Collection_, _NodeModel_, _is_, _sus_, _ts_, classnames, _t2vs_) { | 63 | + function (_wss_, _c_, _NodeModel_, _is_, _sus_, _ts_, _t2vs_) { |
| 79 | 64 | ||
| 80 | wss = _wss_; | 65 | wss = _wss_; |
| 81 | - t2vs = _t2vs_; | ||
| 82 | is = _is_; | 66 | is = _is_; |
| 83 | sus = _sus_; | 67 | sus = _sus_; |
| 84 | - ts = _ts_; | 68 | + Collection = _c_; |
| 85 | - Collection = _Collection_; | ||
| 86 | 69 | ||
| 87 | Model = _NodeModel_.extend({ | 70 | Model = _NodeModel_.extend({ |
| 88 | initialize: function () { | 71 | initialize: function () { | ... | ... |
| ... | @@ -15,8 +15,10 @@ | ... | @@ -15,8 +15,10 @@ |
| 15 | "license": "Apache 2.0", | 15 | "license": "Apache 2.0", |
| 16 | "devDependencies": { | 16 | "devDependencies": { |
| 17 | "browser-sync": "^2.12.8", | 17 | "browser-sync": "^2.12.8", |
| 18 | + "eslint": "^3.4.0", | ||
| 19 | + "eslint-config-google": "^0.6.0", | ||
| 20 | + "express": "^4.14.0", | ||
| 18 | "parallelshell": "^2.0.0", | 21 | "parallelshell": "^2.0.0", |
| 19 | - "serve-static": "^1.10.2", | 22 | + "serve-static": "^1.10.2" |
| 20 | - "express": "^4.14.0" | ||
| 21 | } | 23 | } |
| 22 | } | 24 | } | ... | ... |
-
Please register or login to post a comment