GUI -- Cleaned up sprite definition format in JSON.
- Implemented sprite layer in topology view. Change-Id: I0861641684df12202d6ccd069d89375a8005d4a8
Showing
7 changed files
with
234 additions
and
50 deletions
... | @@ -9,6 +9,7 @@ | ... | @@ -9,6 +9,7 @@ |
9 | <script src="app/view/topo/topoOblique.js"></script> | 9 | <script src="app/view/topo/topoOblique.js"></script> |
10 | <script src="app/view/topo/topoPanel.js"></script> | 10 | <script src="app/view/topo/topoPanel.js"></script> |
11 | <script src="app/view/topo/topoSelect.js"></script> | 11 | <script src="app/view/topo/topoSelect.js"></script> |
12 | +<script src="app/view/topo/topoSprite.js"></script> | ||
12 | <script src="app/view/topo/topoTraffic.js"></script> | 13 | <script src="app/view/topo/topoTraffic.js"></script> |
13 | <script src="app/view/topo/topoToolbar.js"></script> | 14 | <script src="app/view/topo/topoToolbar.js"></script> |
14 | <script src="app/view/device/device.js"></script> | 15 | <script src="app/view/device/device.js"></script> | ... | ... |
... | @@ -542,3 +542,46 @@ | ... | @@ -542,3 +542,46 @@ |
542 | fill: #eee; | 542 | fill: #eee; |
543 | } | 543 | } |
544 | 544 | ||
545 | +/* Sprite Layer */ | ||
546 | + | ||
547 | +#ov-topo svg #topo-sprites text { | ||
548 | + text-anchor: middle; | ||
549 | + font-size: 10pt; | ||
550 | + font-style: italic; | ||
551 | +} | ||
552 | + | ||
553 | +.light #ov-topo svg #topo-sprites .sprite1 use { | ||
554 | + stroke-width: 1.0; | ||
555 | + stroke: goldenrod; | ||
556 | + fill: none; | ||
557 | +} | ||
558 | +.dark #ov-topo svg #topo-sprites .sprite1 use { | ||
559 | + stroke-width: 1.0; | ||
560 | + stroke: #541; | ||
561 | + fill: none; | ||
562 | +} | ||
563 | + | ||
564 | +.light #ov-topo svg #topo-sprites .sprite1 text { | ||
565 | + fill: #eda; | ||
566 | +} | ||
567 | +.dark #ov-topo svg #topo-sprites .sprite1 text { | ||
568 | + fill: #543; | ||
569 | +} | ||
570 | + | ||
571 | +.light #ov-topo svg #topo-sprites .sprite2 use { | ||
572 | + stroke: #bbd; | ||
573 | + stroke-width: 1.0; | ||
574 | + fill: none; | ||
575 | +} | ||
576 | +.dark #ov-topo svg #topo-sprites .sprite2 use { | ||
577 | + stroke: #445; | ||
578 | + stroke-width: 1.0; | ||
579 | + fill: none; | ||
580 | +} | ||
581 | + | ||
582 | +.light #ov-topo svg #topo-sprites .sprite2 text { | ||
583 | + fill: #cce; | ||
584 | +} | ||
585 | +.dark #ov-topo svg #topo-sprites .sprite2 text { | ||
586 | + fill: #446; | ||
587 | +} | ... | ... |
... | @@ -33,7 +33,7 @@ | ... | @@ -33,7 +33,7 @@ |
33 | tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs; | 33 | tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs; |
34 | 34 | ||
35 | // DOM elements | 35 | // DOM elements |
36 | - var ovtopo, svg, defs, zoomLayer, mapG, forceG, noDevsLayer; | 36 | + var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; |
37 | 37 | ||
38 | // Internal state | 38 | // Internal state |
39 | var zoomer, actionMap; | 39 | var zoomer, actionMap; |
... | @@ -53,6 +53,7 @@ | ... | @@ -53,6 +53,7 @@ |
53 | P: [tfs.togglePorts, 'Toggle Port Highlighting'], | 53 | P: [tfs.togglePorts, 'Toggle Port Highlighting'], |
54 | dash: [tfs.showBadLinks, 'Show bad links'], | 54 | dash: [tfs.showBadLinks, 'Show bad links'], |
55 | B: [toggleMap, 'Toggle background map'], | 55 | B: [toggleMap, 'Toggle background map'], |
56 | + S: [toggleSprites, 'Toggle sprite layer'], | ||
56 | 57 | ||
57 | //X: [toggleNodeLock, 'Lock / unlock node positions'], | 58 | //X: [toggleNodeLock, 'Lock / unlock node positions'], |
58 | Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'], | 59 | Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'], |
... | @@ -116,6 +117,14 @@ | ... | @@ -116,6 +117,14 @@ |
116 | flash.flash(verb + ' background map'); | 117 | flash.flash(verb + ' background map'); |
117 | } | 118 | } |
118 | 119 | ||
120 | + function toggleSprites(x) { | ||
121 | + var on = (x === 'keyev') ? !sus.visible(spriteG) : !!x, | ||
122 | + verb = on ? 'Show' : 'Hide'; | ||
123 | + sus.visible(spriteG, on); | ||
124 | + updatePrefsState('sprites', on); | ||
125 | + flash.flash(verb + ' sprite layer'); | ||
126 | + } | ||
127 | + | ||
119 | function resetZoom() { | 128 | function resetZoom() { |
120 | zoomer.reset(); | 129 | zoomer.reset(); |
121 | } | 130 | } |
... | @@ -247,24 +256,6 @@ | ... | @@ -247,24 +256,6 @@ |
247 | .attr('opacity', b ? 1 : 0); | 256 | .attr('opacity', b ? 1 : 0); |
248 | } | 257 | } |
249 | 258 | ||
250 | - function addSprites() { | ||
251 | - var g = zoomLayer.append ('g').attr('id', 'topo-sprites'); | ||
252 | - | ||
253 | - function cloud(g, x, y) { | ||
254 | - g.append('use').attr({ | ||
255 | - width: 100, | ||
256 | - height: 100, | ||
257 | - 'xlink:href': '#cloud', | ||
258 | - transform: sus.translate([x, y]) + sus.scale(4,4) | ||
259 | - }).style('stroke', 'goldenrod') | ||
260 | - .style('fill', 'none') | ||
261 | - .style('stroke-width', 1.0); | ||
262 | - } | ||
263 | - | ||
264 | - cloud(g, 0, 50); | ||
265 | - cloud(g, 800, 40); | ||
266 | - cloud(g, 400, 450); | ||
267 | - } | ||
268 | 259 | ||
269 | // --- User Preferemces ---------------------------------------------- | 260 | // --- User Preferemces ---------------------------------------------- |
270 | 261 | ||
... | @@ -285,6 +276,7 @@ | ... | @@ -285,6 +276,7 @@ |
285 | toggleInstances(prefsState.insts); | 276 | toggleInstances(prefsState.insts); |
286 | toggleSummary(prefsState.summary); | 277 | toggleSummary(prefsState.summary); |
287 | toggleDetails(prefsState.detail); | 278 | toggleDetails(prefsState.detail); |
279 | + toggleSprites(prefsState.sprites); | ||
288 | } | 280 | } |
289 | 281 | ||
290 | 282 | ||
... | @@ -298,11 +290,11 @@ | ... | @@ -298,11 +290,11 @@ |
298 | 'TopoEventService', 'TopoForceService', 'TopoPanelService', | 290 | 'TopoEventService', 'TopoForceService', 'TopoPanelService', |
299 | 'TopoInstService', 'TopoSelectService', 'TopoLinkService', | 291 | 'TopoInstService', 'TopoSelectService', 'TopoLinkService', |
300 | 'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService', | 292 | 'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService', |
301 | - 'TopoToolbarService', | 293 | + 'TopoToolbarService', 'TopoSpriteService', |
302 | 294 | ||
303 | function ($scope, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_, | 295 | function ($scope, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_, |
304 | _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_, | 296 | _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_, |
305 | - _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_) { | 297 | + _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_, tspr) { |
306 | var self = this, | 298 | var self = this, |
307 | projection, | 299 | projection, |
308 | dim, | 300 | dim, |
... | @@ -373,7 +365,8 @@ | ... | @@ -373,7 +365,8 @@ |
373 | toggleMap(prefsState.bg); | 365 | toggleMap(prefsState.bg); |
374 | } | 366 | } |
375 | ); | 367 | ); |
376 | - // addSprites(); | 368 | + spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites'); |
369 | + tspr.loadSprites(spriteG); | ||
377 | 370 | ||
378 | forceG = zoomLayer.append('g').attr('id', 'topo-force'); | 371 | forceG = zoomLayer.append('g').attr('id', 'topo-force'); |
379 | tfs.initForce(svg, forceG, uplink, dim); | 372 | tfs.initForce(svg, forceG, uplink, dim); | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 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 Sprite Module. | ||
19 | + Defines behavior for loading sprites. | ||
20 | + */ | ||
21 | + | ||
22 | +(function () { | ||
23 | + 'use strict'; | ||
24 | + | ||
25 | + // injected refs | ||
26 | + var $log, $http, fs, sus; | ||
27 | + | ||
28 | + // internal state | ||
29 | + var spriteLayer, | ||
30 | + cache = d3.map(); | ||
31 | + | ||
32 | + // constants | ||
33 | + var urlPrefix = 'data/ext/'; | ||
34 | + | ||
35 | + function getUrl(id) { | ||
36 | + return urlPrefix + id + '.json'; | ||
37 | + } | ||
38 | + | ||
39 | + // ========================= | ||
40 | + | ||
41 | + function clearCache() { | ||
42 | + cache = d3.map(); | ||
43 | + } | ||
44 | + | ||
45 | + | ||
46 | + function loadSpriteData(id, cb) { | ||
47 | + var url = getUrl(id), | ||
48 | + promise = cache.get(id); | ||
49 | + | ||
50 | + if (!promise) { | ||
51 | + // need to fetch data and cache it | ||
52 | + promise = $http.get(url); | ||
53 | + | ||
54 | + promise.meta = { | ||
55 | + id: id, | ||
56 | + url: url, | ||
57 | + wasCached: false | ||
58 | + }; | ||
59 | + | ||
60 | + promise.then(function (response) { | ||
61 | + // success | ||
62 | + promise.spriteData = response.data; | ||
63 | + cb(promise.spriteData); | ||
64 | + }, function (response) { | ||
65 | + // error | ||
66 | + $log.warn('Failed to retrieve sprite data: ' + url, | ||
67 | + response.status, response.data); | ||
68 | + }); | ||
69 | + | ||
70 | + } else { | ||
71 | + promise.meta.wasCached = true; | ||
72 | + cb(promise.spriteData); | ||
73 | + } | ||
74 | + } | ||
75 | + | ||
76 | + function doSprite(def, item) { | ||
77 | + var g; | ||
78 | + | ||
79 | + function xfm(x, y, s) { | ||
80 | + return sus.translate([x,y]) + sus.scale(s, s); | ||
81 | + } | ||
82 | + | ||
83 | + g = spriteLayer.append('g') | ||
84 | + .classed(def['class'], true) | ||
85 | + .attr('transform', xfm(item.x, item.y, def.scale)); | ||
86 | + | ||
87 | + if (item.label) { | ||
88 | + g.append('text') | ||
89 | + .text(item.label) | ||
90 | + .attr({ | ||
91 | + x: def.width / 2, | ||
92 | + y: def.height * def.textyoff | ||
93 | + }); | ||
94 | + } | ||
95 | + | ||
96 | + g.append('use').attr({ | ||
97 | + width: def.width, | ||
98 | + height: def.height, | ||
99 | + 'xlink:href': '#' + def.use | ||
100 | + }); | ||
101 | + } | ||
102 | + | ||
103 | + function loadSprites(layer) { | ||
104 | + spriteLayer = layer; | ||
105 | + | ||
106 | + loadSpriteData('sprites', function (data) { | ||
107 | + var defs = {}; | ||
108 | + | ||
109 | + $log.debug("Loading sprites...", data.file_desc); | ||
110 | + | ||
111 | + data.defn.forEach(function (d) { | ||
112 | + defs[d.id] = d; | ||
113 | + }); | ||
114 | + | ||
115 | + data.load.forEach(function (item) { | ||
116 | + doSprite(defs[item.id], item); | ||
117 | + }); | ||
118 | + }); | ||
119 | + | ||
120 | + } | ||
121 | + | ||
122 | + | ||
123 | + // === ----------------------------------------------------- | ||
124 | + // === MODULE DEFINITION === | ||
125 | + | ||
126 | + angular.module('ovTopo') | ||
127 | + .factory('TopoSpriteService', | ||
128 | + ['$log', '$http', 'FnService', 'SvgUtilService', | ||
129 | + | ||
130 | + function (_$log_, _$http_, _fs_, _sus_) { | ||
131 | + $log = _$log_; | ||
132 | + $http = _$http_; | ||
133 | + fs = _fs_; | ||
134 | + sus = _sus_; | ||
135 | + | ||
136 | + return { | ||
137 | + clearCache: clearCache, | ||
138 | + loadSprites: loadSprites | ||
139 | + }; | ||
140 | + }]); | ||
141 | + | ||
142 | +}()); |
... | @@ -42,6 +42,7 @@ | ... | @@ -42,6 +42,7 @@ |
42 | M: { id: 'offline-tog', gid: 'switch', isel: true }, | 42 | M: { id: 'offline-tog', gid: 'switch', isel: true }, |
43 | P: { id: 'ports-tog', gid: 'ports', isel: true }, | 43 | P: { id: 'ports-tog', gid: 'ports', isel: true }, |
44 | B: { id: 'bkgrnd-tog', gid: 'map', isel: true }, | 44 | B: { id: 'bkgrnd-tog', gid: 'map', isel: true }, |
45 | + S: { id: 'sprite-tog', gid: 'cloud', isel: false }, | ||
45 | 46 | ||
46 | //X: { id: 'nodelock-tog', gid: 'lock', isel: false }, | 47 | //X: { id: 'nodelock-tog', gid: 'lock', isel: false }, |
47 | Z: { id: 'oblique-tog', gid: 'oblique', isel: false }, | 48 | Z: { id: 'oblique-tog', gid: 'oblique', isel: false }, |
... | @@ -62,6 +63,7 @@ | ... | @@ -62,6 +63,7 @@ |
62 | // initial toggle state: default settings and tag to key mapping | 63 | // initial toggle state: default settings and tag to key mapping |
63 | var defaultPrefsState = { | 64 | var defaultPrefsState = { |
64 | bg: 1, | 65 | bg: 1, |
66 | + sprites: 0, | ||
65 | insts: 1, | 67 | insts: 1, |
66 | summary: 1, | 68 | summary: 1, |
67 | detail: 1, | 69 | detail: 1, |
... | @@ -69,6 +71,7 @@ | ... | @@ -69,6 +71,7 @@ |
69 | }, | 71 | }, |
70 | prefsMap = { | 72 | prefsMap = { |
71 | bg: 'B', | 73 | bg: 'B', |
74 | + sprites: 'S', | ||
72 | insts: 'I', | 75 | insts: 'I', |
73 | summary: 'O', | 76 | summary: 'O', |
74 | details: 'D', | 77 | details: 'D', |
... | @@ -129,6 +132,7 @@ | ... | @@ -129,6 +132,7 @@ |
129 | addToggle('M'); | 132 | addToggle('M'); |
130 | addToggle('P'); | 133 | addToggle('P'); |
131 | addToggle('B'); | 134 | addToggle('B'); |
135 | + addToggle('S'); | ||
132 | } | 136 | } |
133 | function addSecondRow() { | 137 | function addSecondRow() { |
134 | //addToggle('X'); | 138 | //addToggle('X'); | ... | ... |
1 | { | 1 | { |
2 | + "file_desc": "Cloud Sprite Data", | ||
3 | + | ||
2 | "_comment": [ | 4 | "_comment": [ |
3 | "configuration file for loading canned and/or custom sprites (and labels)", | 5 | "configuration file for loading canned and/or custom sprites (and labels)", |
4 | "into the topology view. These appear above the map layer, but below", | 6 | "into the topology view. These appear above the map layer, but below", |
5 | "the nodes/links layer." | 7 | "the nodes/links layer." |
6 | ], | 8 | ], |
7 | 9 | ||
8 | - "_comment_defn": "'defn' array contains custom sprite definitions", | 10 | + "_comment_custom": "'custom' contains custom path data", |
9 | - "defn": [ | 11 | + "custom": [ |
10 | 12 | ||
11 | ], | 13 | ], |
12 | 14 | ||
13 | - "_comment_defstyle": "'defstyle' defines default styles to apply", | 15 | + "_comment_defn": "'defn' array contains sprite definitions", |
14 | - "defstyle": { | 16 | + "defn": [ |
15 | - "sprite": { | 17 | + { |
16 | - "stroke": "goldenrod", | 18 | + "id": "subnet", |
17 | - "stroke-width": 1.0, | 19 | + "class": "sprite1", |
18 | - "fill": "none" | 20 | + "use": "cloud", |
21 | + "width": 120, | ||
22 | + "height": 120, | ||
23 | + "scale": 3.0, | ||
24 | + "textyoff": 0.4 | ||
19 | }, | 25 | }, |
20 | - "text": { | 26 | + { |
21 | - "text-style": "italic", | 27 | + "id": "subnet2", |
22 | - "test-size": "20pt" | 28 | + "class": "sprite2", |
29 | + "use": "cloud", | ||
30 | + "width": 200, | ||
31 | + "height": 200, | ||
32 | + "scale": 3.0, | ||
33 | + "textyoff": 0.4 | ||
23 | } | 34 | } |
24 | - }, | ||
25 | - | ||
26 | - "_comment_load": [ | ||
27 | - "'load' array contains list of sprites/labels to load", | ||
28 | - " note that 'copies' array defines [x,y] coords to position copies" | ||
29 | ], | 35 | ], |
36 | + | ||
37 | + "_comment_load": "'load' array contains list of sprites to load", | ||
30 | "load": [ | 38 | "load": [ |
31 | - { | 39 | + { "id": "subnet", "x": -40, "y":20, "label":"apples" }, |
32 | - "id": "cloud", | 40 | + { "id": "subnet", "x":400, "y":40, "label":"bananas" }, |
33 | - "width": 100, | 41 | + { "id": "subnet", "x":840, "y":60, "label":"cherries" }, |
34 | - "height": 100, | 42 | + { "id": "subnet2", "x":300, "y":400 } |
35 | - "scale": 4.0, | ||
36 | - "copies": [ | ||
37 | - [0, 50], [800, 40], [400, 450] | ||
38 | - ], | ||
39 | - "style": { | ||
40 | - "stroke": "green" | ||
41 | - } | ||
42 | - } | ||
43 | ] | 43 | ] |
44 | } | 44 | } | ... | ... |
... | @@ -107,6 +107,7 @@ | ... | @@ -107,6 +107,7 @@ |
107 | <script src="app/view/topo/topoOblique.js"></script> | 107 | <script src="app/view/topo/topoOblique.js"></script> |
108 | <script src="app/view/topo/topoPanel.js"></script> | 108 | <script src="app/view/topo/topoPanel.js"></script> |
109 | <script src="app/view/topo/topoSelect.js"></script> | 109 | <script src="app/view/topo/topoSelect.js"></script> |
110 | + <script src="app/view/topo/topoSprite.js"></script> | ||
110 | <script src="app/view/topo/topoTraffic.js"></script> | 111 | <script src="app/view/topo/topoTraffic.js"></script> |
111 | <script src="app/view/topo/topoToolbar.js"></script> | 112 | <script src="app/view/topo/topoToolbar.js"></script> |
112 | <script src="app/view/device/device.js"></script> | 113 | <script src="app/view/device/device.js"></script> | ... | ... |
-
Please register or login to post a comment