blob: bbd7f8d465ba561671eb898935f18991bf788081 [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
29 // SVG elements;
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
Steven Burrowsec1f45c2016-08-08 16:14:41 +010063 var $log, wss, t2is, t2rs, t2ls, t2vs;
64 var svg, forceG, uplink, dim, opts;
Simon Huntd5b96732016-07-08 13:22:27 -070065
66 // ========================== Helper Functions
67
Steven Burrowsec1f45c2016-08-08 16:14:41 +010068 function init(_svg_, _forceG_, _uplink_, _dim_, _opts_) {
69 svg = _svg_;
70 forceG = _forceG_;
71 uplink = _uplink_;
72 dim = _dim_;
73 opts = _opts_
Simon Huntd5b96732016-07-08 13:22:27 -070074 }
75
76 function destroy() {
77 $log.debug('Destroy topo force layout');
78 }
79
Simon Hunt98189192016-07-29 19:02:27 -070080 // ========================== Temporary Code (to be deleted later)
81
82 function request(dir, rid) {
83 wss.sendEvent('topo2navRegion', {
84 dir: dir,
85 rid: rid
86 });
87 }
88
89 function doTmpCurrentLayout(data) {
90 var topdiv = d3.select('#topo2tmp');
91 var parentRegion = data.parent;
92 var span = topdiv.select('.parentRegion').select('span');
93 span.text(parentRegion || '[no parent]');
94 span.classed('nav-me', !!parentRegion);
95 }
96
97 function doTmpCurrentRegion(data) {
98 var topdiv = d3.select('#topo2tmp');
99 var span = topdiv.select('.thisRegion').select('span');
100 var div;
101
102 span.text(data.id);
103
104 div = topdiv.select('.subRegions').select('div');
105 data.subregions.forEach(function (r) {
106
107 function nav() {
108 request('down', r.id);
109 }
110
111 div.append('p')
112 .classed('nav-me', true)
113 .text(r.id)
114 .on('click', nav);
115 });
116
117 div = topdiv.select('.devices').select('div');
118 data.layerOrder.forEach(function (tag, idx) {
119 var devs = data.devices[idx];
120 devs.forEach(function (d) {
121 div.append('p')
122 .text('[' + tag + '] ' + d.id);
123 });
124
125 });
126
127 div = topdiv.select('.hosts').select('div');
128 data.layerOrder.forEach(function (tag, idx) {
129 var hosts = data.hosts[idx];
130 hosts.forEach(function (h) {
131 div.append('p')
132 .text('[' + tag + '] ' + h.id);
133 });
134 });
135
136 div = topdiv.select('.links').select('div');
137 var links = data.links;
138 links.forEach(function (lnk) {
139 div.append('p')
140 .text(lnk.id);
141 });
142 }
143
144 function doTmpPeerRegions(data) {
145
146 }
147
Simon Huntd5b96732016-07-08 13:22:27 -0700148 // ========================== Event Handlers
149
150 function allInstances(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100151 $log.debug('>> topo2AllInstances event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700152 doTmpCurrentLayout(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100153 t2is.allInstances(data);
Simon Huntd5b96732016-07-08 13:22:27 -0700154 }
155
156 function currentLayout(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100157 $log.debug('>> topo2CurrentLayout event:', data);
Simon Huntd5b96732016-07-08 13:22:27 -0700158 }
159
160 function currentRegion(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100161 $log.debug('>> topo2CurrentRegion event:', data);
Simon Hunt98189192016-07-29 19:02:27 -0700162 doTmpCurrentRegion(data);
Steven Burrows57e24e92016-08-04 18:38:24 +0100163 t2rs.addRegion(data);
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100164 t2ls.init(svg, forceG, uplink, dim, opts);
165 t2ls.update();
166 t2ls.start();
Simon Hunt98189192016-07-29 19:02:27 -0700167 }
168
169 function topo2PeerRegions(data) {
170 $log.debug('>> topo2PeerRegions event:', data)
171 doTmpPeerRegions(data);
172 }
173
174 function topo2PeerRegions(data) {
175 $log.debug('>> topo2PeerRegions event:', data)
Simon Huntd5b96732016-07-08 13:22:27 -0700176 }
177
178 function startDone(data) {
Steven Burrows57e24e92016-08-04 18:38:24 +0100179 $log.debug('>> topo2StartDone event:', data);
Simon Huntd5b96732016-07-08 13:22:27 -0700180 }
Steven Burrows57e24e92016-08-04 18:38:24 +0100181
182
183 function showMastership(masterId) {
184 if (!masterId) {
185 restoreLayerState();
186 } else {
187 showMastershipFor(masterId);
188 }
189 }
190
191 function restoreLayerState() {
192 // NOTE: this level of indirection required, for when we have
193 // the layer filter functionality re-implemented
194 suppressLayers(false);
195 }
196
197 // ========================== Main Service Definition
198
199 function showMastershipFor(id) {
200 suppressLayers(true);
201 node.each(function (n) {
202 if (n.master === id) {
203 n.el.classed('suppressedmax', false);
204 }
205 });
206 }
207
208 function supAmt(less) {
209 return less ? 'suppressed' : 'suppressedmax';
210 }
211
212 function suppressLayers(b, less) {
213 var cls = supAmt(less);
214 node.classed(cls, b);
215 // link.classed(cls, b);
216 }
217
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100218 function newDim(_dim_) {
219 dim = _dim_;
220 t2vs.newDim(dim);
221 // force.size(dim);
222 // tms.newDim(dim);
223 t2ls.setDimensions();
224 }
225
226 function getDim() {
227 return dim;
228 }
229
Simon Huntd5b96732016-07-08 13:22:27 -0700230 // ========================== Main Service Definition
231
232 angular.module('ovTopo2')
233 .factory('Topo2ForceService',
Steven Burrows57e24e92016-08-04 18:38:24 +0100234 ['$log', 'WebSocketService', 'Topo2InstanceService', 'Topo2RegionService',
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100235 'Topo2LayoutService', 'Topo2ViewService',
236 function (_$log_, _wss_, _t2is_, _t2rs_, _t2ls_, _t2vs_) {
237
Simon Huntd5b96732016-07-08 13:22:27 -0700238 $log = _$log_;
239 wss = _wss_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100240 t2is = _t2is_;
241 t2rs = _t2rs_;
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100242 t2ls = _t2ls_;
243 t2vs = _t2vs_;
Steven Burrows57e24e92016-08-04 18:38:24 +0100244
Simon Huntd5b96732016-07-08 13:22:27 -0700245 return {
Steven Burrows57e24e92016-08-04 18:38:24 +0100246
Simon Huntd5b96732016-07-08 13:22:27 -0700247 init: init,
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100248 newDim: newDim,
Steven Burrows57e24e92016-08-04 18:38:24 +0100249
Simon Huntd5b96732016-07-08 13:22:27 -0700250 destroy: destroy,
251 topo2AllInstances: allInstances,
252 topo2CurrentLayout: currentLayout,
253 topo2CurrentRegion: currentRegion,
Steven Burrows57e24e92016-08-04 18:38:24 +0100254 topo2StartDone: startDone,
255
256 showMastership: showMastership,
257 topo2PeerRegions: topo2PeerRegions
Simon Huntd5b96732016-07-08 13:22:27 -0700258 };
259 }]);
260}());