GUI -- Completed Show Summary panel.
- added GlyphService.addGlyph().
- added SvgUtilService.translate().
Change-Id: I0bbc51a8f1d9c24b8b4f1377236570070da6f160
diff --git a/web/gui/src/main/webapp/app/fw/svg/glyph.css b/web/gui/src/main/webapp/app/fw/svg/glyph.css
new file mode 100644
index 0000000..8291065
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/svg/glyph.css
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014,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 -- Glyph Service -- CSS file
+ */
+
+svg .glyph {
+ stroke: none;
+ fill-rule: evenodd;
+}
+
+.light svg .glyph,
+.dark svg .glyph.overlay {
+ fill: black;
+}
+
+.dark svg .glyph,
+.light svg .glyph.overlay {
+ fill: white;
+}
diff --git a/web/gui/src/main/webapp/app/fw/svg/glyph.js b/web/gui/src/main/webapp/app/fw/svg/glyph.js
index 07c7d0b..f85b697 100644
--- a/web/gui/src/main/webapp/app/fw/svg/glyph.js
+++ b/web/gui/src/main/webapp/app/fw/svg/glyph.js
@@ -20,9 +20,11 @@
(function () {
'use strict';
- var $log,
- fs,
- glyphs = d3.map(),
+ // injected references
+ var $log, fs, sus;
+
+ // internal state
+ var glyphs = d3.map(),
msgGS = 'GlyphService.';
// ----------------------------------------------------------------------
@@ -133,78 +135,102 @@
// ----------------------------------------------------------------------
+ function clear() {
+ // start with a fresh map
+ glyphs = d3.map();
+ }
+
+ function init() {
+ clear();
+ register(birdViewBox, birdData);
+ register(glyphViewBox, glyphData);
+ register(badgeViewBox, badgeData);
+ }
+
+ function register(viewBox, data, overwrite) {
+ var dmap = d3.map(data),
+ dups = [],
+ ok;
+
+ dmap.forEach(function (key, value) {
+ if (!overwrite && glyphs.get(key)) {
+ dups.push(key);
+ } else {
+ glyphs.set(key, {id: key, vb: viewBox, d: value});
+ }
+ });
+ ok = (dups.length == 0);
+ if (!ok) {
+ dups.forEach(function (id) {
+ $log.warn(msgGS + 'register(): ID collision: "'+id+'"');
+ });
+ }
+ return ok;
+ }
+
+ function ids() {
+ return glyphs.keys();
+ }
+
+ function glyph(id) {
+ return glyphs.get(id);
+ }
+
+ // Note: defs should be a D3 selection of a single <defs> element
+ function loadDefs(defs, glyphIds, noClear) {
+ var list = fs.isA(glyphIds) || ids(),
+ clearCache = !noClear;
+
+ if (clearCache) {
+ // remove all existing content
+ defs.html(null);
+ }
+
+ // load up the requested glyphs
+ list.forEach(function (id) {
+ var g = glyph(id);
+ if (g) {
+ if (noClear) {
+ // quick exit if symbol is already present
+ if (defs.select('symbol#' + g.id).size() > 0) {
+ return;
+ }
+ }
+ defs.append('symbol')
+ .attr({ id: g.id, viewBox: g.vb })
+ .append('path').attr('d', g.d);
+ }
+ });
+ }
+
+ function addGlyph(elem, glyphId, size, overlay, trans) {
+ var sz = size || 40,
+ ovr = !!overlay,
+ xns = fs.isA(trans),
+ atr = {
+ width: sz,
+ height: sz,
+ 'class': 'glyph',
+ 'xlink:href': '#' + glyphId
+ };
+
+ if (xns) {
+ atr.transform = sus.translate(trans);
+ }
+ elem.append('use').attr(atr).classed('overlay', ovr);
+
+ }
+
+ // ----------------------------------------------------------------------
+
angular.module('onosSvg')
- .factory('GlyphService', ['$log', 'FnService', function (_$log_, _fs_) {
+ .factory('GlyphService',
+ ['$log', 'FnService', 'SvgUtilService',
+
+ function (_$log_, _fs_, _sus_) {
$log = _$log_;
fs = _fs_;
-
- function clear() {
- // start with a fresh map
- glyphs = d3.map();
- }
-
- function init() {
- clear();
- register(birdViewBox, birdData);
- register(glyphViewBox, glyphData);
- register(badgeViewBox, badgeData);
- }
-
- function register(viewBox, data, overwrite) {
- var dmap = d3.map(data),
- dups = [],
- ok;
-
- dmap.forEach(function (key, value) {
- if (!overwrite && glyphs.get(key)) {
- dups.push(key);
- } else {
- glyphs.set(key, {id: key, vb: viewBox, d: value});
- }
- });
- ok = (dups.length == 0);
- if (!ok) {
- dups.forEach(function (id) {
- $log.warn(msgGS + 'register(): ID collision: "'+id+'"');
- });
- }
- return ok;
- }
-
- function ids() {
- return glyphs.keys();
- }
-
- function glyph(id) {
- return glyphs.get(id);
- }
-
- // Note: defs should be a D3 selection of a single <defs> element
- function loadDefs(defs, glyphIds, noClear) {
- var list = fs.isA(glyphIds) || ids(),
- clearCache = !noClear;
-
- if (clearCache) {
- // remove all existing content
- defs.html(null);
- }
-
- // load up the requested glyphs
- list.forEach(function (id) {
- var g = glyph(id);
- if (g) {
- if (noClear) {
- // quick exit if symbol is already present
- if (defs.select('symbol#' + g.id).size() > 0) {
- return;
- }
- }
- defs.append('symbol')
- .attr({ id: g.id, viewBox: g.vb })
- .append('path').attr('d', g.d);
- }
- });
- }
+ sus = _sus_;
return {
clear: clear,
@@ -212,8 +238,10 @@
register: register,
ids: ids,
glyph: glyph,
- loadDefs: loadDefs
+ loadDefs: loadDefs,
+ addGlyph: addGlyph
};
- }]);
+ }]
+ );
}());
diff --git a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
index a0e0fff..1f5adc0 100644
--- a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
+++ b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
@@ -136,10 +136,18 @@
$log.warn('SvgUtilService: cat7 -- To Be Implemented');
}
+ function translate(x, y) {
+ if (fs.isA(x) && x.length === 2 && !y) {
+ return 'translate(' + x[0] + ',' + x[1] + ')';
+ }
+ return 'translate(' + x + ',' + y + ')';
+ }
+
return {
createDragBehavior: createDragBehavior,
loadGlow: loadGlow,
- cat7: cat7
+ cat7: cat7,
+ translate: translate
};
}]);
}());
diff --git a/web/gui/src/main/webapp/app/index.html b/web/gui/src/main/webapp/app/index.html
index 92b1712..738c967 100644
--- a/web/gui/src/main/webapp/app/index.html
+++ b/web/gui/src/main/webapp/app/index.html
@@ -66,6 +66,7 @@
<link rel="stylesheet" href="onos.css">
<link rel="stylesheet" href="common.css">
<link rel="stylesheet" href="fw/mast/mast.css">
+ <link rel="stylesheet" href="fw/svg/glyph.css">
<link rel="stylesheet" href="fw/svg/icon.css">
<link rel="stylesheet" href="fw/layer/panel.css">
<link rel="stylesheet" href="fw/nav/nav.css">
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 785df8c..d7e7ec3 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -56,17 +56,6 @@
height: 42px;
}
-#topo-p-summary svg .glyphIcon {
- stroke: none;
- fill-rule: evenodd;
-}
-.light #topo-p-summary svg .glyphIcon {
- fill: black;
-}
-.dark #topo-p-summary svg .glyphIcon {
- fill: #ddd;
-}
-
#topo-p-summary h2 {
position: absolute;
margin: 0 4px;
diff --git a/web/gui/src/main/webapp/app/view/topo/topoPanel.js b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
index d05dc3e..efc195f 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
@@ -23,7 +23,7 @@
'use strict';
// injected refs
- var $log, ps;
+ var $log, ps, gs;
// constants
var idSum = 'topo-p-summary',
@@ -70,18 +70,15 @@
function populateSummary(data) {
summaryPanel.empty();
- var svg = summaryPanel.append('svg').attr({
- width: 40,
- height: 40
- }).style('background-color', 'goldenrod'),
- iid = '#' + (data.type || 'unknown');
+ var svg = summaryPanel.append('svg'); //.style('background-color', 'goldenrod'),
+ //iid = '#' + (data.type || 'unknown');
var title = summaryPanel.append('h2'),
table = summaryPanel.append('table'),
tbody = table.append('tbody');
- // append glyph iid to SVG // black fill
- // append glyph bird to SVG // white fill
+ gs.addGlyph(svg, 'node', 40);
+ gs.addGlyph(svg, 'bird', 24, true, [8,12]);
title.text(data.id);
@@ -103,11 +100,12 @@
angular.module('ovTopo')
.factory('TopoPanelService',
- ['$log', 'PanelService',
+ ['$log', 'PanelService', 'GlyphService',
- function (_$log_, _ps_) {
+ function (_$log_, _ps_, _gs_) {
$log = _$log_;
ps = _ps_;
+ gs = _gs_;
function initPanels() {
summaryPanel = ps.createPanel(idSum, panelOpts);
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
index 587d617..b72de5a 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/glyph-spec.js
@@ -18,7 +18,7 @@
ONOS GUI -- SVG -- Glyph Service - Unit Tests
*/
describe('factory: fw/svg/glyph.js', function() {
- var $log, fs, gs, d3Elem;
+ var $log, fs, gs, d3Elem, svg;
var numBaseGlyphs = 13,
vbBird = '352 224 113 112',
@@ -47,13 +47,16 @@
beforeEach(module('onosUtil', 'onosSvg'));
beforeEach(inject(function (_$log_, FnService, GlyphService) {
+ var body = d3.select('body');
$log = _$log_;
fs = FnService;
gs = GlyphService;
- d3Elem = d3.select('body').append('defs').attr('id', 'myDefs');
+ d3Elem = body.append('defs').attr('id', 'myDefs');
+ svg = body.append('svg').attr('id', 'mySvg');
}));
afterEach(function () {
+ d3.select('#mySvg').remove();
d3.select('#myDefs').remove();
gs.clear();
});
@@ -64,7 +67,7 @@
it('should define api functions', function () {
expect(fs.areFunctions(gs, [
- 'clear', 'init', 'register', 'ids', 'glyph', 'loadDefs'
+ 'clear', 'init', 'register', 'ids', 'glyph', 'loadDefs', 'addGlyph'
])).toBeTruthy();
});
@@ -246,4 +249,40 @@
verifyLoadedInDom('chain', vbGlyph);
verifyLoadedInDom('node', vbGlyph);
});
+
+ it('should add a glyph with default size', function () {
+ gs.init();
+ gs.addGlyph(svg, 'crown');
+ var what = svg.selectAll('use');
+ expect(what.size()).toEqual(1);
+ expect(what.attr('width')).toEqual('40');
+ expect(what.attr('height')).toEqual('40');
+ expect(what.attr('xlink:href')).toEqual('#crown');
+ expect(what.classed('glyph')).toBeTruthy();
+ expect(what.classed('overlay')).toBeFalsy();
+ });
+
+ it('should add a glyph with given size', function () {
+ gs.init();
+ gs.addGlyph(svg, 'crown', 37);
+ var what = svg.selectAll('use');
+ expect(what.size()).toEqual(1);
+ expect(what.attr('width')).toEqual('37');
+ expect(what.attr('height')).toEqual('37');
+ expect(what.attr('xlink:href')).toEqual('#crown');
+ expect(what.classed('glyph')).toBeTruthy();
+ expect(what.classed('overlay')).toBeFalsy();
+ });
+
+ it('should add a glyph marked as overlay', function () {
+ gs.init();
+ gs.addGlyph(svg, 'crown', 20, true);
+ var what = svg.selectAll('use');
+ expect(what.size()).toEqual(1);
+ expect(what.attr('width')).toEqual('20');
+ expect(what.attr('height')).toEqual('20');
+ expect(what.attr('xlink:href')).toEqual('#crown');
+ expect(what.classed('glyph')).toBeTruthy();
+ expect(what.classed('overlay')).toBeTruthy();
+ });
});
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
index 7caa83e..964320b 100644
--- a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
@@ -39,8 +39,18 @@
it('should define api functions', function () {
expect(fs.areFunctions(sus, [
- 'createDragBehavior', 'loadGlow', 'cat7'
+ 'createDragBehavior', 'loadGlow', 'cat7', 'translate'
])).toBeTruthy();
});
+ // TODO: add unit tests for drag behavior etc.
+
+ it('should translate from two args', function () {
+ expect(sus.translate(1,2)).toEqual('translate(1,2)');
+ });
+
+ it('should translate from an array', function () {
+ expect(sus.translate([3,4])).toEqual('translate(3,4)');
+ });
+
});