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
302 additions
and
494 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 | 26 | ||
49 | - // note: these are the device icon colors without affinity (no master) | 27 | + // Configuration |
50 | - var dColTheme = { | 28 | + var hostRadius = 14; |
51 | - light: { | ||
52 | - online: '#444444', | ||
53 | - offline: '#cccccc' | ||
54 | - }, | ||
55 | - dark: { | ||
56 | - // TODO: theme | ||
57 | - online: '#444444', | ||
58 | - offline: '#cccccc' | ||
59 | - } | ||
60 | - }; | ||
61 | 29 | ||
62 | function init() {} | 30 | function init() {} |
63 | 31 | ||
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 | - | ||
102 | - node.select('text').text(label); | ||
103 | - labelWidth = label ? computeLabelWidth(node) : 0; | ||
104 | - | ||
105 | - node.select('rect') | ||
106 | - .transition() | ||
107 | - .attr(iconBox(devIconDim, labelWidth)); | ||
108 | - | ||
109 | - if (bdg) { | ||
110 | - renderBadge(node, bdg, devBadgeOff); | ||
111 | - } | ||
112 | - } | ||
113 | - | ||
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()) |
... | @@ -151,7 +130,8 @@ | ... | @@ -151,7 +130,8 @@ |
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,9 +266,7 @@ | ... | @@ -291,9 +266,7 @@ |
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') { |
... | @@ -301,17 +274,6 @@ | ... | @@ -301,17 +274,6 @@ |
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 | }); |
... | @@ -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,10 +56,10 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -56,10 +56,10 @@ 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 | ||
... | @@ -68,7 +68,9 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. | ... | @@ -68,7 +68,9 @@ Visualization of the topology in an SVG layer, using a D3 Force Layout. |
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 | ||
... | @@ -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', |
155 | + this.nodeType, | ||
156 | + this.get('type'), | ||
157 | + { | ||
153 | online: this.get('online') | 158 | online: this.get('online') |
154 | - }); | 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