GUI -- TopoView - Migrated more helper functions to topoModel.js.
Change-Id: I902c3561210c46fd23c6f6f01323d003dacefc19
Showing
5 changed files
with
217 additions
and
169 deletions
... | @@ -61,7 +61,7 @@ | ... | @@ -61,7 +61,7 @@ |
61 | eh = api[eid]; | 61 | eh = api[eid]; |
62 | 62 | ||
63 | if (eh) { | 63 | if (eh) { |
64 | - $log.debug(' *EVENT* ', ev.payload); | 64 | + $log.debug(' *EVENT* ', eid, ev.payload); |
65 | eh(ev.payload); | 65 | eh(ev.payload); |
66 | } else { | 66 | } else { |
67 | $log.warn('Unknown event (ignored):', ev); | 67 | $log.warn('Unknown event (ignored):', ev); | ... | ... |
... | @@ -70,6 +70,7 @@ | ... | @@ -70,6 +70,7 @@ |
70 | revLinkToKey: {} | 70 | revLinkToKey: {} |
71 | }, | 71 | }, |
72 | lu = network.lookup, // shorthand | 72 | lu = network.lookup, // shorthand |
73 | + rlk = network.revLinkToKey, | ||
73 | deviceLabelIndex = 0, // for device label cycling | 74 | deviceLabelIndex = 0, // for device label cycling |
74 | hostLabelIndex = 0, // for host label cycling | 75 | hostLabelIndex = 0, // for host label cycling |
75 | showHosts = true, // whether hosts are displayed | 76 | showHosts = true, // whether hosts are displayed |
... | @@ -134,9 +135,6 @@ | ... | @@ -134,9 +135,6 @@ |
134 | d = tms.createDeviceNode(data); | 135 | d = tms.createDeviceNode(data); |
135 | network.nodes.push(d); | 136 | network.nodes.push(d); |
136 | lu[id] = d; | 137 | lu[id] = d; |
137 | - | ||
138 | - $log.debug("Created new device.. ", d.id, d.x, d.y); | ||
139 | - | ||
140 | updateNodes(); | 138 | updateNodes(); |
141 | fStart(); | 139 | fStart(); |
142 | } | 140 | } |
... | @@ -154,7 +152,7 @@ | ... | @@ -154,7 +152,7 @@ |
154 | } | 152 | } |
155 | updateNodes(); | 153 | updateNodes(); |
156 | if (wasOnline !== d.online) { | 154 | if (wasOnline !== d.online) { |
157 | - findAttachedLinks(d.id).forEach(restyleLinkElement); | 155 | + tms.findAttachedLinks(d.id).forEach(restyleLinkElement); |
158 | updateOfflineVisibility(d); | 156 | updateOfflineVisibility(d); |
159 | } | 157 | } |
160 | } else { | 158 | } else { |
... | @@ -188,16 +186,10 @@ | ... | @@ -188,16 +186,10 @@ |
188 | d = tms.createHostNode(data); | 186 | d = tms.createHostNode(data); |
189 | network.nodes.push(d); | 187 | network.nodes.push(d); |
190 | lu[id] = d; | 188 | lu[id] = d; |
191 | - | ||
192 | - $log.debug("Created new host.. ", d.id, d.x, d.y); | ||
193 | - | ||
194 | updateNodes(); | 189 | updateNodes(); |
195 | 190 | ||
196 | lnk = tms.createHostLink(data); | 191 | lnk = tms.createHostLink(data); |
197 | if (lnk) { | 192 | if (lnk) { |
198 | - | ||
199 | - $log.debug("Created new host-link.. ", lnk.key); | ||
200 | - | ||
201 | d.linkData = lnk; // cache ref on its host | 193 | d.linkData = lnk; // cache ref on its host |
202 | network.links.push(lnk); | 194 | network.links.push(lnk); |
203 | lu[d.ingress] = lnk; | 195 | lu[d.ingress] = lnk; |
... | @@ -235,7 +227,7 @@ | ... | @@ -235,7 +227,7 @@ |
235 | } | 227 | } |
236 | 228 | ||
237 | function addLink(data) { | 229 | function addLink(data) { |
238 | - var result = findLink(data, 'add'), | 230 | + var result = tms.findLink(data, 'add'), |
239 | bad = result.badLogic, | 231 | bad = result.badLogic, |
240 | d = result.ldata; | 232 | d = result.ldata; |
241 | 233 | ||
... | @@ -261,7 +253,7 @@ | ... | @@ -261,7 +253,7 @@ |
261 | } | 253 | } |
262 | 254 | ||
263 | function updateLink(data) { | 255 | function updateLink(data) { |
264 | - var result = findLink(data, 'update'), | 256 | + var result = tms.findLink(data, 'update'), |
265 | bad = result.badLogic; | 257 | bad = result.badLogic; |
266 | if (bad) { | 258 | if (bad) { |
267 | //logicError(bad + ': ' + link.id); | 259 | //logicError(bad + ': ' + link.id); |
... | @@ -271,7 +263,7 @@ | ... | @@ -271,7 +263,7 @@ |
271 | } | 263 | } |
272 | 264 | ||
273 | function removeLink(data) { | 265 | function removeLink(data) { |
274 | - var result = findLink(data, 'remove'), | 266 | + var result = tms.findLink(data, 'remove'), |
275 | bad = result.badLogic; | 267 | bad = result.badLogic; |
276 | if (bad) { | 268 | if (bad) { |
277 | // may have already removed link, if attached to removed device | 269 | // may have already removed link, if attached to removed device |
... | @@ -286,20 +278,10 @@ | ... | @@ -286,20 +278,10 @@ |
286 | function addLinkUpdate(ldata, link) { | 278 | function addLinkUpdate(ldata, link) { |
287 | // add link event, but we already have the reverse link installed | 279 | // add link event, but we already have the reverse link installed |
288 | ldata.fromTarget = link; | 280 | ldata.fromTarget = link; |
289 | - network.revLinkToKey[link.id] = ldata.key; | 281 | + rlk[link.id] = ldata.key; |
290 | restyleLinkElement(ldata); | 282 | restyleLinkElement(ldata); |
291 | } | 283 | } |
292 | 284 | ||
293 | - function makeNodeKey(d, what) { | ||
294 | - var port = what + 'Port'; | ||
295 | - return d[what] + '/' + d[port]; | ||
296 | - } | ||
297 | - | ||
298 | - function makeLinkKey(d, flipped) { | ||
299 | - var one = flipped ? makeNodeKey(d, 'dst') : makeNodeKey(d, 'src'), | ||
300 | - two = flipped ? makeNodeKey(d, 'src') : makeNodeKey(d, 'dst'); | ||
301 | - return one + '-' + two; | ||
302 | - } | ||
303 | 285 | ||
304 | var widthRatio = 1.4, | 286 | var widthRatio = 1.4, |
305 | linkScale = d3.scale.linear() | 287 | linkScale = d3.scale.linear() |
... | @@ -329,113 +311,7 @@ | ... | @@ -329,113 +311,7 @@ |
329 | .attr('stroke', linkConfig[th].baseColor); | 311 | .attr('stroke', linkConfig[th].baseColor); |
330 | } | 312 | } |
331 | 313 | ||
332 | - function findLinkById(id) { | ||
333 | - // check to see if this is a reverse lookup, else default to given id | ||
334 | - var key = network.revLinkToKey[id] || id; | ||
335 | - return key && lu[key]; | ||
336 | - } | ||
337 | 314 | ||
338 | - function findLink(linkData, op) { | ||
339 | - var key = makeLinkKey(linkData), | ||
340 | - keyrev = makeLinkKey(linkData, 1), | ||
341 | - link = lu[key], | ||
342 | - linkRev = lu[keyrev], | ||
343 | - result = {}, | ||
344 | - ldata = link || linkRev, | ||
345 | - rawLink; | ||
346 | - | ||
347 | - if (op === 'add') { | ||
348 | - if (link) { | ||
349 | - // trying to add a link that we already know about | ||
350 | - result.ldata = link; | ||
351 | - result.badLogic = 'addLink: link already added'; | ||
352 | - | ||
353 | - } else if (linkRev) { | ||
354 | - // we found the reverse of the link to be added | ||
355 | - result.ldata = linkRev; | ||
356 | - if (linkRev.fromTarget) { | ||
357 | - result.badLogic = 'addLink: link already added'; | ||
358 | - } | ||
359 | - } | ||
360 | - } else if (op === 'update') { | ||
361 | - if (!ldata) { | ||
362 | - result.badLogic = 'updateLink: link not found'; | ||
363 | - } else { | ||
364 | - rawLink = link ? ldata.fromSource : ldata.fromTarget; | ||
365 | - result.updateWith = function (data) { | ||
366 | - angular.extend(rawLink, data); | ||
367 | - restyleLinkElement(ldata); | ||
368 | - } | ||
369 | - } | ||
370 | - } else if (op === 'remove') { | ||
371 | - if (!ldata) { | ||
372 | - result.badLogic = 'removeLink: link not found'; | ||
373 | - } else { | ||
374 | - rawLink = link ? ldata.fromSource : ldata.fromTarget; | ||
375 | - | ||
376 | - if (!rawLink) { | ||
377 | - result.badLogic = 'removeLink: link not found'; | ||
378 | - | ||
379 | - } else { | ||
380 | - result.removeRawLink = function () { | ||
381 | - if (link) { | ||
382 | - // remove fromSource | ||
383 | - ldata.fromSource = null; | ||
384 | - if (ldata.fromTarget) { | ||
385 | - // promote target into source position | ||
386 | - ldata.fromSource = ldata.fromTarget; | ||
387 | - ldata.fromTarget = null; | ||
388 | - ldata.key = keyrev; | ||
389 | - delete network.lookup[key]; | ||
390 | - network.lookup[keyrev] = ldata; | ||
391 | - delete network.revLinkToKey[keyrev]; | ||
392 | - } | ||
393 | - } else { | ||
394 | - // remove fromTarget | ||
395 | - ldata.fromTarget = null; | ||
396 | - delete network.revLinkToKey[keyrev]; | ||
397 | - } | ||
398 | - if (ldata.fromSource) { | ||
399 | - restyleLinkElement(ldata); | ||
400 | - } else { | ||
401 | - removeLinkElement(ldata); | ||
402 | - } | ||
403 | - } | ||
404 | - } | ||
405 | - } | ||
406 | - } | ||
407 | - return result; | ||
408 | - } | ||
409 | - | ||
410 | - function findDevices(offlineOnly) { | ||
411 | - var a = []; | ||
412 | - network.nodes.forEach(function (d) { | ||
413 | - if (d.class === 'device' && !(offlineOnly && d.online)) { | ||
414 | - a.push(d); | ||
415 | - } | ||
416 | - }); | ||
417 | - return a; | ||
418 | - } | ||
419 | - | ||
420 | - function findAttachedHosts(devId) { | ||
421 | - var hosts = []; | ||
422 | - network.nodes.forEach(function (d) { | ||
423 | - if (d.class === 'host' && d.cp.device === devId) { | ||
424 | - hosts.push(d); | ||
425 | - } | ||
426 | - }); | ||
427 | - return hosts; | ||
428 | - } | ||
429 | - | ||
430 | - function findAttachedLinks(devId) { | ||
431 | - var links = []; | ||
432 | - network.links.forEach(function (d) { | ||
433 | - if (d.source.id === devId || d.target.id === devId) { | ||
434 | - links.push(d); | ||
435 | - } | ||
436 | - }); | ||
437 | - return links; | ||
438 | - } | ||
439 | 315 | ||
440 | function removeLinkElement(d) { | 316 | function removeLinkElement(d) { |
441 | var idx = fs.find(d.key, network.links, 'key'), | 317 | var idx = fs.find(d.key, network.links, 'key'), |
... | @@ -475,8 +351,8 @@ | ... | @@ -475,8 +351,8 @@ |
475 | function removeDeviceElement(d) { | 351 | function removeDeviceElement(d) { |
476 | var id = d.id; | 352 | var id = d.id; |
477 | // first, remove associated hosts and links.. | 353 | // first, remove associated hosts and links.. |
478 | - findAttachedHosts(id).forEach(removeHostElement); | 354 | + tms.findAttachedHosts(id).forEach(removeHostElement); |
479 | - findAttachedLinks(id).forEach(removeLinkElement); | 355 | + tms.findAttachedLinks(id).forEach(removeLinkElement); |
480 | 356 | ||
481 | // remove from lookup cache | 357 | // remove from lookup cache |
482 | delete lu[id]; | 358 | delete lu[id]; |
... | @@ -485,7 +361,7 @@ | ... | @@ -485,7 +361,7 @@ |
485 | network.nodes.splice(idx, 1); | 361 | network.nodes.splice(idx, 1); |
486 | 362 | ||
487 | if (!network.nodes.length) { | 363 | if (!network.nodes.length) { |
488 | - xlink.showNoDevs(true); | 364 | + uplink.showNoDevs(true); |
489 | } | 365 | } |
490 | 366 | ||
491 | // remove from SVG | 367 | // remove from SVG |
... | @@ -502,11 +378,11 @@ | ... | @@ -502,11 +378,11 @@ |
502 | function updDev(d, show) { | 378 | function updDev(d, show) { |
503 | sus.makeVisible(d.el, show); | 379 | sus.makeVisible(d.el, show); |
504 | 380 | ||
505 | - findAttachedLinks(d.id).forEach(function (link) { | 381 | + tms.findAttachedLinks(d.id).forEach(function (link) { |
506 | b = show && ((link.type() !== 'hostLink') || showHosts); | 382 | b = show && ((link.type() !== 'hostLink') || showHosts); |
507 | sus.makeVisible(link.el, b); | 383 | sus.makeVisible(link.el, b); |
508 | }); | 384 | }); |
509 | - findAttachedHosts(d.id).forEach(function (host) { | 385 | + tms.findAttachedHosts(d.id).forEach(function (host) { |
510 | b = show && showHosts; | 386 | b = show && showHosts; |
511 | sus.makeVisible(host.el, b); | 387 | sus.makeVisible(host.el, b); |
512 | }); | 388 | }); |
... | @@ -517,7 +393,7 @@ | ... | @@ -517,7 +393,7 @@ |
517 | updDev(dev, dev.online || showOffline); | 393 | updDev(dev, dev.online || showOffline); |
518 | } else { | 394 | } else { |
519 | // updating all offline devices | 395 | // updating all offline devices |
520 | - findDevices(true).forEach(function (d) { | 396 | + tms.findDevices(true).forEach(function (d) { |
521 | updDev(d, showOffline); | 397 | updDev(d, showOffline); |
522 | }); | 398 | }); |
523 | } | 399 | } |
... | @@ -532,12 +408,7 @@ | ... | @@ -532,12 +408,7 @@ |
532 | // attach the x, y, longitude, latitude... | 408 | // attach the x, y, longitude, latitude... |
533 | if (!clearPos) { | 409 | if (!clearPos) { |
534 | ll = tms.lngLatFromCoord([d.x, d.y]); | 410 | ll = tms.lngLatFromCoord([d.x, d.y]); |
535 | - metaUi = { | 411 | + metaUi = {x: d.x, y: d.y, lng: ll[0], lat: ll[1]}; |
536 | - x: d.x, | ||
537 | - y: d.y, | ||
538 | - lng: ll[0], | ||
539 | - lat: ll[1] | ||
540 | - }; | ||
541 | } | 412 | } |
542 | d.metaUi = metaUi; | 413 | d.metaUi = metaUi; |
543 | uplink.sendEvent('updateMeta', { | 414 | uplink.sendEvent('updateMeta', { |
... | @@ -691,7 +562,7 @@ | ... | @@ -691,7 +562,7 @@ |
691 | 562 | ||
692 | function cycleDeviceLabels() { | 563 | function cycleDeviceLabels() { |
693 | deviceLabelIndex = (deviceLabelIndex+1) % 3; | 564 | deviceLabelIndex = (deviceLabelIndex+1) % 3; |
694 | - findDevices().forEach(function (d) { | 565 | + tms.findDevices().forEach(function (d) { |
695 | updateDeviceLabel(d); | 566 | updateDeviceLabel(d); |
696 | }); | 567 | }); |
697 | } | 568 | } |
... | @@ -1107,7 +978,7 @@ | ... | @@ -1107,7 +978,7 @@ |
1107 | }, | 978 | }, |
1108 | linkLabelAttr: { | 979 | linkLabelAttr: { |
1109 | transform: function (d) { | 980 | transform: function (d) { |
1110 | - var lnk = findLinkById(d.key); | 981 | + var lnk = tms.findLinkById(d.key); |
1111 | if (lnk) { | 982 | if (lnk) { |
1112 | return transformLabel({ | 983 | return transformLabel({ |
1113 | x1: lnk.source.x, | 984 | x1: lnk.source.x, |
... | @@ -1223,6 +1094,15 @@ | ... | @@ -1223,6 +1094,15 @@ |
1223 | // ========================== | 1094 | // ========================== |
1224 | // Module definition | 1095 | // Module definition |
1225 | 1096 | ||
1097 | + function mkModelApi(uplink) { | ||
1098 | + return { | ||
1099 | + projection: uplink.projection, | ||
1100 | + network: network, | ||
1101 | + restyleLinkElement: restyleLinkElement, | ||
1102 | + removeLinkElement: removeLinkElement | ||
1103 | + }; | ||
1104 | + } | ||
1105 | + | ||
1226 | angular.module('ovTopo') | 1106 | angular.module('ovTopo') |
1227 | .factory('TopoForceService', | 1107 | .factory('TopoForceService', |
1228 | ['$log', 'FnService', 'SvgUtilService', 'IconService', 'ThemeService', | 1108 | ['$log', 'FnService', 'SvgUtilService', 'IconService', 'ThemeService', |
... | @@ -1241,7 +1121,7 @@ | ... | @@ -1241,7 +1121,7 @@ |
1241 | icfg = is.iconConfig(); | 1121 | icfg = is.iconConfig(); |
1242 | 1122 | ||
1243 | // forceG is the SVG group to display the force layout in | 1123 | // forceG is the SVG group to display the force layout in |
1244 | - // xlink is the cross-link api from the main topo source file | 1124 | + // uplink is the api from the main topo source file |
1245 | // dim is the initial dimensions of the SVG as [w,h] | 1125 | // dim is the initial dimensions of the SVG as [w,h] |
1246 | // opts are, well, optional :) | 1126 | // opts are, well, optional :) |
1247 | function initForce(forceG, _uplink_, _dim_, opts) { | 1127 | function initForce(forceG, _uplink_, _dim_, opts) { |
... | @@ -1250,10 +1130,7 @@ | ... | @@ -1250,10 +1130,7 @@ |
1250 | 1130 | ||
1251 | $log.debug('initForce().. dim = ' + dim); | 1131 | $log.debug('initForce().. dim = ' + dim); |
1252 | 1132 | ||
1253 | - tms.initModel({ | 1133 | + tms.initModel(mkModelApi(uplink), dim); |
1254 | - projection: uplink.projection, | ||
1255 | - lookup: network.lookup | ||
1256 | - }, dim); | ||
1257 | 1134 | ||
1258 | settings = angular.extend({}, defaultSettings, opts); | 1135 | settings = angular.extend({}, defaultSettings, opts); |
1259 | 1136 | ... | ... |
... | @@ -26,6 +26,15 @@ | ... | @@ -26,6 +26,15 @@ |
26 | // injected refs | 26 | // injected refs |
27 | var $log, fs, rnd, api; | 27 | var $log, fs, rnd, api; |
28 | 28 | ||
29 | + // shorthand | ||
30 | + var lu, rlk, nodes, links; | ||
31 | + | ||
32 | + // api: | ||
33 | + // projection: func() | ||
34 | + // network {...} | ||
35 | + // restyleLinkElement: func(ldata) | ||
36 | + // removeLinkElement: func(ldata) | ||
37 | + | ||
29 | var dim; // dimensions of layout, as [w,h] | 38 | var dim; // dimensions of layout, as [w,h] |
30 | 39 | ||
31 | // configuration 'constants' | 40 | // configuration 'constants' |
... | @@ -95,7 +104,7 @@ | ... | @@ -95,7 +104,7 @@ |
95 | } | 104 | } |
96 | 105 | ||
97 | function getDevice(cp) { | 106 | function getDevice(cp) { |
98 | - var d = api.lookup[cp.device]; | 107 | + var d = lu[cp.device]; |
99 | return d || rand(); | 108 | return d || rand(); |
100 | } | 109 | } |
101 | 110 | ||
... | @@ -194,8 +203,8 @@ | ... | @@ -194,8 +203,8 @@ |
194 | 203 | ||
195 | 204 | ||
196 | function linkEndPoints(srcId, dstId) { | 205 | function linkEndPoints(srcId, dstId) { |
197 | - var srcNode = api.lookup[srcId], | 206 | + var srcNode = lu[srcId], |
198 | - dstNode = api.lookup[dstId], | 207 | + dstNode = lu[dstId], |
199 | sMiss = !srcNode ? missMsg('src', srcId) : '', | 208 | sMiss = !srcNode ? missMsg('src', srcId) : '', |
200 | dMiss = !dstNode ? missMsg('dst', dstId) : ''; | 209 | dMiss = !dstNode ? missMsg('dst', dstId) : ''; |
201 | 210 | ||
... | @@ -218,6 +227,127 @@ | ... | @@ -218,6 +227,127 @@ |
218 | return '\n[' + what + '] "' + id + '" missing'; | 227 | return '\n[' + what + '] "' + id + '" missing'; |
219 | } | 228 | } |
220 | 229 | ||
230 | + | ||
231 | + function makeNodeKey(d, what) { | ||
232 | + var port = what + 'Port'; | ||
233 | + return d[what] + '/' + d[port]; | ||
234 | + } | ||
235 | + | ||
236 | + function makeLinkKey(d, flipped) { | ||
237 | + var one = flipped ? makeNodeKey(d, 'dst') : makeNodeKey(d, 'src'), | ||
238 | + two = flipped ? makeNodeKey(d, 'src') : makeNodeKey(d, 'dst'); | ||
239 | + return one + '-' + two; | ||
240 | + } | ||
241 | + | ||
242 | + function findLinkById(id) { | ||
243 | + // check to see if this is a reverse lookup, else default to given id | ||
244 | + var key = rlk[id] || id; | ||
245 | + return key && lu[key]; | ||
246 | + } | ||
247 | + | ||
248 | + function findLink(linkData, op) { | ||
249 | + var key = makeLinkKey(linkData), | ||
250 | + keyrev = makeLinkKey(linkData, 1), | ||
251 | + link = lu[key], | ||
252 | + linkRev = lu[keyrev], | ||
253 | + result = {}, | ||
254 | + ldata = link || linkRev, | ||
255 | + rawLink; | ||
256 | + | ||
257 | + if (op === 'add') { | ||
258 | + if (link) { | ||
259 | + // trying to add a link that we already know about | ||
260 | + result.ldata = link; | ||
261 | + result.badLogic = 'addLink: link already added'; | ||
262 | + | ||
263 | + } else if (linkRev) { | ||
264 | + // we found the reverse of the link to be added | ||
265 | + result.ldata = linkRev; | ||
266 | + if (linkRev.fromTarget) { | ||
267 | + result.badLogic = 'addLink: link already added'; | ||
268 | + } | ||
269 | + } | ||
270 | + } else if (op === 'update') { | ||
271 | + if (!ldata) { | ||
272 | + result.badLogic = 'updateLink: link not found'; | ||
273 | + } else { | ||
274 | + rawLink = link ? ldata.fromSource : ldata.fromTarget; | ||
275 | + result.updateWith = function (data) { | ||
276 | + angular.extend(rawLink, data); | ||
277 | + api.restyleLinkElement(ldata); | ||
278 | + } | ||
279 | + } | ||
280 | + } else if (op === 'remove') { | ||
281 | + if (!ldata) { | ||
282 | + result.badLogic = 'removeLink: link not found'; | ||
283 | + } else { | ||
284 | + rawLink = link ? ldata.fromSource : ldata.fromTarget; | ||
285 | + | ||
286 | + if (!rawLink) { | ||
287 | + result.badLogic = 'removeLink: link not found'; | ||
288 | + | ||
289 | + } else { | ||
290 | + result.removeRawLink = function () { | ||
291 | + if (link) { | ||
292 | + // remove fromSource | ||
293 | + ldata.fromSource = null; | ||
294 | + if (ldata.fromTarget) { | ||
295 | + // promote target into source position | ||
296 | + ldata.fromSource = ldata.fromTarget; | ||
297 | + ldata.fromTarget = null; | ||
298 | + ldata.key = keyrev; | ||
299 | + delete lu[key]; | ||
300 | + lu[keyrev] = ldata; | ||
301 | + delete rlk[keyrev]; | ||
302 | + } | ||
303 | + } else { | ||
304 | + // remove fromTarget | ||
305 | + ldata.fromTarget = null; | ||
306 | + delete rlk[keyrev]; | ||
307 | + } | ||
308 | + if (ldata.fromSource) { | ||
309 | + api.restyleLinkElement(ldata); | ||
310 | + } else { | ||
311 | + api.removeLinkElement(ldata); | ||
312 | + } | ||
313 | + } | ||
314 | + } | ||
315 | + } | ||
316 | + } | ||
317 | + return result; | ||
318 | + } | ||
319 | + | ||
320 | + function findDevices(offlineOnly) { | ||
321 | + var a = []; | ||
322 | + nodes.forEach(function (d) { | ||
323 | + if (d.class === 'device' && !(offlineOnly && d.online)) { | ||
324 | + a.push(d); | ||
325 | + } | ||
326 | + }); | ||
327 | + return a; | ||
328 | + } | ||
329 | + | ||
330 | + function findAttachedHosts(devId) { | ||
331 | + var hosts = []; | ||
332 | + nodes.forEach(function (d) { | ||
333 | + if (d.class === 'host' && d.cp.device === devId) { | ||
334 | + hosts.push(d); | ||
335 | + } | ||
336 | + }); | ||
337 | + return hosts; | ||
338 | + } | ||
339 | + | ||
340 | + function findAttachedLinks(devId) { | ||
341 | + var links = []; | ||
342 | + links.forEach(function (d) { | ||
343 | + if (d.source.id === devId || d.target.id === devId) { | ||
344 | + links.push(d); | ||
345 | + } | ||
346 | + }); | ||
347 | + return links; | ||
348 | + } | ||
349 | + | ||
350 | + | ||
221 | // ========================== | 351 | // ========================== |
222 | // Module definition | 352 | // Module definition |
223 | 353 | ||
... | @@ -233,6 +363,10 @@ | ... | @@ -233,6 +363,10 @@ |
233 | function initModel(_api_, _dim_) { | 363 | function initModel(_api_, _dim_) { |
234 | api = _api_; | 364 | api = _api_; |
235 | dim = _dim_; | 365 | dim = _dim_; |
366 | + lu = api.network.lookup; | ||
367 | + rlk = api.network.revLinkToKey; | ||
368 | + nodes = api.network.nodes; | ||
369 | + links = api.network.links; | ||
236 | } | 370 | } |
237 | 371 | ||
238 | function newDim(_dim_) { | 372 | function newDim(_dim_) { |
... | @@ -250,6 +384,11 @@ | ... | @@ -250,6 +384,11 @@ |
250 | createLink: createLink, | 384 | createLink: createLink, |
251 | coordFromLngLat: coordFromLngLat, | 385 | coordFromLngLat: coordFromLngLat, |
252 | lngLatFromCoord: lngLatFromCoord, | 386 | lngLatFromCoord: lngLatFromCoord, |
387 | + findLink: findLink, | ||
388 | + findLinkById: findLinkById, | ||
389 | + findDevices: findDevices, | ||
390 | + findAttachedHosts: findAttachedHosts, | ||
391 | + findAttachedLinks: findAttachedLinks | ||
253 | } | 392 | } |
254 | }]); | 393 | }]); |
255 | }()); | 394 | }()); | ... | ... |
... | @@ -45,23 +45,22 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -45,23 +45,22 @@ describe('factory: view/topo/topoModel.js', function() { |
45 | return [xy[0] + 2000, xy[1] + 3000]; | 45 | return [xy[0] + 2000, xy[1] + 3000]; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | - // our test device lookup | 48 | + // our test devices and hosts: |
49 | - var lu = { | 49 | + var dev1 = { |
50 | - dev1: { | ||
51 | 'class': 'device', | 50 | 'class': 'device', |
52 | id: 'dev1', | 51 | id: 'dev1', |
53 | x: 17, | 52 | x: 17, |
54 | y: 27, | 53 | y: 27, |
55 | online: true | 54 | online: true |
56 | }, | 55 | }, |
57 | - dev2: { | 56 | + dev2 = { |
58 | 'class': 'device', | 57 | 'class': 'device', |
59 | id: 'dev2', | 58 | id: 'dev2', |
60 | x: 18, | 59 | x: 18, |
61 | y: 28, | 60 | y: 28, |
62 | online: true | 61 | online: true |
63 | }, | 62 | }, |
64 | - host1: { | 63 | + host1 = { |
65 | 'class': 'host', | 64 | 'class': 'host', |
66 | id: 'host1', | 65 | id: 'host1', |
67 | x: 23, | 66 | x: 23, |
... | @@ -72,7 +71,7 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -72,7 +71,7 @@ describe('factory: view/topo/topoModel.js', function() { |
72 | }, | 71 | }, |
73 | ingress: 'dev1/7-host1' | 72 | ingress: 'dev1/7-host1' |
74 | }, | 73 | }, |
75 | - host2: { | 74 | + host2 = { |
76 | 'class': 'host', | 75 | 'class': 'host', |
77 | id: 'host2', | 76 | id: 'host2', |
78 | x: 24, | 77 | x: 24, |
... | @@ -82,13 +81,20 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -82,13 +81,20 @@ describe('factory: view/topo/topoModel.js', function() { |
82 | port: 0 | 81 | port: 0 |
83 | }, | 82 | }, |
84 | ingress: 'dev0/0-host2' | 83 | ingress: 'dev0/0-host2' |
85 | - } | 84 | + }; |
86 | - }; | 85 | + |
87 | 86 | ||
88 | // our test api | 87 | // our test api |
89 | var api = { | 88 | var api = { |
90 | projection: function () { return mockProjection; }, | 89 | projection: function () { return mockProjection; }, |
91 | - lookup: lu | 90 | + network: { |
91 | + nodes: [dev1, dev2, host1, host2], | ||
92 | + links: [], | ||
93 | + lookup: {dev1: dev1, dev2: dev2, host1: host1, host2: host2}, | ||
94 | + revLinkToKey: {} | ||
95 | + }, | ||
96 | + restyleLinkElement: function () {}, | ||
97 | + removeLinkElement: function () {} | ||
92 | }; | 98 | }; |
93 | 99 | ||
94 | // our test dimensions and well known locations.. | 100 | // our test dimensions and well known locations.. |
... | @@ -204,7 +210,9 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -204,7 +210,9 @@ describe('factory: view/topo/topoModel.js', function() { |
204 | 'initModel', 'newDim', | 210 | 'initModel', 'newDim', |
205 | 'positionNode', 'createDeviceNode', 'createHostNode', | 211 | 'positionNode', 'createDeviceNode', 'createHostNode', |
206 | 'createHostLink', 'createLink', | 212 | 'createHostLink', 'createLink', |
207 | - 'coordFromLngLat', 'lngLatFromCoord' | 213 | + 'coordFromLngLat', 'lngLatFromCoord', |
214 | + 'findLink', 'findLinkById', 'findDevices', | ||
215 | + 'findAttachedHosts', 'findAttachedLinks' | ||
208 | ])).toBeTruthy(); | 216 | ])).toBeTruthy(); |
209 | }); | 217 | }); |
210 | 218 | ||
... | @@ -348,9 +356,9 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -348,9 +356,9 @@ describe('factory: view/topo/topoModel.js', function() { |
348 | // === unit tests for createHostLink() | 356 | // === unit tests for createHostLink() |
349 | 357 | ||
350 | it('should create a basic host link', function () { | 358 | it('should create a basic host link', function () { |
351 | - var link = tms.createHostLink(lu.host1); | 359 | + var link = tms.createHostLink(host1); |
352 | - expect(link.source).toEqual(lu.host1); | 360 | + expect(link.source).toEqual(host1); |
353 | - expect(link.target).toEqual(lu.dev1); | 361 | + expect(link.target).toEqual(dev1); |
354 | expect(link).toHaveEndPoints(host1Loc, dev1Loc); | 362 | expect(link).toHaveEndPoints(host1Loc, dev1Loc); |
355 | expect(link.key).toEqual('dev1/7-host1'); | 363 | expect(link.key).toEqual('dev1/7-host1'); |
356 | expect(link.class).toEqual('link'); | 364 | expect(link.class).toEqual('link'); |
... | @@ -361,7 +369,7 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -361,7 +369,7 @@ describe('factory: view/topo/topoModel.js', function() { |
361 | 369 | ||
362 | it('should return null for failed endpoint lookup', function () { | 370 | it('should return null for failed endpoint lookup', function () { |
363 | spyOn($log, 'error'); | 371 | spyOn($log, 'error'); |
364 | - var link = tms.createHostLink(lu.host2); | 372 | + var link = tms.createHostLink(host2); |
365 | expect(link).toBeNull(); | 373 | expect(link).toBeNull(); |
366 | expect($log.error).toHaveBeenCalledWith( | 374 | expect($log.error).toHaveBeenCalledWith( |
367 | 'Node(s) not on map for link:\n[dst] "dev0" missing' | 375 | 'Node(s) not on map for link:\n[dst] "dev0" missing' |
... | @@ -389,8 +397,8 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -389,8 +397,8 @@ describe('factory: view/topo/topoModel.js', function() { |
389 | linkWidth: 1.5 | 397 | linkWidth: 1.5 |
390 | }, | 398 | }, |
391 | link = tms.createLink(linkData); | 399 | link = tms.createLink(linkData); |
392 | - expect(link.source).toEqual(lu.dev1); | 400 | + expect(link.source).toEqual(dev1); |
393 | - expect(link.target).toEqual(lu.dev2); | 401 | + expect(link.target).toEqual(dev2); |
394 | expect(link).toHaveEndPoints(dev1Loc, dev2Loc); | 402 | expect(link).toHaveEndPoints(dev1Loc, dev2Loc); |
395 | expect(link.key).toEqual('baz'); | 403 | expect(link.key).toEqual('baz'); |
396 | expect(link.class).toEqual('link'); | 404 | expect(link.class).toEqual('link'); |
... | @@ -400,4 +408,5 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -400,4 +408,5 @@ describe('factory: view/topo/topoModel.js', function() { |
400 | expect(link.linkWidth()).toEqual(1.5); | 408 | expect(link.linkWidth()).toEqual(1.5); |
401 | }); | 409 | }); |
402 | 410 | ||
411 | + // TODO: more unit tests for additional functions.... | ||
403 | }); | 412 | }); | ... | ... |
1 | +{ | ||
2 | + "event": "removeDevice", | ||
3 | + "payload": { | ||
4 | + "id": "of:0000ffffffff0008", | ||
5 | + "type": "switch", | ||
6 | + "online": false, | ||
7 | + "master": "myInstA", | ||
8 | + "location": { | ||
9 | + "type": "latlng", | ||
10 | + "lat": 37.7833, | ||
11 | + "lng": -122.4167 | ||
12 | + }, | ||
13 | + "labels": [ | ||
14 | + "", | ||
15 | + "sw-8", | ||
16 | + "0000ffffffff0008" | ||
17 | + ], | ||
18 | + "metaUi": { | ||
19 | + "x": 520, | ||
20 | + "y": 350 | ||
21 | + } | ||
22 | + } | ||
23 | +} |
-
Please register or login to post a comment