blob: 1c2ea67fcf89c81bd5900289948f2dd6340681e7 [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 Burrowsb43c1a92017-03-07 17:13:28 +000029 var t2is, t2rs, t2ls, t2vs, t2bcs, t2ss, t2bgs;
Steven Burrows1aa4f582016-12-13 15:05:41 -050030 var svg, forceG, uplink, dim, opts, zoomer;
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 Burrowsaf96a212016-12-28 12:57:02 +000037 function init(_svg_, _forceG_, _uplink_, _dim_, zoomer, _opts_) {
Steven Burrowsec1f45c2016-08-08 16:14:41 +010038 svg = _svg_;
39 forceG = _forceG_;
40 uplink = _uplink_;
41 dim = _dim_;
Steven Burrowsdfa52b02016-09-02 13:50:43 +010042 opts = _opts_;
43
Steven Burrowsaf96a212016-12-28 12:57:02 +000044 t2bcs.addLayout(t2ls);
Steven Burrowsb43c1a92017-03-07 17:13:28 +000045 t2bgs.init();
46 t2ls = t2ls(svg, forceG, uplink, dim, zoomer, opts);
Steven Burrowsaf96a212016-12-28 12:57:02 +000047 t2rs.layout = t2ls;
48 t2ss.init(svg, zoomer);
Simon Huntd5b96732016-07-08 13:22:27 -070049 }
50
51 function destroy() {
52 $log.debug('Destroy topo force layout');
53 }
54
Simon Hunt98189192016-07-29 19:02:27 -070055 // ========================== Temporary Code (to be deleted later)
56
57 function request(dir, rid) {
58 wss.sendEvent('topo2navRegion', {
59 dir: dir,
60 rid: rid
61 });
62 }
63
64 function doTmpCurrentLayout(data) {
65 var topdiv = d3.select('#topo2tmp');
66 var parentRegion = data.parent;
67 var span = topdiv.select('.parentRegion').select('span');
68 span.text(parentRegion || '[no parent]');
Steven Burrowsdfa52b02016-09-02 13:50:43 +010069 span.classed('nav-me', Boolean(parentRegion));
Simon Hunt98189192016-07-29 19:02:27 -070070 }
71
72 function doTmpCurrentRegion(data) {
73 var topdiv = d3.select('#topo2tmp');
74 var span = topdiv.select('.thisRegion').select('span');
75 var div;
76
77 span.text(data.id);
78
79 div = topdiv.select('.subRegions').select('div');
80 data.subregions.forEach(function (r) {
81
82 function nav() {
83 request('down', r.id);
84 }
85
86 div.append('p')
87 .classed('nav-me', true)
88 .text(r.id)
89 .on('click', nav);
90 });
91
92 div = topdiv.select('.devices').select('div');
93 data.layerOrder.forEach(function (tag, idx) {
94 var devs = data.devices[idx];
95 devs.forEach(function (d) {
96 div.append('p')
97 .text('[' + tag + '] ' + d.id);
98 });
99
100 });
101
102 div = topdiv.select('.hosts').select('div');
103 data.layerOrder.forEach(function (tag, idx) {
104 var hosts = data.hosts[idx];
105 hosts.forEach(function (h) {
106 div.append('p')
107 .text('[' + tag + '] ' + h.id);
108 });
109 });
110
111 div = topdiv.select('.links').select('div');
112 var links = data.links;
113 links.forEach(function (lnk) {
114 div.append('p')
115 .text(lnk.id);
116 });
117 }
118
119 function doTmpPeerRegions(data) {
120
121 }
122
Simon Huntd5b96732016-07-08 13:22:27 -0700123 // ========================== Event Handlers
124
125 function allInstances(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100126 $log.debug('>> topo2AllInstances event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700127 doTmpCurrentLayout(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100128 t2is.allInstances(data);
Simon Huntd5b96732016-07-08 13:22:27 -0700129 }
130
131 function currentLayout(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100132 $log.debug('>> topo2CurrentLayout event:', data);
Steven Burrowsb43c1a92017-03-07 17:13:28 +0000133 t2rs.clear();
Steven Burrowsaf3159d2016-08-25 14:54:30 +0100134 t2bcs.addBreadcrumb(data.crumbs);
Steven Burrowsb43c1a92017-03-07 17:13:28 +0000135 t2bgs.addLayout(data);
Simon Huntd5b96732016-07-08 13:22:27 -0700136 }
137
138 function currentRegion(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100139 $log.debug('>> topo2CurrentRegion event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700140 doTmpCurrentRegion(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100141 t2rs.addRegion(data);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100142 t2ls.createForceLayout();
Simon Hunt98189192016-07-29 19:02:27 -0700143 }
144
145 function topo2PeerRegions(data) {
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100146 $log.debug('>> topo2PeerRegions event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700147 doTmpPeerRegions(data);
148 }
149
Simon Hunt537bc762016-12-20 12:15:13 -0800150 function modelEvent(data) {
151 $log.debug('>> topo2UiModelEvent event:', data);
Steven Burrows42eb9e22017-02-06 14:20:24 +0000152
Simon Hunt537bc762016-12-20 12:15:13 -0800153 // TODO: Interpret the event and update our topo model state (if needed)
154 // To Decide: Can we assume that the server will only send events
155 // related to objects that we are currently showing?
156 // (e.g. filtered by subregion contents?)
Steven Burrows42eb9e22017-02-06 14:20:24 +0000157 t2rs.update(data);
Simon Hunt537bc762016-12-20 12:15:13 -0800158 }
159
Steven Burrows57e24e92016-08-04 18:38:24 +0100160 function showMastership(masterId) {
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100161 if (masterId) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100162 showMastershipFor(masterId);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100163 } else {
164 restoreLayerState();
Steven Burrows57e24e92016-08-04 18:38:24 +0100165 }
166 }
167
168 function restoreLayerState() {
169 // NOTE: this level of indirection required, for when we have
170 // the layer filter functionality re-implemented
171 suppressLayers(false);
172 }
173
174 // ========================== Main Service Definition
175
176 function showMastershipFor(id) {
177 suppressLayers(true);
178 node.each(function (n) {
179 if (n.master === id) {
180 n.el.classed('suppressedmax', false);
181 }
182 });
183 }
184
185 function supAmt(less) {
186 return less ? 'suppressed' : 'suppressedmax';
187 }
188
189 function suppressLayers(b, less) {
190 var cls = supAmt(less);
191 node.classed(cls, b);
192 // link.classed(cls, b);
193 }
194
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100195 function newDim(_dim_) {
196 dim = _dim_;
197 t2vs.newDim(dim);
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100198 }
199
Simon Huntd5b96732016-07-08 13:22:27 -0700200 // ========================== Main Service Definition
201
Steven Burrows1c5c8612016-10-05 13:45:13 -0500202 function update(elements) {
203 angular.forEach(elements, function (el) {
204 el.update();
205 });
206 }
207
Steven Burrows37549ee2016-09-21 14:41:39 +0100208 function updateNodes() {
Steven Burrows1c5c8612016-10-05 13:45:13 -0500209 update(t2rs.regionNodes());
210 }
211
212 function updateLinks() {
213 update(t2rs.regionLinks());
214 }
215
216 function resetAllLocations() {
217 var nodes = t2rs.regionNodes();
218
219 angular.forEach(nodes, function (node) {
220 node.resetPosition();
221 });
222
223 t2ls.update();
224 t2ls.tick();
225 }
226
227 function unpin() {
228 var hovered = t2rs.filterRegionNodes(function (model) {
229 return model.get('hovered');
230 });
231
232 angular.forEach(hovered, function (model) {
233 model.fixed = false;
234 model.el.classed('fixed', false);
Steven Burrows0616e802016-10-06 21:45:07 -0500235 });
Steven Burrows37549ee2016-09-21 14:41:39 +0100236 }
237
Simon Huntd5b96732016-07-08 13:22:27 -0700238 angular.module('ovTopo2')
Steven Burrowsaf96a212016-12-28 12:57:02 +0000239 .factory('Topo2ForceService', [
240 '$log', 'WebSocketService', 'Topo2InstanceService',
Steven Burrows1c5c8612016-10-05 13:45:13 -0500241 'Topo2RegionService', 'Topo2LayoutService', 'Topo2ViewService',
Steven Burrowsaf96a212016-12-28 12:57:02 +0000242 'Topo2BreadcrumbService', 'Topo2ZoomService', 'Topo2SelectService',
Steven Burrowsb43c1a92017-03-07 17:13:28 +0000243 'Topo2BackgroundService',
Steven Burrows1c5c8612016-10-05 13:45:13 -0500244 function (_$log_, _wss_, _t2is_, _t2rs_, _t2ls_,
Steven Burrowsb43c1a92017-03-07 17:13:28 +0000245 _t2vs_, _t2bcs_, zoomService, _t2ss_, _t2bgs_) {
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100246
Simon Huntd5b96732016-07-08 13:22:27 -0700247 $log = _$log_;
248 wss = _wss_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100249 t2is = _t2is_;
250 t2rs = _t2rs_;
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100251 t2ls = _t2ls_;
252 t2vs = _t2vs_;
Steven Burrowsaf3159d2016-08-25 14:54:30 +0100253 t2bcs = _t2bcs_;
Steven Burrowsaf96a212016-12-28 12:57:02 +0000254 t2ss = _t2ss_;
Steven Burrowsb43c1a92017-03-07 17:13:28 +0000255 t2bgs = _t2bgs_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100256
Steven Burrows0616e802016-10-06 21:45:07 -0500257 var onZoom = function () {
258 var nodes = [].concat(
259 t2rs.regionNodes(),
260 t2rs.regionLinks()
261 );
262
263 angular.forEach(nodes, function (node) {
264 node.setScale();
265 });
266 };
267
268 zoomService.addZoomEventListener(onZoom);
269
Simon Huntd5b96732016-07-08 13:22:27 -0700270 return {
Steven Burrows57e24e92016-08-04 18:38:24 +0100271
Simon Huntd5b96732016-07-08 13:22:27 -0700272 init: init,
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100273 newDim: newDim,
Steven Burrows57e24e92016-08-04 18:38:24 +0100274
Simon Huntd5b96732016-07-08 13:22:27 -0700275 destroy: destroy,
276 topo2AllInstances: allInstances,
277 topo2CurrentLayout: currentLayout,
278 topo2CurrentRegion: currentRegion,
Steven Burrows57e24e92016-08-04 18:38:24 +0100279
Simon Hunt537bc762016-12-20 12:15:13 -0800280 topo2UiModelEvent: modelEvent,
281
Steven Burrows57e24e92016-08-04 18:38:24 +0100282 showMastership: showMastership,
Steven Burrows37549ee2016-09-21 14:41:39 +0100283 topo2PeerRegions: topo2PeerRegions,
284
Steven Burrows1c5c8612016-10-05 13:45:13 -0500285 updateNodes: updateNodes,
286 updateLinks: updateLinks,
287 resetAllLocations: resetAllLocations,
288 unpin: unpin
Simon Huntd5b96732016-07-08 13:22:27 -0700289 };
290 }]);
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100291})();