Simon Hunt

GUI -- Cleaned up sprite definition format in JSON.

- Implemented sprite layer in topology view.

Change-Id: I0861641684df12202d6ccd069d89375a8005d4a8
......@@ -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>
......
......@@ -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;
}
......
......@@ -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);
......
/*
* 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
};
}]);
}());
......@@ -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');
......
{
"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",
"defn": [
"_comment_custom": "'custom' contains custom path data",
"custom": [
],
"_comment_defstyle": "'defstyle' defines default styles to apply",
"defstyle": {
"sprite": {
"stroke": "goldenrod",
"stroke-width": 1.0,
"fill": "none"
"_comment_defn": "'defn' array contains sprite definitions",
"defn": [
{
"id": "subnet",
"class": "sprite1",
"use": "cloud",
"width": 120,
"height": 120,
"scale": 3.0,
"textyoff": 0.4
},
"text": {
"text-style": "italic",
"test-size": "20pt"
{
"id": "subnet2",
"class": "sprite2",
"use": "cloud",
"width": 200,
"height": 200,
"scale": 3.0,
"textyoff": 0.4
}
},
"_comment_load": [
"'load' array contains list of sprites/labels to load",
" note that 'copies' array defines [x,y] coords to position copies"
],
"_comment_load": "'load' array contains list of sprites to load",
"load": [
{
"id": "cloud",
"width": 100,
"height": 100,
"scale": 4.0,
"copies": [
[0, 50], [800, 40], [400, 450]
],
"style": {
"stroke": "green"
}
}
{ "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 }
]
}
......
......@@ -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>
......