GUI -- Created sample subnet sprite layout (clouds.json).
- Made paths, defn, load mandatory properties of the sprite definition file.
- (layout.json still a WIP)
Change-Id: I323a7ec7317f0837ff3319d67956cb4f836405eb
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 0caeec7..23ef0b5 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -555,7 +555,7 @@
}
.light #ov-topo svg #topo-sprites .gold1 use {
- stroke: #da2;
+ stroke: #fda;
fill: none;
}
.dark #ov-topo svg #topo-sprites .gold1 use {
diff --git a/web/gui/src/main/webapp/app/view/topo/topoSprite.js b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
index 3b1115a..9b5dbab 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoSprite.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoSprite.js
@@ -32,6 +32,7 @@
// internal state
var spriteLayer, defsElement;
+
function registerPathsAsGlyphs(paths) {
var custom = {},
ids = [];
@@ -40,21 +41,25 @@
return fs.isA(d) ? d.join('') : d;
}
- if (paths) {
- paths.forEach(function (path) {
- var tag = 'spr_' + path.tag;
- custom['_' + tag] = path.viewbox || '0 0 1000 1000';
- custom[tag] = mkd(path.d);
- ids.push(tag);
- });
+ paths.forEach(function (path) {
+ var tag = 'spr_' + path.tag;
- gs.registerGlyphs(custom);
- gs.loadDefs(defsElement, ids, true);
- }
+ if (path.glyph) {
+ // assumption is that we are using a built-in glyph
+ return;
+ }
+
+ custom['_' + tag] = path.viewbox || '0 0 1000 1000';
+ custom[tag] = mkd(path.d);
+ ids.push(tag);
+ });
+
+ gs.registerGlyphs(custom);
+ gs.loadDefs(defsElement, ids, true);
}
- function doSprite(spr, def, pstrk) {
+ function doSprite(spr, def, pmeta) {
var c = spr.class || 'gray1',
p = spr.pos || [0,0],
lab = spr.label,
@@ -64,7 +69,6 @@
dy = def.labelyoff || 1,
sc = def.scale,
xfm = sus.translate(p),
- useId = def.glyph || 'spr_' + def.path,
g, attr, use, style;
if (sc) {
@@ -78,14 +82,14 @@
attr = {
width: w,
height: h,
- 'xlink:href': '#' + useId
+ 'xlink:href': '#' + pmeta.u
};
use = g.append('use').attr(attr);
- if (pstrk) {
+ if (pmeta.s) {
style = {};
- angular.forEach(pstrk, function (value, key) {
+ angular.forEach(pmeta.s, function (value, key) {
style['stroke-' + key] = value;
});
use.style(style);
@@ -127,47 +131,66 @@
// data for the requested sprite definition.
function inData(payload) {
var data = payload.data,
- name, desc, sprites, labels, alpha,
- pathstrokes = {},
- defs = {};
+ name, desc, pfx, sprites, labels, alpha,
+ paths, defn, load,
+ pathmeta = {},
+ defs = {},
+ warn = [];
if (!data) {
- $log.warn(tssid + 'No sprite data loaded.')
+ $log.warn(tssid + 'No sprite data loaded.');
return;
}
name = data.defn_name;
desc = data.defn_desc;
+ paths = data.paths;
+ defn = data.defn;
+ load = data.load;
+ pfx = tssid + '[' + name + ']: ';
$log.debug("Loading sprites...[" + name + "]", desc);
- if (data.paths) {
- registerPathsAsGlyphs(data.paths);
- data.paths.forEach(function (p) {
- pathstrokes[p.tag] = p.stroke;
- });
+ function no(what) {
+ warn.push(pfx + 'No ' + what + ' property defined');
}
- if (data.defn) {
- data.defn.forEach(function (d) {
- defs[d.id] = d;
- });
+ if (!paths) no('paths');
+ if (!defn) no('defn');
+ if (!load) no('load');
+
+ if (warn.length) {
+ $log.error(warn.join('\n'));
+ return;
}
- // pull out the sprite and label items
- if (data.load) {
- sprites = data.load.sprites;
- labels = data.load.labels;
- alpha = data.load.alpha;
- if (alpha) {
- spriteLayer.style('opacity', alpha);
- }
+ // any custom paths need to be added to the glyph DB, and imported
+ registerPathsAsGlyphs(paths);
+
+ paths.forEach(function (p) {
+ pathmeta[p.tag] = {
+ s: p.stroke,
+ u: p.glyph || 'spr_' + p.tag
+ };
+ });
+
+ defn.forEach(function (d) {
+ defs[d.id] = d;
+ });
+
+ // sprites, labels and alpha are each optional components of the load
+ sprites = load.sprites;
+ labels = load.labels;
+ alpha = load.alpha;
+
+ if (alpha) {
+ spriteLayer.style('opacity', alpha);
}
if (sprites) {
sprites.forEach(function (spr) {
var def = defs[spr.id],
- pstrk = def.path && pathstrokes[def.path];
- doSprite(spr, def, pstrk);
+ pmeta = pathmeta[def.path];
+ doSprite(spr, def, pmeta);
});
}
diff --git a/web/gui/src/main/webapp/data/sprites/clouds.json b/web/gui/src/main/webapp/data/sprites/clouds.json
new file mode 100644
index 0000000..e0c5603
--- /dev/null
+++ b/web/gui/src/main/webapp/data/sprites/clouds.json
@@ -0,0 +1,59 @@
+{
+ "defn_name": "clouds",
+ "defn_desc": "Sample Subnet Cloud layout",
+
+ "_comment": [
+ "Sample cloud sprite layout",
+ "(1) Register on the server with ...",
+ " onos-upload-sprites localhost clouds.json",
+ "(2) Load into topology view with ...",
+ " http://localhost:8181/onos/ui/index.html#/topo?sprites=clouds"
+ ],
+
+ "paths": [
+ {
+ "tag": "cloud-dashed",
+ "stroke": {
+ "width": 0.8,
+ "dasharray": [4,2]
+ },
+ "glyph": "cloud"
+ },
+ {
+ "tag": "cloud-solid",
+ "stroke": {
+ "width": 1
+ },
+ "glyph": "cloud"
+ }
+ ],
+
+ "defn": [
+ {
+ "id": "subnetA",
+ "path": "cloud-dashed",
+ "dim": [400,400],
+ "labelyoff": 0.35
+ },
+ {
+ "id": "subnetB",
+ "path": "cloud-solid",
+ "dim": [600,600],
+ "labelyoff": 0.35
+ }
+ ],
+
+ "load": {
+ "sprites": [
+ { "id": "subnetA", "pos":[-200,40], "label":"apples", "class":"blue1" },
+ { "id": "subnetA", "pos":[250,40], "label":"bananas", "class":"blue1" },
+ { "id": "subnetA", "pos":[700,40], "label":"cherries", "class":"blue1" },
+ { "id": "subnetB", "pos":[-200,400], "label":"Menlo Park", "class":"gold1" },
+ { "id": "subnetB", "pos":[500,400], "label":"Stanford", "class":"gold1" }
+ ],
+ "labels": [
+ { "pos":[0,50], "text":"Sample Subnets", "size":1.4 }
+ ]
+ }
+
+}
diff --git a/web/gui/src/main/webapp/data/sprites/layout.json b/web/gui/src/main/webapp/data/sprites/layout.json
index 3e41939..243681a 100644
--- a/web/gui/src/main/webapp/data/sprites/layout.json
+++ b/web/gui/src/main/webapp/data/sprites/layout.json
@@ -18,16 +18,18 @@
"paths": [
{
"tag": "border",
- "d": "M0,0h1000v1000h-1000z",
- "_comment": "bounds of viewbox 0 0 1000 1000"
+ "viewbox": "0 0 1 1",
+ "d": "M0,0h1v1h-1z",
+ "_comment": "path defined in single string"
},
{
- "tag": "multi",
+ "tag": "banner",
+ "viewbox": "0 0 4 8",
"d": [
- "M500,500l-50,50v-200h100v200z",
- "M600,400h200v50h-200z"
+ "M0,0h4v6l-2,-2l-2,2z",
+ "M1,6h2v2h-2z"
],
- "_comment": "shows path constructed from multiple strings"
+ "_comment": "path defined in multiple strings"
},
{
"tag": "triangle",
@@ -49,18 +51,20 @@
"",
"The 'glyph' property refers to glyphs registered with the UI.",
"Alternatively, the 'path' property refers to a custom path defined in",
- "the path array above. The 'dim' property provides the [width,height]",
- "bounds within which the glyph/path is drawn. The 'labelyoff' property",
- "defines the Y-offset of the label as a percentage from the top of the",
- "sprite; for example, 0.4 = 40%. The label is centered horizontally.",
- "",
- "Note that dimension (dim) defaults to [40,40] which is the",
- "approximate size of a device icon."
+ " the path array above.",
+ "The 'dim' property provides the [width,height] bounds within which the",
+ " glyph/path is drawn. (default is [40,40])",
+ "The 'labelyoff' property defines the Y-offset of the label as a",
+ " percentage from the top of the sprite; for example, 0.4 = 40%. The",
+ " label is centered horizontally.",
+ "The 'scale' property (default is 1) defines the scaling factor, which",
+ " is applied after the sprite has been translated to its position."
],
"defn": [
{
"id": "border",
- "path": "border"
+ "path": "border",
+ "dim":[1000,1000]
},
{
"id": "multi",
@@ -103,6 +107,7 @@
],
"load": {
"sprites": [
+ { "id": "border", "class": "gold1" },
{ "id": "subnet", "pos":[-40,20], "label":"apples", "class": "blue1" },
{ "id": "subnet", "pos":[400,40], "label":"bananas", "class": "blue1" },
{ "id": "subnet", "pos":[840,60], "label":"cherries", "class": "blue1" },