Simon Hunt

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
......@@ -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 {
......
......@@ -32,6 +32,7 @@
// internal state
var spriteLayer, defsElement;
function registerPathsAsGlyphs(paths) {
var custom = {},
ids = [];
......@@ -40,9 +41,14 @@
return fs.isA(d) ? d.join('') : d;
}
if (paths) {
paths.forEach(function (path) {
var tag = 'spr_' + path.tag;
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);
......@@ -51,10 +57,9 @@
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 (!paths) no('paths');
if (!defn) no('defn');
if (!load) no('load');
if (warn.length) {
$log.error(warn.join('\n'));
return;
}
if (data.defn) {
data.defn.forEach(function (d) {
// 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;
});
}
// pull out the sprite and label items
if (data.load) {
sprites = data.load.sprites;
labels = data.load.labels;
alpha = data.load.alpha;
// 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);
});
}
......
{
"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 }
]
}
}
......@@ -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" },
......