Steven Burrows
Committed by Gerrit Code Review

Topo2 Fixed device positions

Change-Id: I10e61981000b427ff1ebf6ae0c35bfb2cdbb9c4b
...@@ -64,4 +64,13 @@ layout-add l2 r2 ...@@ -64,4 +64,13 @@ layout-add l2 r2
64 layout-add l3 r3 l2 64 layout-add l3 r3 l2
65 65
66 layouts 66 layouts
67 -EOF
...\ No newline at end of file ...\ No newline at end of file
67 +EOF
68 +
69 +
70 +onos ${host} <<-EOF
71 +
72 +log:set DEBUG org.onosproject.ui.impl.topo.Topo2ViewMessageHandler
73 +log:set DEBUG org.onosproject.ui.impl.topo.Topo2Jsonifier
74 +log:set DEBUG org.onosproject.ui.impl.UiWebSocket
75 +log:list
76 +EOF
......
...@@ -36,6 +36,7 @@ import org.onosproject.net.intent.IntentService; ...@@ -36,6 +36,7 @@ import org.onosproject.net.intent.IntentService;
36 import org.onosproject.net.link.LinkService; 36 import org.onosproject.net.link.LinkService;
37 import org.onosproject.net.statistic.StatisticService; 37 import org.onosproject.net.statistic.StatisticService;
38 import org.onosproject.net.topology.TopologyService; 38 import org.onosproject.net.topology.TopologyService;
39 +import org.onosproject.ui.JsonUtils;
39 import org.onosproject.ui.model.topo.UiClusterMember; 40 import org.onosproject.ui.model.topo.UiClusterMember;
40 import org.onosproject.ui.model.topo.UiDevice; 41 import org.onosproject.ui.model.topo.UiDevice;
41 import org.onosproject.ui.model.topo.UiHost; 42 import org.onosproject.ui.model.topo.UiHost;
...@@ -482,4 +483,18 @@ class Topo2Jsonifier { ...@@ -482,4 +483,18 @@ class Topo2Jsonifier {
482 483
483 return splitList; 484 return splitList;
484 } 485 }
486 +
487 + /**
488 + * Stores the memento for an element.
489 + * This method assumes the payload has an id String, memento ObjectNode
490 + *
491 + * @param payload event payload
492 + */
493 + void updateMeta(ObjectNode payload) {
494 +
495 + String id = JsonUtils.string(payload, "id");
496 + metaUi.put(id, JsonUtils.node(payload, "memento"));
497 +
498 + log.debug("Storing metadata for {}", id);
499 + }
485 } 500 }
......
...@@ -60,6 +60,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { ...@@ -60,6 +60,7 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
60 private static final String START = "topo2Start"; 60 private static final String START = "topo2Start";
61 private static final String NAV_REGION = "topo2navRegion"; 61 private static final String NAV_REGION = "topo2navRegion";
62 private static final String STOP = "topo2Stop"; 62 private static final String STOP = "topo2Stop";
63 + private static final String UPDATE_META2 = "updateMeta2";
63 64
64 // === Outbound event identifiers 65 // === Outbound event identifiers
65 private static final String ALL_INSTANCES = "topo2AllInstances"; 66 private static final String ALL_INSTANCES = "topo2AllInstances";
...@@ -87,7 +88,8 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { ...@@ -87,7 +88,8 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
87 return ImmutableSet.of( 88 return ImmutableSet.of(
88 new Topo2Start(), 89 new Topo2Start(),
89 new Topo2NavRegion(), 90 new Topo2NavRegion(),
90 - new Topo2Stop() 91 + new Topo2Stop(),
92 + new Topo2UpdateMeta()
91 ); 93 );
92 } 94 }
93 95
...@@ -196,4 +198,15 @@ public class Topo2ViewMessageHandler extends UiMessageHandler { ...@@ -196,4 +198,15 @@ public class Topo2ViewMessageHandler extends UiMessageHandler {
196 } 198 }
197 } 199 }
198 200
201 + private final class Topo2UpdateMeta extends RequestHandler {
202 + private Topo2UpdateMeta() {
203 + super(UPDATE_META2);
204 + }
205 +
206 + @Override
207 + public void process(long sid, ObjectNode payload) {
208 + t2json.updateMeta(payload);
209 + }
210 + }
211 +
199 } 212 }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 25
26 // references to injected services 26 // references to injected services
27 var $scope, $log, fs, mast, ks, zs, 27 var $scope, $log, fs, mast, ks, zs,
28 - gs, sus, ps, t2es, t2fs, t2is, t2bcs, t2kcs, t2ms; 28 + gs, sus, ps, t2es, t2fs, t2is, t2bcs, t2kcs, t2ms, t2mcs;
29 29
30 // DOM elements 30 // DOM elements
31 var ovtopo2, svg, defs, zoomLayer, forceG; 31 var ovtopo2, svg, defs, zoomLayer, forceG;
...@@ -88,12 +88,13 @@ ...@@ -88,12 +88,13 @@
88 'WebSocketService', 'PrefsService', 'ThemeService', 88 'WebSocketService', 'PrefsService', 'ThemeService',
89 'Topo2EventService', 'Topo2ForceService', 'Topo2InstanceService', 89 'Topo2EventService', 'Topo2ForceService', 'Topo2InstanceService',
90 'Topo2BreadcrumbService', 'Topo2KeyCommandService', 'Topo2MapService', 90 'Topo2BreadcrumbService', 'Topo2KeyCommandService', 'Topo2MapService',
91 + 'Topo2MapConfigService',
91 92
92 function (_$scope_, _$log_, _$loc_, 93 function (_$scope_, _$log_, _$loc_,
93 _fs_, _mast_, _ks_, _zs_, 94 _fs_, _mast_, _ks_, _zs_,
94 _gs_, _ms_, _sus_, _flash_, 95 _gs_, _ms_, _sus_, _flash_,
95 _wss_, _ps_, _th_, 96 _wss_, _ps_, _th_,
96 - _t2es_, _t2fs_, _t2is_, _t2bcs_, _t2kcs_, _t2ms_) { 97 + _t2es_, _t2fs_, _t2is_, _t2bcs_, _t2kcs_, _t2ms_, _t2mcs_) {
97 98
98 var params = _$loc_.search(), 99 var params = _$loc_.search(),
99 dim, 100 dim,
...@@ -127,6 +128,7 @@ ...@@ -127,6 +128,7 @@
127 t2bcs = _t2bcs_; 128 t2bcs = _t2bcs_;
128 t2kcs = _t2kcs_; 129 t2kcs = _t2kcs_;
129 t2ms = _t2ms_; 130 t2ms = _t2ms_;
131 + t2mcs = _t2mcs_;
130 132
131 // capture selected intent parameters (if they are set in the 133 // capture selected intent parameters (if they are set in the
132 // query string) so that the traffic overlay can highlight 134 // query string) so that the traffic overlay can highlight
...@@ -177,25 +179,25 @@ ...@@ -177,25 +179,25 @@
177 function (proj) { 179 function (proj) {
178 var z = ps.getPrefs('topo_zoom', { tx: 0, ty: 0, sc: 1 }); 180 var z = ps.getPrefs('topo_zoom', { tx: 0, ty: 0, sc: 1 });
179 zoomer.panZoom([z.tx, z.ty], z.sc); 181 zoomer.panZoom([z.tx, z.ty], z.sc);
182 +
183 + t2mcs.projection(proj);
180 $log.debug('** Zoom restored:', z); 184 $log.debug('** Zoom restored:', z);
181 $log.debug('** We installed the projection:', proj); 185 $log.debug('** We installed the projection:', proj);
186 +
187 + // Now the map has load and we have a projection we can
188 + // get the info from the server
189 + t2es.start();
190 +
182 } 191 }
183 ); 192 );
184 193
185 // initialize the force layout, ready to render the topology 194 // initialize the force layout, ready to render the topology
186 forceG = zoomLayer.append('g').attr('id', 'topo-force'); 195 forceG = zoomLayer.append('g').attr('id', 'topo-force');
196 +
187 t2fs.init(svg, forceG, uplink, dim); 197 t2fs.init(svg, forceG, uplink, dim);
188 t2bcs.init(); 198 t2bcs.init();
189 t2kcs.init(t2fs); 199 t2kcs.init(t2fs);
190 200
191 -
192 - // =-=-=-=-=-=-=-=-
193 - // TODO: in future, we will load background map data
194 - // asynchronously (hence the promise) and then chain off
195 - // there to send the topo2start event to the server.
196 - // For now, we'll send the event inline...
197 - t2es.start();
198 -
199 t2is.initInst({ showMastership: t2fs.showMastership }); 201 t2is.initInst({ showMastership: t2fs.showMastership });
200 202
201 // === ORIGINAL CODE === 203 // === ORIGINAL CODE ===
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 (function () { 22 (function () {
23 'use strict'; 23 'use strict';
24 24
25 - var $log, sus, t2rs, t2d3, t2vs, t2ss; 25 + var $log, wss, sus, t2rs, t2d3, t2vs, t2ss;
26 26
27 var uplink, linkG, linkLabelG, nodeG; 27 var uplink, linkG, linkLabelG, nodeG;
28 var link, node; 28 var link, node;
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
142 // once we've finished moving, pin the node in position 142 // once we've finished moving, pin the node in position
143 d.fixed = true; 143 d.fixed = true;
144 d3.select(this).classed('fixed', true); 144 d3.select(this).classed('fixed', true);
145 - // TODO: sendUpdateMeta(d); 145 + sendUpdateMeta(d);
146 t2ss.clickConsumed(true); 146 t2ss.clickConsumed(true);
147 } 147 }
148 148
...@@ -153,6 +153,31 @@ ...@@ -153,6 +153,31 @@
153 return !nodeLock && !zoomingOrPanning(ev); 153 return !nodeLock && !zoomingOrPanning(ev);
154 } 154 }
155 155
156 + function sendUpdateMeta(d, clearPos) {
157 + var metaUi = {},
158 + ll;
159 +
160 + // if we are not clearing the position data (unpinning),
161 + // attach the x, y, (and equivalent longitude, latitude)...
162 + if (!clearPos) {
163 + ll = d.lngLatFromCoord([d.x, d.y]);
164 + metaUi = {
165 + x: d.x,
166 + y: d.y,
167 + equivLoc: {
168 + lng: ll[0],
169 + lat: ll[1]
170 + }
171 + };
172 + }
173 + d.metaUi = metaUi;
174 + wss.sendEvent('updateMeta2', {
175 + id: d.get('id'),
176 + class: d.get('class'),
177 + memento: metaUi
178 + });
179 + }
180 +
156 // predicate that indicates when clicking is active 181 // predicate that indicates when clicking is active
157 function clickEnabled() { 182 function clickEnabled() {
158 return true; 183 return true;
...@@ -396,12 +421,13 @@ ...@@ -396,12 +421,13 @@
396 angular.module('ovTopo2') 421 angular.module('ovTopo2')
397 .factory('Topo2LayoutService', 422 .factory('Topo2LayoutService',
398 [ 423 [
399 - '$log', 'SvgUtilService', 'Topo2RegionService', 424 + '$log', 'WebSocketService', 'SvgUtilService', 'Topo2RegionService',
400 'Topo2D3Service', 'Topo2ViewService', 'Topo2SelectService', 425 'Topo2D3Service', 'Topo2ViewService', 'Topo2SelectService',
401 426
402 - function (_$log_, _sus_, _t2rs_, _t2d3_, _t2vs_, _t2ss_) { 427 + function (_$log_, _wss_, _sus_, _t2rs_, _t2d3_, _t2vs_, _t2ss_) {
403 428
404 $log = _$log_; 429 $log = _$log_;
430 + wss = _wss_;
405 t2rs = _t2rs_; 431 t2rs = _t2rs_;
406 t2d3 = _t2d3_; 432 t2d3 = _t2d3_;
407 t2vs = _t2vs_; 433 t2vs = _t2vs_;
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
55 55
56 if (mapFilePath === '*countries') { 56 if (mapFilePath === '*countries') {
57 cfilter = countryFilters[mapId] || countryFilters.uk; 57 cfilter = countryFilters[mapId] || countryFilters.uk;
58 - loadMap = ms.loadMapRegionInto 58 + loadMap = ms.loadMapRegionInto;
59 } 59 }
60 60
61 promise = loadMap(mapG, mapFilePath, mapId, { 61 promise = loadMap(mapG, mapFilePath, mapId, {
......
1 +/*
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 Layout Module.
19 + Module that contains the d3.force.layout logic
20 + */
21 +
22 +(function () {
23 + 'use strict';
24 +
25 + // Injected refs
26 + var $log;
27 +
28 + // Internal State
29 + var proj;
30 +
31 + function projection(x) {
32 + if (x) {
33 + proj = x;
34 + $log.debug("Set the projection");
35 + }
36 + return proj;
37 + }
38 +
39 + angular.module('ovTopo2')
40 + .factory('Topo2MapConfigService',
41 + ['$log',
42 + function (_$log_) {
43 +
44 + $log = _$log_;
45 +
46 + return {
47 + projection: projection
48 + };
49 + }
50 + ]
51 + );
52 +})();
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
22 (function () { 22 (function () {
23 'use strict'; 23 'use strict';
24 24
25 - var randomService, ps, sus, is, ts; 25 + var randomService, ps, sus, is, ts, t2mcs;
26 var fn; 26 var fn;
27 27
28 // Internal state; 28 // Internal state;
...@@ -55,8 +55,7 @@ ...@@ -55,8 +55,7 @@
55 } 55 }
56 56
57 function positionNode(node, forUpdate) { 57 function positionNode(node, forUpdate) {
58 - 58 + var meta = node.get('metaUi'),
59 - var meta = node.metaUi,
60 x = meta && meta.x, 59 x = meta && meta.x,
61 y = meta && meta.y, 60 y = meta && meta.y,
62 dim = [800, 600], 61 dim = [800, 600],
...@@ -64,7 +63,6 @@ ...@@ -64,7 +63,6 @@
64 63
65 // If the device contains explicit LONG/LAT data, use that to position 64 // If the device contains explicit LONG/LAT data, use that to position
66 if (setLongLat(node)) { 65 if (setLongLat(node)) {
67 - // Indicate we want to update cached meta data...
68 return true; 66 return true;
69 } 67 }
70 68
...@@ -103,13 +101,16 @@ ...@@ -103,13 +101,16 @@
103 } 101 }
104 102
105 function getDevice(cp) { 103 function getDevice(cp) {
106 - // console.log(cp);
107 - // var d = lu[cp.device];
108 - // return d || rand();
109 return rand(); 104 return rand();
110 } 105 }
111 106
112 xy = (node.class === 'host') ? near(getDevice(node.cp)) : rand(); 107 xy = (node.class === 'host') ? near(getDevice(node.cp)) : rand();
108 +
109 + if (node.class === 'sub-region') {
110 + xy = rand();
111 + node.x = node.px = xy.x;
112 + node.y = node.py = xy.y;
113 + }
113 angular.extend(node, xy); 114 angular.extend(node, xy);
114 } 115 }
115 116
...@@ -118,7 +119,7 @@ ...@@ -118,7 +119,7 @@
118 coord; 119 coord;
119 120
120 if (loc && loc.type === 'lnglat') { 121 if (loc && loc.type === 'lnglat') {
121 - coord = [0, 0]; 122 + coord = coordFromLngLat(loc);
122 node.fixed = true; 123 node.fixed = true;
123 node.px = node.x = coord[0]; 124 node.px = node.x = coord[0];
124 node.py = node.y = coord[1]; 125 node.py = node.y = coord[1];
...@@ -126,11 +127,16 @@ ...@@ -126,11 +127,16 @@
126 } 127 }
127 } 128 }
128 129
130 + function coordFromLngLat(loc) {
131 + var p = t2mcs.projection();
132 + return p ? p.invert([loc.lng, loc.lat]) : [0, 0];
133 + }
134 +
129 angular.module('ovTopo2') 135 angular.module('ovTopo2')
130 .factory('Topo2NodeModel', 136 .factory('Topo2NodeModel',
131 ['Topo2Model', 'FnService', 'RandomService', 'Topo2PrefsService', 137 ['Topo2Model', 'FnService', 'RandomService', 'Topo2PrefsService',
132 - 'SvgUtilService', 'IconService', 'ThemeService', 138 + 'SvgUtilService', 'IconService', 'ThemeService', 'Topo2MapConfigService',
133 - function (Model, _fn_, _RandomService_, _ps_, _sus_, _is_, _ts_) { 139 + function (Model, _fn_, _RandomService_, _ps_, _sus_, _is_, _ts_, _t2mcs_) {
134 140
135 randomService = _RandomService_; 141 randomService = _RandomService_;
136 ts = _ts_; 142 ts = _ts_;
...@@ -138,11 +144,18 @@ ...@@ -138,11 +144,18 @@
138 ps = _ps_; 144 ps = _ps_;
139 sus = _sus_; 145 sus = _sus_;
140 is = _is_; 146 is = _is_;
147 + t2mcs = _t2mcs_;
141 148
142 return Model.extend({ 149 return Model.extend({
143 initialize: function () { 150 initialize: function () {
144 this.node = this.createNode(); 151 this.node = this.createNode();
145 }, 152 },
153 + createNode: function () {
154 + this.set('class', this.nodeType);
155 + this.set('svgClass', this.svgClassName());
156 + positionNode(this);
157 + return this;
158 + },
146 setUpEvents: function () { 159 setUpEvents: function () {
147 var _this = this; 160 var _this = this;
148 angular.forEach(this.events, function (handler, key) { 161 angular.forEach(this.events, function (handler, key) {
...@@ -221,6 +234,10 @@ ...@@ -221,6 +234,10 @@
221 } 234 }
222 ); 235 );
223 }, 236 },
237 + lngLatFromCoord: function (coord) {
238 + var p = t2mcs.projection();
239 + return p ? p.invert(coord) : [0, 0];
240 + },
224 update: function () { 241 update: function () {
225 this.updateLabel(); 242 this.updateLabel();
226 }, 243 },
...@@ -236,15 +253,6 @@ ...@@ -236,15 +253,6 @@
236 .transition() 253 .transition()
237 .attr(this.labelBox(devIconDim, labelWidth)); 254 .attr(this.labelBox(devIconDim, labelWidth));
238 }, 255 },
239 - createNode: function () {
240 - var node = angular.extend({}, this.attributes);
241 -
242 - // Augment as needed...
243 - node.class = this.nodeType;
244 - node.svgClass = this.svgClassName();
245 - positionNode(node);
246 - return node;
247 - },
248 onEnter: function (el) { 256 onEnter: function (el) {
249 this.el = d3.select(el); 257 this.el = d3.select(el);
250 this.render(); 258 this.render();
......
...@@ -141,6 +141,7 @@ ...@@ -141,6 +141,7 @@
141 <script src="app/view/topo2/topo2Link.js"></script> 141 <script src="app/view/topo2/topo2Link.js"></script>
142 <script src="app/view/topo2/topo2Map.js"></script> 142 <script src="app/view/topo2/topo2Map.js"></script>
143 <script src="app/view/topo2/topo2MapCountryFilters.js"></script> 143 <script src="app/view/topo2/topo2MapCountryFilters.js"></script>
144 + <script src="app/view/topo2/topo2MapConfig.js"></script>
144 <script src="app/view/topo2/topo2MapDialog.js"></script> 145 <script src="app/view/topo2/topo2MapDialog.js"></script>
145 <script src="app/view/topo2/topo2Model.js"></script> 146 <script src="app/view/topo2/topo2Model.js"></script>
146 <script src="app/view/topo2/topo2NodeModel.js"></script> 147 <script src="app/view/topo2/topo2NodeModel.js"></script>
......