blob: 7e8adb46a91e4200c8f94ad33be30365f2bc601f [file] [log] [blame]
Sean Condon83fc39f2018-04-19 18:56:13 +01001/*
2 * Copyright 2015-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import { Injectable } from '@angular/core';
17import { FnService } from '../../fw/util/fn.service';
18import { LogService } from '../../log.service';
19import * as gds from './glyphdata.service';
20import * as d3 from 'd3';
21
22// constants
23const msgGS = 'GlyphService.';
24const rg = 'registerGlyphs(): ';
25const rgs = 'registerGlyphSet(): ';
26
27/**
28 * ONOS GUI -- SVG -- Glyph Service
29 */
30@Injectable()
31export class GlyphService {
32 // internal state
33 glyphs = d3.map();
34
35 constructor(
36 private fs: FnService,
37// private gd: GlyphDataService,
38 private log: LogService
39 ) {
40 this.clear();
41 this.init();
42 this.log.debug('GlyphService constructed');
43 }
44
45 warn(msg: string): void {
46 this.log.warn(msgGS + msg);
47 }
48
49 addToMap(key, value, vbox, overwrite: boolean, dups) {
50 if (!overwrite && this.glyphs.get(key)) {
51 dups.push(key);
52 } else {
53 this.glyphs.set(key, { id: key, vb: vbox, d: value });
54 }
55 }
56
57 reportDups(dups: string[], which: string): boolean {
58 const ok: boolean = (dups.length === 0);
59 const msg = 'ID collision: ';
60
61 if (!ok) {
62 dups.forEach((id) => {
63 this.warn(which + msg + '"' + id + '"');
64 });
65 }
66 return ok;
67 }
68
69 reportMissVb(missing: string[], which: string): boolean {
70 const ok: boolean = (missing.length === 0);
71 const msg = 'Missing viewbox property: ';
72
73 if (!ok) {
74 missing.forEach((vbk) => {
75 this.warn(which + msg + '"' + vbk + '"');
76 });
77 }
78 return ok;
79 }
80
81 clear() {
82 // start with a fresh map
83 this.glyphs = d3.map();
84 }
85
86 init() {
87 this.log.info('Registering glyphs');
88 this.registerGlyphs(gds.logos);
89 this.registerGlyphSet(gds.glyphDataSet);
90 this.registerGlyphSet(gds.badgeDataSet);
91 this.registerGlyphs(gds.spriteData);
92 this.registerGlyphSet(gds.mojoDataSet);
93 this.registerGlyphs(gds.extraGlyphs);
94 }
95
96 registerGlyphs(data: Map<string, string>, overwrite: boolean = false): boolean {
97 const dups: string[] = [];
98 const missvb: string[] = [];
Sean Condon49e15be2018-05-16 16:58:29 +010099 for (const [key, value] of data.entries()) {
Sean Condon83fc39f2018-04-19 18:56:13 +0100100 const vbk = '_' + key;
101 const vb = data.get(vbk);
102
103 if (key[0] !== '_') {
104 if (!vb) {
105 missvb.push(vbk);
106 continue;
107 }
108 this.addToMap(key, value, vb, overwrite, dups);
109 }
110 }
111 return this.reportDups(dups, rg) && this.reportMissVb(missvb, rg);
112 }
113
114 registerGlyphSet(data: Map<string, string>, overwrite: boolean = false): boolean {
115 const dups: string[] = [];
116 const vb: string = data.get('_viewbox');
117
118 if (!vb) {
119 this.warn(rgs + 'no "_viewbox" property found');
120 return false;
121 }
122
Sean Condon49e15be2018-05-16 16:58:29 +0100123 for (const [key, value] of data.entries()) {
Sean Condon83fc39f2018-04-19 18:56:13 +0100124// angular.forEach(data, function (value, key) {
125 if (key[0] !== '_') {
126 this.addToMap(key, value, vb, overwrite, dups);
127 }
128 }
129 return this.reportDups(dups, rgs);
130 }
131
132 ids() {
133 return this.glyphs.keys();
134 }
135
136 glyph(id) {
137 return this.glyphs.get(id);
138 }
139
140 glyphDefined(id) {
141 return this.glyphs.has(id);
142 }
143
144
145 /**
146 * Load definitions of a glyph
147 *
148 * Note: defs should be a D3 selection of a single <defs> element
149 */
150 loadDefs(defs, glyphIds: string[], noClear: boolean) {
151 const list = this.fs.isA(glyphIds) || this.ids();
152
153 if (!noClear) {
154 // remove all existing content
155 defs.html(null);
156 }
157
158 // load up the requested glyphs
159 list.forEach((id) => {
160 const g = this.glyph(id);
161 if (g) {
162 if (noClear) {
163 // quick exit if symbol is already present
164 // TODO: check if this should be a continue or break instead
165 if (defs.select('symbol#' + g.id).size() > 0) {
166 return;
167 }
168 }
169 defs.append('symbol')
170 .attr('id', g.id)
171 .attr('viewBox', g.vb)
172 .append('path')
173 .attr('d', g.d);
174 }
175 });
176 }
177}