GUI -- Cleaned up sprite definition format in JSON.
- Implemented sprite layer in topology view.
Change-Id: I0861641684df12202d6ccd069d89375a8005d4a8
diff --git a/web/gui/src/main/resources/core/js.html b/web/gui/src/main/resources/core/js.html
index 8d6d87d..ac9247b 100644
--- a/web/gui/src/main/resources/core/js.html
+++ b/web/gui/src/main/resources/core/js.html
@@ -9,6 +9,7 @@
<script src="app/view/topo/topoOblique.js"></script>
<script src="app/view/topo/topoPanel.js"></script>
<script src="app/view/topo/topoSelect.js"></script>
+<script src="app/view/topo/topoSprite.js"></script>
<script src="app/view/topo/topoTraffic.js"></script>
<script src="app/view/topo/topoToolbar.js"></script>
<script src="app/view/device/device.js"></script>
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.css b/web/gui/src/main/webapp/app/view/topo/topo.css
index b629559..887c2fc 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -542,3 +542,46 @@
fill: #eee;
}
+/* Sprite Layer */
+
+#ov-topo svg #topo-sprites text {
+ text-anchor: middle;
+ font-size: 10pt;
+ font-style: italic;
+}
+
+.light #ov-topo svg #topo-sprites .sprite1 use {
+ stroke-width: 1.0;
+ stroke: goldenrod;
+ fill: none;
+}
+.dark #ov-topo svg #topo-sprites .sprite1 use {
+ stroke-width: 1.0;
+ stroke: #541;
+ fill: none;
+}
+
+.light #ov-topo svg #topo-sprites .sprite1 text {
+ fill: #eda;
+}
+.dark #ov-topo svg #topo-sprites .sprite1 text {
+ fill: #543;
+}
+
+.light #ov-topo svg #topo-sprites .sprite2 use {
+ stroke: #bbd;
+ stroke-width: 1.0;
+ fill: none;
+}
+.dark #ov-topo svg #topo-sprites .sprite2 use {
+ stroke: #445;
+ stroke-width: 1.0;
+ fill: none;
+}
+
+.light #ov-topo svg #topo-sprites .sprite2 text {
+ fill: #cce;
+}
+.dark #ov-topo svg #topo-sprites .sprite2 text {
+ fill: #446;
+}
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index b16cb6d..68ecf2c 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -33,7 +33,7 @@
tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs;
// DOM elements
- var ovtopo, svg, defs, zoomLayer, mapG, forceG, noDevsLayer;
+ var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
// Internal state
var zoomer, actionMap;
@@ -53,6 +53,7 @@
P: [tfs.togglePorts, 'Toggle Port Highlighting'],
dash: [tfs.showBadLinks, 'Show bad links'],
B: [toggleMap, 'Toggle background map'],
+ S: [toggleSprites, 'Toggle sprite layer'],
//X: [toggleNodeLock, 'Lock / unlock node positions'],
Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'],
@@ -116,6 +117,14 @@
flash.flash(verb + ' background map');
}
+ function toggleSprites(x) {
+ var on = (x === 'keyev') ? !sus.visible(spriteG) : !!x,
+ verb = on ? 'Show' : 'Hide';
+ sus.visible(spriteG, on);
+ updatePrefsState('sprites', on);
+ flash.flash(verb + ' sprite layer');
+ }
+
function resetZoom() {
zoomer.reset();
}
@@ -247,24 +256,6 @@
.attr('opacity', b ? 1 : 0);
}
- function addSprites() {
- var g = zoomLayer.append ('g').attr('id', 'topo-sprites');
-
- function cloud(g, x, y) {
- g.append('use').attr({
- width: 100,
- height: 100,
- 'xlink:href': '#cloud',
- transform: sus.translate([x, y]) + sus.scale(4,4)
- }).style('stroke', 'goldenrod')
- .style('fill', 'none')
- .style('stroke-width', 1.0);
- }
-
- cloud(g, 0, 50);
- cloud(g, 800, 40);
- cloud(g, 400, 450);
- }
// --- User Preferemces ----------------------------------------------
@@ -285,6 +276,7 @@
toggleInstances(prefsState.insts);
toggleSummary(prefsState.summary);
toggleDetails(prefsState.detail);
+ toggleSprites(prefsState.sprites);
}
@@ -298,11 +290,11 @@
'TopoEventService', 'TopoForceService', 'TopoPanelService',
'TopoInstService', 'TopoSelectService', 'TopoLinkService',
'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
- 'TopoToolbarService',
+ 'TopoToolbarService', 'TopoSpriteService',
function ($scope, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
_zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_,
- _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_) {
+ _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_, tspr) {
var self = this,
projection,
dim,
@@ -373,7 +365,8 @@
toggleMap(prefsState.bg);
}
);
- // addSprites();
+ spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites');
+ tspr.loadSprites(spriteG);
forceG = zoomLayer.append('g').attr('id', 'topo-force');
tfs.initForce(svg, forceG, uplink, dim);
diff --git a/web/gui/src/main/webapp/app/view/topo/topoSprite.js b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
new file mode 100644
index 0000000..15e5182
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Topology Sprite Module.
+ Defines behavior for loading sprites.
+ */
+
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, $http, fs, sus;
+
+ // internal state
+ var spriteLayer,
+ cache = d3.map();
+
+ // constants
+ var urlPrefix = 'data/ext/';
+
+ function getUrl(id) {
+ return urlPrefix + id + '.json';
+ }
+
+ // =========================
+
+ function clearCache() {
+ cache = d3.map();
+ }
+
+
+ function loadSpriteData(id, cb) {
+ var url = getUrl(id),
+ promise = cache.get(id);
+
+ if (!promise) {
+ // need to fetch data and cache it
+ promise = $http.get(url);
+
+ promise.meta = {
+ id: id,
+ url: url,
+ wasCached: false
+ };
+
+ promise.then(function (response) {
+ // success
+ promise.spriteData = response.data;
+ cb(promise.spriteData);
+ }, function (response) {
+ // error
+ $log.warn('Failed to retrieve sprite data: ' + url,
+ response.status, response.data);
+ });
+
+ } else {
+ promise.meta.wasCached = true;
+ cb(promise.spriteData);
+ }
+ }
+
+ function doSprite(def, item) {
+ var g;
+
+ function xfm(x, y, s) {
+ return sus.translate([x,y]) + sus.scale(s, s);
+ }
+
+ g = spriteLayer.append('g')
+ .classed(def['class'], true)
+ .attr('transform', xfm(item.x, item.y, def.scale));
+
+ if (item.label) {
+ g.append('text')
+ .text(item.label)
+ .attr({
+ x: def.width / 2,
+ y: def.height * def.textyoff
+ });
+ }
+
+ g.append('use').attr({
+ width: def.width,
+ height: def.height,
+ 'xlink:href': '#' + def.use
+ });
+ }
+
+ function loadSprites(layer) {
+ spriteLayer = layer;
+
+ loadSpriteData('sprites', function (data) {
+ var defs = {};
+
+ $log.debug("Loading sprites...", data.file_desc);
+
+ data.defn.forEach(function (d) {
+ defs[d.id] = d;
+ });
+
+ data.load.forEach(function (item) {
+ doSprite(defs[item.id], item);
+ });
+ });
+
+ }
+
+
+ // === -----------------------------------------------------
+ // === MODULE DEFINITION ===
+
+ angular.module('ovTopo')
+ .factory('TopoSpriteService',
+ ['$log', '$http', 'FnService', 'SvgUtilService',
+
+ function (_$log_, _$http_, _fs_, _sus_) {
+ $log = _$log_;
+ $http = _$http_;
+ fs = _fs_;
+ sus = _sus_;
+
+ return {
+ clearCache: clearCache,
+ loadSprites: loadSprites
+ };
+ }]);
+
+}());
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
index 8a1895b..47e2a00 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -42,6 +42,7 @@
M: { id: 'offline-tog', gid: 'switch', isel: true },
P: { id: 'ports-tog', gid: 'ports', isel: true },
B: { id: 'bkgrnd-tog', gid: 'map', isel: true },
+ S: { id: 'sprite-tog', gid: 'cloud', isel: false },
//X: { id: 'nodelock-tog', gid: 'lock', isel: false },
Z: { id: 'oblique-tog', gid: 'oblique', isel: false },
@@ -62,6 +63,7 @@
// initial toggle state: default settings and tag to key mapping
var defaultPrefsState = {
bg: 1,
+ sprites: 0,
insts: 1,
summary: 1,
detail: 1,
@@ -69,6 +71,7 @@
},
prefsMap = {
bg: 'B',
+ sprites: 'S',
insts: 'I',
summary: 'O',
details: 'D',
@@ -129,6 +132,7 @@
addToggle('M');
addToggle('P');
addToggle('B');
+ addToggle('S');
}
function addSecondRow() {
//addToggle('X');
diff --git a/web/gui/src/main/webapp/data/ext/sprites.json b/web/gui/src/main/webapp/data/ext/sprites.json
index 5cf4109..74b9129 100644
--- a/web/gui/src/main/webapp/data/ext/sprites.json
+++ b/web/gui/src/main/webapp/data/ext/sprites.json
@@ -1,44 +1,44 @@
{
+ "file_desc": "Cloud Sprite Data",
+
"_comment": [
"configuration file for loading canned and/or custom sprites (and labels)",
"into the topology view. These appear above the map layer, but below",
"the nodes/links layer."
],
- "_comment_defn": "'defn' array contains custom sprite definitions",
+ "_comment_custom": "'custom' contains custom path data",
+ "custom": [
+
+ ],
+
+ "_comment_defn": "'defn' array contains sprite definitions",
"defn": [
-
- ],
-
- "_comment_defstyle": "'defstyle' defines default styles to apply",
- "defstyle": {
- "sprite": {
- "stroke": "goldenrod",
- "stroke-width": 1.0,
- "fill": "none"
- },
- "text": {
- "text-style": "italic",
- "test-size": "20pt"
- }
- },
-
- "_comment_load": [
- "'load' array contains list of sprites/labels to load",
- " note that 'copies' array defines [x,y] coords to position copies"
- ],
- "load": [
{
- "id": "cloud",
- "width": 100,
- "height": 100,
- "scale": 4.0,
- "copies": [
- [0, 50], [800, 40], [400, 450]
- ],
- "style": {
- "stroke": "green"
- }
+ "id": "subnet",
+ "class": "sprite1",
+ "use": "cloud",
+ "width": 120,
+ "height": 120,
+ "scale": 3.0,
+ "textyoff": 0.4
+ },
+ {
+ "id": "subnet2",
+ "class": "sprite2",
+ "use": "cloud",
+ "width": 200,
+ "height": 200,
+ "scale": 3.0,
+ "textyoff": 0.4
}
+ ],
+
+ "_comment_load": "'load' array contains list of sprites to load",
+ "load": [
+ { "id": "subnet", "x": -40, "y":20, "label":"apples" },
+ { "id": "subnet", "x":400, "y":40, "label":"bananas" },
+ { "id": "subnet", "x":840, "y":60, "label":"cherries" },
+ { "id": "subnet2", "x":300, "y":400 }
]
}
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 5d78257..e408846 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -107,6 +107,7 @@
<script src="app/view/topo/topoOblique.js"></script>
<script src="app/view/topo/topoPanel.js"></script>
<script src="app/view/topo/topoSelect.js"></script>
+ <script src="app/view/topo/topoSprite.js"></script>
<script src="app/view/topo/topoTraffic.js"></script>
<script src="app/view/topo/topoToolbar.js"></script>
<script src="app/view/device/device.js"></script>