GUI -- Implemented loadIcon() in the IconService.
Change-Id: Ib19e9ee01d0c015a2ba6f0431bc0d84adf530efd
Showing
3 changed files
with
98 additions
and
6 deletions
| ... | @@ -72,7 +72,7 @@ | ... | @@ -72,7 +72,7 @@ |
| 72 | 72 | ||
| 73 | <div> | 73 | <div> |
| 74 | <table class="summary-list"> | 74 | <table class="summary-list"> |
| 75 | - <tr> <th>One</th> <th>Two</th> <th>Three</th> </tr> | 75 | + <tr> <th></th> <th>Two</th> <th>Three</th> </tr> |
| 76 | <tr> | 76 | <tr> |
| 77 | <td> | 77 | <td> |
| 78 | <div icon icon-id="deviceOnline"> | 78 | <div icon icon-id="deviceOnline"> | ... | ... |
| ... | @@ -22,14 +22,53 @@ | ... | @@ -22,14 +22,53 @@ |
| 22 | (function () { | 22 | (function () { |
| 23 | 'use strict'; | 23 | 'use strict'; |
| 24 | 24 | ||
| 25 | - var $log; | 25 | + var $log, fs; |
| 26 | + | ||
| 27 | + var viewBoxDim = 50, | ||
| 28 | + viewBox = '0 0 ' + viewBoxDim + ' ' + viewBoxDim; | ||
| 29 | + | ||
| 30 | + // maps icon id to the glyph id it uses. | ||
| 31 | + // note: icon id maps to a CSS class for styling that icon | ||
| 32 | + var glyphMapping = { | ||
| 33 | + deviceOnline: 'checkMark', | ||
| 34 | + deviceOffline: 'xMark' | ||
| 35 | + }; | ||
| 26 | 36 | ||
| 27 | angular.module('onosSvg') | 37 | angular.module('onosSvg') |
| 28 | - .factory('IconService', ['$log', function (_$log_) { | 38 | + .factory('IconService', ['$log', 'FnService', function (_$log_, _fs_) { |
| 29 | $log = _$log_; | 39 | $log = _$log_; |
| 40 | + fs = _fs_; | ||
| 41 | + | ||
| 42 | + // div is a D3 selection of the <DIV> element into which icon should load | ||
| 43 | + // iconCls is the CSS class used to identify the icon | ||
| 44 | + // size is dimension of icon in pixels. Defaults to 20. | ||
| 45 | + function loadIcon(div, iconCls, size) { | ||
| 46 | + var dim = size || 20, | ||
| 47 | + gid = glyphMapping[iconCls] || 'unknown'; | ||
| 48 | + | ||
| 49 | + var svg = div.append('svg').attr({ | ||
| 50 | + width: dim, | ||
| 51 | + height: dim, | ||
| 52 | + viewBox: viewBox | ||
| 53 | + }); | ||
| 54 | + var g = svg.append('g').attr({ | ||
| 55 | + 'class': 'icon ' + iconCls | ||
| 56 | + }); | ||
| 57 | + g.append('rect').attr({ | ||
| 58 | + width: viewBoxDim, | ||
| 59 | + height: viewBoxDim, | ||
| 60 | + rx: 4 | ||
| 61 | + }); | ||
| 62 | + g.append('use').attr({ | ||
| 63 | + width: viewBoxDim, | ||
| 64 | + height: viewBoxDim, | ||
| 65 | + 'class': 'glyph', | ||
| 66 | + 'xlink:href': '#' + gid | ||
| 67 | + }); | ||
| 68 | + } | ||
| 30 | 69 | ||
| 31 | return { | 70 | return { |
| 32 | - tbd: function () {} | 71 | + loadIcon: loadIcon |
| 33 | }; | 72 | }; |
| 34 | }]); | 73 | }]); |
| 35 | 74 | ... | ... |
| ... | @@ -20,17 +20,70 @@ | ... | @@ -20,17 +20,70 @@ |
| 20 | @author Simon Hunt | 20 | @author Simon Hunt |
| 21 | */ | 21 | */ |
| 22 | describe('factory: fw/svg/icon.js', function() { | 22 | describe('factory: fw/svg/icon.js', function() { |
| 23 | - var is; | 23 | + var is, d3Elem; |
| 24 | + | ||
| 25 | + var viewBox = '0 0 50 50', | ||
| 26 | + glyphSize = '50', | ||
| 27 | + iconSize = '20'; | ||
| 28 | + | ||
| 24 | 29 | ||
| 25 | beforeEach(module('onosSvg')); | 30 | beforeEach(module('onosSvg')); |
| 26 | 31 | ||
| 27 | beforeEach(inject(function (IconService) { | 32 | beforeEach(inject(function (IconService) { |
| 28 | is = IconService; | 33 | is = IconService; |
| 34 | + d3Elem = d3.select('body').append('div').attr('id', 'myDiv'); | ||
| 29 | })); | 35 | })); |
| 30 | 36 | ||
| 37 | + afterEach(function () { | ||
| 38 | + d3.select('#myDiv').remove(); | ||
| 39 | + }); | ||
| 40 | + | ||
| 31 | it('should define IconService', function () { | 41 | it('should define IconService', function () { |
| 32 | expect(is).toBeDefined(); | 42 | expect(is).toBeDefined(); |
| 33 | }); | 43 | }); |
| 34 | 44 | ||
| 35 | - // TODO: unit tests for icon functions | 45 | + function checkElemSize(elem, dim) { |
| 46 | + expect(elem.attr('width')).toEqual(dim); | ||
| 47 | + expect(elem.attr('height')).toEqual(dim); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + function verifyIconStructure(iconClass, useHref, iSize, vBox, gSize) { | ||
| 51 | + var isz = iSize || iconSize, | ||
| 52 | + vbx = vBox || viewBox, | ||
| 53 | + gsz = gSize || glyphSize; | ||
| 54 | + | ||
| 55 | + var svg = d3Elem.selectAll('svg'); | ||
| 56 | + expect(svg.size()).toBe(1); | ||
| 57 | + checkElemSize(svg, isz); | ||
| 58 | + expect(svg.attr('viewBox')).toEqual(vbx); | ||
| 59 | + | ||
| 60 | + var g = svg.selectAll('g'); | ||
| 61 | + expect(g.size()).toBe(1); | ||
| 62 | + expect(g.classed('icon')).toBeTruthy(); | ||
| 63 | + expect(g.classed(iconClass)).toBeTruthy(); | ||
| 64 | + | ||
| 65 | + var rect = g.select('rect'); | ||
| 66 | + expect(rect.size()).toBe(1); | ||
| 67 | + checkElemSize(rect, gsz); | ||
| 68 | + expect(rect.attr('rx')).toEqual('4'); | ||
| 69 | + | ||
| 70 | + var use = g.select('use'); | ||
| 71 | + expect(use.classed('glyph')).toBeTruthy(); | ||
| 72 | + expect(use.attr('xlink:href')).toEqual(useHref); | ||
| 73 | + checkElemSize(use, gsz); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + it('should load an icon into a div', function () { | ||
| 78 | + expect(d3Elem.html()).toEqual(''); | ||
| 79 | + is.loadIcon(d3Elem, 'deviceOnline'); | ||
| 80 | + verifyIconStructure('deviceOnline', '#checkMark'); | ||
| 81 | + }); | ||
| 82 | + | ||
| 83 | + it('should allow us to specify the icon size', function () { | ||
| 84 | + expect(d3Elem.html()).toEqual(''); | ||
| 85 | + is.loadIcon(d3Elem, 'deviceOffline', 32); | ||
| 86 | + verifyIconStructure('deviceOffline', '#xMark', '32'); | ||
| 87 | + }); | ||
| 88 | + | ||
| 36 | }); | 89 | }); | ... | ... |
-
Please register or login to post a comment