blob: aeac6d48e95a838e686b331068b60051e918cd7e [file] [log] [blame]
Steven Burrows1c5c8612016-10-05 13:45:13 -05001/*
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 Node Position Module.
19 Module that helps position nodes in the topology
20 */
21
22(function () {
23 'use strict';
24
25 // Injected vars
Steven Burrows3db5ddb2017-02-17 15:21:20 +000026 var rs, t2mcs, t2sls;
Steven Burrows1c5c8612016-10-05 13:45:13 -050027
28 // Internal state;
29 var nearDist = 15;
30
31 function positionNode(node, forUpdate) {
32 var meta = node.get('metaUi'),
33 x = meta && meta.x,
34 y = meta && meta.y,
35 dim = [800, 600],
36 xy;
37
38 // If the device contains explicit LONG/LAT data, use that to position
39 if (setLongLat(node)) {
40 // Indicate we want to update cached meta data...
41 return true;
42 }
43
44 // else if we have [x,y] cached in meta data, use that...
45 if (x !== undefined && y !== undefined) {
46 node.fixed = true;
47 node.px = node.x = x;
48 node.py = node.y = y;
49 return;
50 }
51
52 // if this is a node update (not a node add).. skip randomizer
53 if (forUpdate) {
54 return;
55 }
56
57 // Note: Placing incoming unpinned nodes at exactly the same point
58 // (center of the view) causes them to explode outwards when
59 // the force layout kicks in. So, we spread them out a bit
60 // initially, to provide a more serene layout convergence.
61 // Additionally, if the node is a host, we place it near
62 // the device it is connected to.
63
64 function rand() {
65 return {
66 x: rs.randDim(dim[0]),
67 y: rs.randDim(dim[1])
68 };
69 }
70
71 function near(node) {
72 return {
73 x: node.x + nearDist + rs.spread(nearDist),
74 y: node.y + nearDist + rs.spread(nearDist)
75 };
76 }
77
78 function getDevice(cp) {
79 return rand();
80 }
81
82 xy = (node.class === 'host') ? near(getDevice(node.cp)) : rand();
83
84 if (node.class === 'sub-region') {
85 xy = rand();
86 node.x = node.px = xy.x;
87 node.y = node.py = xy.y;
88 }
89 angular.extend(node, xy);
90 }
91
92 function setLongLat(el) {
93 var loc = el.get('location'),
94 coord;
95
Simon Huntbc30e682017-02-15 18:39:23 -080096 if (loc && loc.type === 'geo') {
Steven Burrows1c5c8612016-10-05 13:45:13 -050097
98 if (loc.lat === 0 && loc.lng === 0) {
99 return false;
100 }
101
102 coord = coordFromLngLat(loc);
103 el.fixed = true;
104 el.x = el.px = coord[0];
105 el.y = el.py = coord[1];
106
107 return true;
108 }
Simon Huntbc30e682017-02-15 18:39:23 -0800109
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000110 if (loc && loc.type === 'grid') {
111
112 if (loc.gridX === 0 && loc.gridY === 0) {
113 return false;
114 }
115
116 coord = coordFromXY(loc);
117 el.fixed = true;
118 el.x = el.px = coord[0];
119 el.y = el.py = coord[1];
120
121 return true;
122 }
Steven Burrows1c5c8612016-10-05 13:45:13 -0500123 }
124
125 function coordFromLngLat(loc) {
126 var p = t2mcs.projection();
127 return p ? p([loc.lng, loc.lat]) : [0, 0];
128 }
129
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000130 function coordFromXY(loc) {
Steven Burrows11162542017-02-27 21:52:56 +0000131 var scale = 1000 / t2sls.getWidth(),
132 yOffset = (1000 - (t2sls.getHeight() * scale)) / 2;
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000133
Steven Burrows11162542017-02-27 21:52:56 +0000134 // 1000 is a hardcoded HTML value of the SVG element (topo2.html)
135 var x = scale * loc.gridX,
136 y = (scale * loc.gridY) + yOffset;
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000137 return [x, y];
138 }
139
Steven Burrows1c5c8612016-10-05 13:45:13 -0500140 angular.module('ovTopo2')
141 .factory('Topo2NodePositionService',
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000142 ['RandomService', 'Topo2MapConfigService', 'Topo2SpriteLayerService',
143 function (_rs_, _t2mcs_, _t2sls_) {
Steven Burrows1c5c8612016-10-05 13:45:13 -0500144
145 rs = _rs_;
146 t2mcs = _t2mcs_;
Steven Burrows3db5ddb2017-02-17 15:21:20 +0000147 t2sls = _t2sls_;
Steven Burrows1c5c8612016-10-05 13:45:13 -0500148
149 return {
150 positionNode: positionNode,
151 setLongLat: setLongLat
152 };
153 }
154 ]);
155})();