blob: b6ed85069105d6ae8c951d832b99beaf284ac52b [file] [log] [blame]
Simon Huntd5b96732016-07-08 13:22:27 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Topology Force Module.
19 Visualization of the topology in an SVG layer, using a D3 Force Layout.
20 */
21
22(function () {
23 'use strict';
24
25 // injected refs
Steven Burrows57e24e92016-08-04 18:38:24 +010026 var $log,
27 wss;
28
Steven Burrowsdfa52b02016-09-02 13:50:43 +010029 var t2is, t2rs, t2ls, t2vs, t2bcs;
Steven Burrowsec1f45c2016-08-08 16:14:41 +010030 var svg, forceG, uplink, dim, opts;
Simon Huntd5b96732016-07-08 13:22:27 -070031
Steven Burrowsdfa52b02016-09-02 13:50:43 +010032 // D3 Selections
33 var node;
34
Simon Huntd5b96732016-07-08 13:22:27 -070035 // ========================== Helper Functions
36
Steven Burrowsec1f45c2016-08-08 16:14:41 +010037 function init(_svg_, _forceG_, _uplink_, _dim_, _opts_) {
38 svg = _svg_;
39 forceG = _forceG_;
40 uplink = _uplink_;
41 dim = _dim_;
Steven Burrowsdfa52b02016-09-02 13:50:43 +010042 opts = _opts_;
43
44 t2ls.init(svg, forceG, uplink, dim, opts);
Simon Huntd5b96732016-07-08 13:22:27 -070045 }
46
47 function destroy() {
48 $log.debug('Destroy topo force layout');
49 }
50
Simon Hunt98189192016-07-29 19:02:27 -070051 // ========================== Temporary Code (to be deleted later)
52
53 function request(dir, rid) {
54 wss.sendEvent('topo2navRegion', {
55 dir: dir,
56 rid: rid
57 });
58 }
59
60 function doTmpCurrentLayout(data) {
61 var topdiv = d3.select('#topo2tmp');
62 var parentRegion = data.parent;
63 var span = topdiv.select('.parentRegion').select('span');
64 span.text(parentRegion || '[no parent]');
Steven Burrowsdfa52b02016-09-02 13:50:43 +010065 span.classed('nav-me', Boolean(parentRegion));
Simon Hunt98189192016-07-29 19:02:27 -070066 }
67
68 function doTmpCurrentRegion(data) {
69 var topdiv = d3.select('#topo2tmp');
70 var span = topdiv.select('.thisRegion').select('span');
71 var div;
72
73 span.text(data.id);
74
75 div = topdiv.select('.subRegions').select('div');
76 data.subregions.forEach(function (r) {
77
78 function nav() {
79 request('down', r.id);
80 }
81
82 div.append('p')
83 .classed('nav-me', true)
84 .text(r.id)
85 .on('click', nav);
86 });
87
88 div = topdiv.select('.devices').select('div');
89 data.layerOrder.forEach(function (tag, idx) {
90 var devs = data.devices[idx];
91 devs.forEach(function (d) {
92 div.append('p')
93 .text('[' + tag + '] ' + d.id);
94 });
95
96 });
97
98 div = topdiv.select('.hosts').select('div');
99 data.layerOrder.forEach(function (tag, idx) {
100 var hosts = data.hosts[idx];
101 hosts.forEach(function (h) {
102 div.append('p')
103 .text('[' + tag + '] ' + h.id);
104 });
105 });
106
107 div = topdiv.select('.links').select('div');
108 var links = data.links;
109 links.forEach(function (lnk) {
110 div.append('p')
111 .text(lnk.id);
112 });
113 }
114
115 function doTmpPeerRegions(data) {
116
117 }
118
Simon Huntd5b96732016-07-08 13:22:27 -0700119 // ========================== Event Handlers
120
121 function allInstances(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100122 $log.debug('>> topo2AllInstances event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700123 doTmpCurrentLayout(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100124 t2is.allInstances(data);
Simon Huntd5b96732016-07-08 13:22:27 -0700125 }
126
127 function currentLayout(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100128 $log.debug('>> topo2CurrentLayout event:', data);
Steven Burrowsaf3159d2016-08-25 14:54:30 +0100129 t2bcs.addBreadcrumb(data.crumbs);
Simon Huntd5b96732016-07-08 13:22:27 -0700130 }
131
132 function currentRegion(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100133 $log.debug('>> topo2CurrentRegion event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700134 doTmpCurrentRegion(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100135 t2rs.addRegion(data);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100136 t2ls.createForceLayout();
Simon Hunt98189192016-07-29 19:02:27 -0700137 }
138
139 function topo2PeerRegions(data) {
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100140 $log.debug('>> topo2PeerRegions event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700141 doTmpPeerRegions(data);
142 }
143
Simon Huntd5b96732016-07-08 13:22:27 -0700144 function startDone(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100145 $log.debug('>> topo2StartDone event:', data);
Simon Huntd5b96732016-07-08 13:22:27 -0700146 }
Steven Burrows57e24e92016-08-04 18:38:24 +0100147
Steven Burrows57e24e92016-08-04 18:38:24 +0100148 function showMastership(masterId) {
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100149 if (masterId) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100150 showMastershipFor(masterId);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100151 } else {
152 restoreLayerState();
Steven Burrows57e24e92016-08-04 18:38:24 +0100153 }
154 }
155
156 function restoreLayerState() {
157 // NOTE: this level of indirection required, for when we have
158 // the layer filter functionality re-implemented
159 suppressLayers(false);
160 }
161
162 // ========================== Main Service Definition
163
164 function showMastershipFor(id) {
165 suppressLayers(true);
166 node.each(function (n) {
167 if (n.master === id) {
168 n.el.classed('suppressedmax', false);
169 }
170 });
171 }
172
173 function supAmt(less) {
174 return less ? 'suppressed' : 'suppressedmax';
175 }
176
177 function suppressLayers(b, less) {
178 var cls = supAmt(less);
179 node.classed(cls, b);
180 // link.classed(cls, b);
181 }
182
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100183 function newDim(_dim_) {
184 dim = _dim_;
185 t2vs.newDim(dim);
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100186 }
187
Simon Huntd5b96732016-07-08 13:22:27 -0700188 // ========================== Main Service Definition
189
Steven Burrows1c5c8612016-10-05 13:45:13 -0500190 function update(elements) {
191 angular.forEach(elements, function (el) {
192 el.update();
193 });
194 }
195
Steven Burrows37549ee2016-09-21 14:41:39 +0100196 function updateNodes() {
Steven Burrows1c5c8612016-10-05 13:45:13 -0500197 update(t2rs.regionNodes());
198 }
199
200 function updateLinks() {
201 update(t2rs.regionLinks());
202 }
203
204 function resetAllLocations() {
205 var nodes = t2rs.regionNodes();
206
207 angular.forEach(nodes, function (node) {
208 node.resetPosition();
209 });
210
211 t2ls.update();
212 t2ls.tick();
213 }
214
215 function unpin() {
216 var hovered = t2rs.filterRegionNodes(function (model) {
217 return model.get('hovered');
218 });
219
220 angular.forEach(hovered, function (model) {
221 model.fixed = false;
222 model.el.classed('fixed', false);
Steven Burrows0616e802016-10-06 21:45:07 -0500223 });
Steven Burrows37549ee2016-09-21 14:41:39 +0100224 }
225
Simon Huntd5b96732016-07-08 13:22:27 -0700226 angular.module('ovTopo2')
227 .factory('Topo2ForceService',
Steven Burrows1c5c8612016-10-05 13:45:13 -0500228 ['$log', 'WebSocketService', 'Topo2InstanceService',
229 'Topo2RegionService', 'Topo2LayoutService', 'Topo2ViewService',
230 'Topo2BreadcrumbService', 'Topo2ZoomService',
231 function (_$log_, _wss_, _t2is_, _t2rs_, _t2ls_,
232 _t2vs_, _t2bcs_, zoomService) {
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100233
Simon Huntd5b96732016-07-08 13:22:27 -0700234 $log = _$log_;
235 wss = _wss_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100236 t2is = _t2is_;
237 t2rs = _t2rs_;
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100238 t2ls = _t2ls_;
239 t2vs = _t2vs_;
Steven Burrowsaf3159d2016-08-25 14:54:30 +0100240 t2bcs = _t2bcs_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100241
Steven Burrows0616e802016-10-06 21:45:07 -0500242 var onZoom = function () {
243 var nodes = [].concat(
244 t2rs.regionNodes(),
245 t2rs.regionLinks()
246 );
247
248 angular.forEach(nodes, function (node) {
249 node.setScale();
250 });
251 };
252
253 zoomService.addZoomEventListener(onZoom);
254
Simon Huntd5b96732016-07-08 13:22:27 -0700255 return {
Steven Burrows57e24e92016-08-04 18:38:24 +0100256
Simon Huntd5b96732016-07-08 13:22:27 -0700257 init: init,
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100258 newDim: newDim,
Steven Burrows57e24e92016-08-04 18:38:24 +0100259
Simon Huntd5b96732016-07-08 13:22:27 -0700260 destroy: destroy,
261 topo2AllInstances: allInstances,
262 topo2CurrentLayout: currentLayout,
263 topo2CurrentRegion: currentRegion,
Steven Burrows57e24e92016-08-04 18:38:24 +0100264 topo2StartDone: startDone,
265
266 showMastership: showMastership,
Steven Burrows37549ee2016-09-21 14:41:39 +0100267 topo2PeerRegions: topo2PeerRegions,
268
Steven Burrows1c5c8612016-10-05 13:45:13 -0500269 updateNodes: updateNodes,
270 updateLinks: updateLinks,
271 resetAllLocations: resetAllLocations,
272 unpin: unpin
Simon Huntd5b96732016-07-08 13:22:27 -0700273 };
274 }]);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100275})();