| /* |
| * Copyright 2015-present 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 -- SVG -- Icon Service |
| */ |
| (function () { |
| 'use strict'; |
| |
| var $log, fs, gs, sus; |
| |
| 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 = { |
| active: 'checkMark', |
| inactive: 'xMark', |
| |
| plus: 'plus', |
| minus: 'minus', |
| play: 'play', |
| stop: 'stop', |
| |
| close: 'xClose', |
| |
| topo: 'topo', |
| |
| refresh: 'refresh', |
| query: 'query', |
| garbage: 'garbage', |
| |
| upArrow: 'triangleUp', |
| downArrow: 'triangleDown', |
| |
| appInactive: 'unknown', |
| |
| node: 'node', |
| devIcon_SWITCH: 'switch', |
| devIcon_ROADM: 'roadm', |
| devIcon_OTN: 'otn', |
| deviceTable: 'switch', |
| flowTable: 'flowTable', |
| portTable: 'portTable', |
| groupTable: 'groupTable', |
| meterTable: 'meterTable', |
| |
| hostIcon_endstation: 'endstation', |
| hostIcon_router: 'router', |
| hostIcon_bgpSpeaker: 'bgpSpeaker', |
| |
| // navigation menu icons... |
| nav_apps: 'bird', |
| nav_settings: 'cog', |
| nav_cluster: 'node', |
| nav_processors: 'allTraffic', |
| |
| nav_topo: 'topo', |
| nav_devs: 'switch', |
| nav_links: 'ports', |
| nav_hosts: 'endstation', |
| nav_intents: 'relatedIntents', |
| nav_tunnels: 'ports' // TODO: use tunnel glyph, when available |
| }; |
| |
| function ensureIconLibDefs() { |
| var body = d3.select('body'), |
| svg = body.select('svg#IconLibDefs'); |
| |
| if (svg.empty()) { |
| svg = body.append('svg').attr('id', 'IconLibDefs'); |
| svg.append('defs'); |
| } |
| return svg.select('defs'); |
| } |
| |
| // div is a D3 selection of the <DIV> element into which icon should load |
| // glyphId identifies the glyph to use |
| // size is dimension of icon in pixels. Defaults to 20. |
| // 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, glyphId, size, installGlyph, svgClass) { |
| var dim = size || 20, |
| svgCls = svgClass || 'embeddedIcon', |
| gid = glyphId || 'unknown', |
| svg, g; |
| |
| if (installGlyph) { |
| gs.loadDefs(ensureIconLibDefs(), [gid], true); |
| } |
| |
| svg = div.append('svg').attr({ |
| 'class': svgCls, |
| width: dim, |
| height: dim, |
| viewBox: viewBox |
| }); |
| |
| g = svg.append('g').attr({ |
| 'class': 'icon' |
| }); |
| |
| g.append('rect').attr({ |
| width: vboxSize, |
| height: vboxSize, |
| rx: cornerSize |
| }); |
| |
| g.append('use').attr({ |
| width: vboxSize, |
| height: vboxSize, |
| 'class': 'glyph', |
| 'xlink:href': '#' + gid |
| }); |
| } |
| |
| // 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. |
| // 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 loadIconByClass(div, iconCls, size, installGlyph, svgClass) { |
| loadIcon(div, glyphMapping[iconCls], size, installGlyph, svgClass); |
| div.select('svg g').classed(iconCls, true); |
| } |
| |
| function loadEmbeddedIcon(div, iconCls, size) { |
| loadIconByClass(div, iconCls, size, true); |
| } |
| |
| // Adds a device glyph to the specified element. |
| // Returns the D3 selection of the glyph (use) element. |
| function addDeviceIcon(elem, glyphId, iconDim) { |
| var gid = gs.glyphDefined(glyphId) ? glyphId : 'query'; |
| return elem.append('use').attr({ |
| 'xlink:href': '#' + gid, |
| width: iconDim, |
| height: iconDim |
| }); |
| } |
| |
| function addHostIcon(elem, radius, glyphId) { |
| var dim = radius * 1.5, |
| xlate = -dim / 2, |
| g = elem.append('g') |
| .attr('class', 'svgIcon hostIcon'); |
| |
| g.append('circle').attr('r', radius); |
| |
| g.append('use').attr({ |
| 'xlink:href': '#' + glyphId, |
| width: dim, |
| height: dim, |
| transform: sus.translate(xlate,xlate) |
| }); |
| return g; |
| } |
| |
| function sortIcons() { |
| function _s(div, gid) { |
| div.style('display', 'inline-block'); |
| loadEmbeddedIcon(div, gid, 10); |
| div.classed('tableColSort', true); |
| } |
| |
| return { |
| asc: function (div) { _s(div, 'upArrow'); }, |
| desc: function (div) { _s(div, 'downArrow'); }, |
| none: function (div) { div.remove(); } |
| }; |
| } |
| |
| function registerIconMapping(iconId, glyphId) { |
| if (glyphMapping[iconId]) { |
| $log.warn('Icon with id', iconId, 'already mapped. Ignoring.'); |
| } else { |
| // map icon-->glyph |
| glyphMapping[iconId] = glyphId; |
| // make sure definition is installed |
| gs.loadDefs(ensureIconLibDefs(), [glyphId], true); |
| } |
| } |
| |
| // ========================= |
| // === DEFINE THE MODULE |
| |
| angular.module('onosSvg') |
| .directive('icon', ['IconService', function (is) { |
| return { |
| restrict: 'A', |
| link: function (scope, element, attrs) { |
| attrs.$observe('iconId', function () { |
| var div = d3.select(element[0]); |
| div.selectAll('*').remove(); |
| is.loadEmbeddedIcon(div, attrs.iconId, attrs.iconSize); |
| }); |
| } |
| }; |
| }]) |
| |
| .factory('IconService', ['$log', 'FnService', 'GlyphService', |
| 'SvgUtilService', |
| |
| function (_$log_, _fs_, _gs_, _sus_) { |
| $log = _$log_; |
| fs = _fs_; |
| gs = _gs_; |
| sus = _sus_; |
| |
| return { |
| loadIcon: loadIcon, |
| loadIconByClass: loadIconByClass, |
| loadEmbeddedIcon: loadEmbeddedIcon, |
| addDeviceIcon: addDeviceIcon, |
| addHostIcon: addHostIcon, |
| sortIcons: sortIcons, |
| registerIconMapping: registerIconMapping |
| }; |
| }]); |
| |
| }()); |