| /* |
| * Copyright 2015-present Open Networking Foundation |
| * |
| * 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 -- Topology Sprite Module. |
| Defines behavior for loading sprites into the sprite layer. |
| */ |
| |
| (function () { |
| 'use strict'; |
| |
| // injected refs |
| var $log, fs, gs, sus, wss; |
| |
| // constants |
| var tssid = 'TopoSpriteService: ', |
| fontsize = 20; // default font size 20pt. |
| |
| // internal state |
| var spriteLayer, defsElement; |
| |
| |
| function registerPathsAsGlyphs(paths) { |
| var custom = {}, |
| ids = []; |
| |
| function mkd(d) { |
| return fs.isA(d) ? d.join('') : d; |
| } |
| |
| 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); |
| }); |
| |
| gs.registerGlyphs(custom); |
| gs.loadDefs(defsElement, ids, true); |
| } |
| |
| function applyStrokeStyle(s, use) { |
| var style; |
| if (s) { |
| style = {}; |
| angular.forEach(s, function (value, key) { |
| style['stroke-' + key] = value; |
| }); |
| use.style(style); |
| } |
| } |
| |
| function applyFillClass(f, use) { |
| use.classed('fill-' + f, true); |
| } |
| |
| function doSprite(spr, def, pathmeta) { |
| var pmeta = pathmeta[def.path], |
| c = spr.class || 'gray1', |
| p = spr.pos || [0, 0], |
| lab = spr.label, |
| dim = def.dim || [40, 40], |
| w = dim[0], |
| h = dim[1], |
| dy = def.labelyoff || 1, |
| sc = def.scale, |
| xfm = sus.translate(p), |
| g, attr, use; |
| |
| if (sc) { |
| xfm += sus.scale(sc, sc); |
| } |
| |
| g = spriteLayer.append('g') |
| .classed(c, true) |
| .attr('transform', xfm); |
| |
| attr = { |
| width: w, |
| height: h, |
| 'xlink:href': '#' + pmeta.u, |
| }; |
| |
| use = g.append('use').attr(attr); |
| applyStrokeStyle(pmeta.s, use); |
| applyFillClass(def.fill, use); |
| |
| |
| // add subpaths if they have been defined |
| if (fs.isA(def.subpaths)) { |
| def.subpaths.forEach(function (v) { |
| pmeta = pathmeta[v.path]; |
| attr = { |
| width: w, |
| height: h, |
| 'xlink:href': '#' + pmeta.u, |
| transform: sus.translate(v.pos), |
| }; |
| use = g.append('use').attr(attr); |
| applyStrokeStyle(pmeta.s, use); |
| applyFillClass(def.subpathfill, use); |
| }); |
| } |
| |
| if (lab) { |
| g.append('text') |
| .text(lab) |
| .attr({ x: w / 2, y: h * dy }); |
| } |
| } |
| |
| function doLabel(label) { |
| var c = label.class || 'gray1', |
| p = label.pos || [0, 0], |
| sz = label.size || 1.0; |
| |
| spriteLayer.append('g') |
| .classed(c, true) |
| .attr('transform', sus.translate(p)) |
| .append('text') |
| .text(label.text) |
| .style('font-size', (fontsize * sz)+'pt'); |
| } |
| |
| |
| // ========================== |
| // event handlers |
| |
| // Handles response from 'spriteListRequest' which lists all the |
| // registered sprite definitions on the server. |
| // (see onos-upload-sprites) |
| function inList(payload) { |
| $log.debug(tssid + 'Registered sprite definitions:', payload.names); |
| // Some day, we will make this list available to the user in |
| // a dropdown selection box... |
| } |
| |
| // Handles response from 'spriteDataRequest' which provides the |
| // data for the requested sprite definition. |
| function inData(payload) { |
| var data = payload.data, |
| name, desc, pfx, sprites, labels, alpha, |
| paths, defn, load, |
| pathmeta = {}, |
| defs = {}, |
| warn = []; |
| |
| if (!data) { |
| $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); |
| |
| 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; |
| } |
| |
| // 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; |
| }); |
| |
| // 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]; |
| doSprite(spr, def, pathmeta); |
| }); |
| } |
| |
| if (labels) { |
| labels.forEach(doLabel); |
| } |
| } |
| |
| |
| function loadSprites(layer, defsElem, defname) { |
| var name = defname || 'sprites'; |
| spriteLayer = layer; |
| defsElement = defsElem; |
| |
| $log.info(tssid + 'Requesting sprite definition ['+name+']...'); |
| |
| wss.sendEvent('spriteListRequest'); |
| wss.sendEvent('spriteDataRequest', { name: name }); |
| } |
| |
| // === ----------------------------------------------------- |
| // === MODULE DEFINITION === |
| |
| angular.module('ovTopo') |
| .factory('TopoSpriteService', |
| ['$log', 'FnService', 'GlyphService', |
| 'SvgUtilService', 'WebSocketService', |
| |
| function (_$log_, _fs_, _gs_, _sus_, _wss_) { |
| $log = _$log_; |
| fs = _fs_; |
| gs = _gs_; |
| sus = _sus_; |
| wss = _wss_; |
| |
| return { |
| loadSprites: loadSprites, |
| spriteListResponse: inList, |
| spriteDataResponse: inData, |
| }; |
| }]); |
| |
| }()); |