Simon Hunt

GUI -- Completed icon directive definition, and wired up device view.

Change-Id: Ia3cf0655fb17d47adc54f9f4540bb25eacbaaa62
......@@ -59,20 +59,16 @@
// create icon directive, so that we can inject icons into
// HTML tables etc.
.directive('icon', ['GlyphService', function (gs) {
.directive('icon', ['IconService', function (is) {
return {
templateUrl: 'toBeDecided-iconContext.html',
restrict: 'A',
scope: {
iconId: '@'
},
link: function (scope, element, attrs) {
// TODO: implement this
// needs to pull out the parameters for the icon
// from the attributes of the element, and use those
// as arguments to the IconService.addIcon(...) call.
is.loadEmbeddedIcon(d3.select(element[0]), scope.iconId);
}
};
}]);
}());
......
......@@ -35,6 +35,7 @@
"devices": [{
"id": "of:0000000000000001",
"available": true,
"_iconid_available": "deviceOnline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -44,23 +45,38 @@
"protocol": "OF_10"
}
},
{
"id": "of:0000000000000004",
"available": true,
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
}]
{
"id": "of:0000000000000004",
"available": false,
"_iconid_available": "deviceOffline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
},
{
"id": "of:0000000000000092",
"available": false,
"_iconid_available": "deviceOffline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.0.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
}]
},
'2': {
"devices": [{
"id": "of:0000000000000002",
"available": true,
"_iconid_available": "deviceOnline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
......@@ -70,18 +86,19 @@
"protocol": "OF_10"
}
},
{
"id": "of:0000000000000006",
"available": true,
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.1.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
}]
{
"id": "of:0000000000000006",
"available": true,
"_iconid_available": "deviceOnline",
"role": "MASTER",
"mfr": "Nicira, Inc.",
"hw": "Open vSwitch",
"sw": "2.1.1",
"serial": "None",
"annotations": {
"protocol": "OF_10"
}
}]
},
'empty': {
devices: []
......
......@@ -168,16 +168,25 @@
}
// Note: defs should be a D3 selection of a single <defs> element
function loadDefs(defs, glyphIds) {
var list = fs.isA(glyphIds) || ids();
function loadDefs(defs, glyphIds, noClear) {
var list = fs.isA(glyphIds) || ids(),
clearCache = !noClear;
// remove all existing content
defs.html(null);
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);
......
/*
* 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 -- Icon Service -- CSS file
*/
svg.embeddedIcon .icon .glyph {
stroke: none;
fill: white;
fill-rule: evenodd;
}
svg.embeddedIcon .icon.deviceOnline {
fill: green;
}
svg.embeddedIcon .icon.deviceOffline {
fill: darkred;
}
svg.embeddedIcon .icon rect {
stroke: black;
stroke-width: 1px;
}
......@@ -22,53 +22,89 @@
(function () {
'use strict';
var $log, fs;
var $log, fs, gs;
var viewBoxDim = 50,
viewBox = '0 0 ' + viewBoxDim + ' ' + viewBoxDim;
var vboxSize = 50,
cornerSize = vboxSize / 10,
viewBox = '0 0 ' + vboxSize + ' ' + vboxSize;
// maps icon id to the glyph id it uses.
// note: icon id maps to a CSS class for styling that icon
var glyphMapping = {
deviceOnline: 'checkMark',
deviceOffline: 'xMark'
deviceOnline: 'crown',
deviceOffline: 'chain'
//deviceOnline: 'checkMark',
//deviceOffline: 'xMark'
};
function ensureIconLibDefs() {
var body = d3.select('body'),
svg = body.select('svg#IconLibDefs'),
defs;
if (svg.empty()) {
svg = body.append('svg').attr('id', 'IconLibDefs');
defs = svg.append('defs');
}
return svg.select('defs');
}
angular.module('onosSvg')
.factory('IconService', ['$log', 'FnService', function (_$log_, _fs_) {
.factory('IconService', ['$log', 'FnService', 'GlyphService',
function (_$log_, _fs_, _gs_) {
$log = _$log_;
fs = _fs_;
gs = _gs_;
// div is a D3 selection of the <DIV> element into which icon should load
// iconCls is the CSS class used to identify the icon
// size is dimension of icon in pixels. Defaults to 20.
function loadIcon(div, iconCls, size) {
// installGlyph, if truthy, will cause the glyph to be added to
// well-known defs element. Defaults to false.
// svgClass is the CSS class used to identify the SVG layer.
// Defaults to 'embeddedIcon'.
function loadIcon(div, iconCls, size, installGlyph, svgClass) {
var dim = size || 20,
gid = glyphMapping[iconCls] || 'unknown';
svgCls = svgClass || 'embeddedIcon',
gid = glyphMapping[iconCls] || 'unknown',
svg, g;
var svg = div.append('svg').attr({
if (installGlyph) {
gs.loadDefs(ensureIconLibDefs(), [gid], true);
}
svg = div.append('svg').attr({
'class': svgCls,
width: dim,
height: dim,
viewBox: viewBox
});
var g = svg.append('g').attr({
g = svg.append('g').attr({
'class': 'icon ' + iconCls
});
g.append('rect').attr({
width: viewBoxDim,
height: viewBoxDim,
rx: 4
width: vboxSize,
height: vboxSize,
rx: cornerSize
});
g.append('use').attr({
width: viewBoxDim,
height: viewBoxDim,
width: vboxSize,
height: vboxSize,
'class': 'glyph',
'xlink:href': '#' + gid
});
}
function loadEmbeddedIcon(div, iconCls, size) {
loadIcon(div, iconCls, size, true);
}
return {
loadIcon: loadIcon
loadIcon: loadIcon,
loadEmbeddedIcon: loadEmbeddedIcon
};
}]);
......
......@@ -58,6 +58,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/icon.css">
<link rel="stylesheet" href="fw/nav/nav.css">
<!-- This is where contributed javascript will get injected -->
......
......@@ -4,17 +4,19 @@
<table class="summary-list">
<tr>
<th></th>
<th>ID</th>
<th>Manufacturer</th>
<th>Hardware Version</th>
<th>Software Version</th>
</tr>
<tr ng-repeat="dev in ctrl.deviceData">
<!-- add more property fields for table from device data -->
<td><div icon icon-id="{{dev._iconid_available}}"></div></td>
<td>{{dev.id}}</td>
<td>{{dev.mfr}}</td>
<td>{{dev.hw}}</td>
<td>{{dev.sw}}</td>
<!-- add more property fields for table from device data -->
</tr>
</table>
......
......@@ -65,7 +65,7 @@ describe('factory: fw/svg/icon.js', function() {
var rect = g.select('rect');
expect(rect.size()).toBe(1);
checkElemSize(rect, gsz);
expect(rect.attr('rx')).toEqual('4');
expect(rect.attr('rx')).toEqual('5');
var use = g.select('use');
expect(use.classed('glyph')).toBeTruthy();
......