Simon Hunt

GUI - Converted Devices to use Glyph icons instead of png's.

Change-Id: I5d979f6e515168fda2c2eabe97780beaa5206691
1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <meta charset="utf-8">
5 + <title>Icons</title>
6 +
7 + <script src="../libs/d3.js"></script>
8 + <script src="../libs/topojson.v1.min.js"></script>
9 + <script src="../libs/jquery-2.1.1.min.js"></script>
10 +
11 + <style>
12 + html,
13 + body {
14 + background-color: #ddf;
15 + font-family: Arial, Helvetica, sans-serif;
16 + font-size: 9pt;
17 + }
18 +
19 + svg {
20 + background-color: #fff;
21 + }
22 +
23 + svg .glyph {
24 + stroke: none;
25 + fill: black;
26 + fill-rule: evenodd;
27 + }
28 +
29 + svg .device rect.iconBg {
30 + fill: #ddd;
31 + stroke: #000;
32 + }
33 +
34 + .hide {
35 + visibility: hidden;
36 + }
37 +
38 + </style>
39 +</head>
40 +<body>
41 + <svg width="1000px" height="600px" viewBox="0 0 1000 600" >
42 + <defs>
43 + <symbol id="router" class="glyph" viewBox="-55 -55 110 110">
44 + <path d="M-45 0 A45 45 0 0 1 45 0 A45 45 0 0 1 -45 0
45 + M -35 -5 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
46 + M 35 -5 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
47 + M -5 -8 l 0 -12, -8 0, 13 -18, 13 18, -8 0, 0 12 z
48 + M -5 8 l 0 12, -8 0, 13 18, 13 -18, -8 0, 0 -12 z
49 + "></path>
50 + </symbol>
51 +
52 + <symbol id="bgpSpeaker" class="glyph" viewBox="-55 -55 110 110">
53 + <path d="M-45 -15
54 + a45 35 0 0 1 90 0
55 + Q45 22 0 45
56 + Q-45 22 -45 -15
57 + z
58 +
59 + M -5 -26 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
60 + M 5 2 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
61 +
62 + "></path>
63 + <!-- a45 45 0 0 1 -10 30
64 + -->
65 + </symbol>
66 +
67 + <symbol id="switch" class="glyph" viewBox="-55 -55 110 110">
68 + <path d="M-45 -35 a10 10 0 0 1 10 -10 h70
69 + a 10 10 0 0 1 10 10 v70
70 + a 10 10 0 0 1 -10 10 h -70
71 + a 10 10 0 0 1 -10 -10 z
72 + M 5 -29 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
73 + M 5 5 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
74 + M -5 -15 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
75 + M -5 19 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
76 + "></path>
77 + </symbol>
78 +
79 + <symbol id="roadm" class="glyph" viewBox="-55 -55 110 110">
80 + <path d="M-45 -20 l25 -25 h40 l25 25 v40
81 + l-25 25 h-40 l-25 -25 z
82 +
83 + M 3 -29 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
84 + M 3 5 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z
85 + M -3 -15 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
86 + M -3 19 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z
87 + "></path>
88 + </symbol>
89 +
90 + <symbol id="node" class="glyph" viewBox="-55 -55 110 110">
91 + <path d="M-40 45 a5 5 0 0 1 -5 -5 v-65 a5 5 0 0 1 5 -5
92 + h80 a5 5 0 0 1 5 5 v65 a5 5 0 0 1 -5 5 z
93 + M-41 -32.5 l11 -11 a10 3 0 0 1 10 -2 h40
94 + a10 3 0 0 1 10 2 l11 11 z
95 + M-39 -20 a5 5 0 0 1 10 0 a5 5 0 0 1 -10 0 z
96 + "></path>
97 + </symbol>
98 +
99 + <symbol id="nodeSlave" class="glyph" viewBox="-55 -55 110 110">
100 + <path d="M-40 45 a5 5 0 0 1 -5 -5 v-65 a5 5 0 0 1 5 -5
101 + h80 a5 5 0 0 1 5 5 v65 a5 5 0 0 1 -5 5 z
102 + M-41 -32.5 l11 -11 a10 3 0 0 1 10 -2 h40
103 + a10 3 0 0 1 10 2 l11 11 z
104 + M-39 -20 a5 5 0 0 1 10 0 a5 5 0 0 1 -10 0 z
105 +
106 + M-6 -6
107 + l6 -6
108 + a8.485 8.485 0 0 1 12 12
109 + l-6 6
110 + a8.485 8.485 0 0 1 -13 -2
111 + l3 -3
112 + a4 4 0 0 0 6 1
113 + l8 -8
114 + a2.8 2.8 0 0 0 -5 -5
115 + l-5 5
116 + z
117 +
118 + "></path>
119 + </symbol>
120 +
121 + <symbol id="host" class="glyph" viewBox="-55 -55 110 110">
122 + <path d="M-45 -40 a5 5 0 0 1 5 -5 h65 a5 5 0 0 1 5 5
123 + v80 a5 5 0 0 1 -5 5 h-65 a5 5 0 0 1 -5 -5 z
124 + M32.5 -41 l11 11 a3 10 0 0 1 2 10 v40
125 + a3 10 0 0 1 -2 10 l-11 11 z
126 +
127 + M-38 -36
128 + a2 2 0 0 1 2 -2 h56
129 + a2 2 0 0 1 2 2 v26
130 + a2 2 0 0 1 -2 2 h-56
131 + a2 2 0 0 1 -2 -2
132 + z
133 +
134 + M-35 -35 h54 v10 h-54 z
135 + M-35 -22 h54 v10 h-54 z
136 +
137 + M-13 15 a5 5 0 0 1 10 0 a5 5 0 0 1 -10 0 z
138 + "></path>
139 + </symbol>
140 +
141 + <symbol id="unknown" class="glyph" viewBox="-55 -55 110 110">
142 + <path d="M-20 -15 a5 5 0 0 1 5 -5 h30 a5 5 0 0 1 5 5 v30 a5 5 0 0 1 -5 5 h-30 a5 5 0 0 1 -5 -5 z "></path>
143 + </symbol>
144 +
145 +
146 +
147 +
148 + </defs>
149 +
150 +
151 + <g transform="translate(10,10)scale(4)translate(0,20)" >
152 +
153 + <g class="hide">
154 + <!--link-->
155 + <path fill="#010101" d="M459.654,233.373l-90.531,90.5c-49.969,50-131.031,50-181,0c-7.875-7.844-14.031-16.688-19.438-25.813
156 + l42.063-42.063c2-2.016,4.469-3.172,6.828-4.531c2.906,9.938,7.984,19.344,15.797,27.156c24.953,24.969,65.563,24.938,90.5,0
157 + l90.5-90.5c24.969-24.969,24.969-65.563,0-90.516c-24.938-24.953-65.531-24.953-90.5,0l-32.188,32.219
158 + c-26.109-10.172-54.25-12.906-81.641-8.891l68.578-68.578c50-49.984,131.031-49.984,181.031,0
159 + C509.623,102.342,509.623,183.389,459.654,233.373z M220.326,382.186l-32.203,32.219c-24.953,24.938-65.563,24.938-90.516,0
160 + c-24.953-24.969-24.953-65.563,0-90.531l90.516-90.5c24.969-24.969,65.547-24.969,90.5,0c7.797,7.797,12.875,17.203,15.813,27.125
161 + c2.375-1.375,4.813-2.5,6.813-4.5l42.063-42.047c-5.375-9.156-11.563-17.969-19.438-25.828c-49.969-49.984-131.031-49.984-181.016,0
162 + l-90.5,90.5c-49.984,50-49.984,131.031,0,181.031c49.984,49.969,131.031,49.969,181.016,0l68.594-68.594
163 + C274.561,395.092,246.42,392.342,220.326,382.186z"></path>
164 +
165 +
166 + <!--crown-->
167 + <path d="M94.257,32.808c0,4.466-3.62,8.085-8.085,8.085c-0.495,0-0.979-0.051-1.449-0.136l-6.637,23.695v8.518H21.914v-8.849
168 + l-6.579-23.373c-0.489,0.092-0.992,0.145-1.507,0.145c-4.465,0-8.085-3.619-8.085-8.085c0-4.466,3.62-8.086,8.085-8.086
169 + c4.465,0,8.085,3.62,8.085,8.086c0,1.099-0.222,2.146-0.619,3.102c8.078,2.726,20.551,4.947,26.163-4.449
170 + c-3.219-1.066-5.543-4.095-5.543-7.671c0-4.466,3.62-8.086,8.085-8.086s8.085,3.62,8.085,8.086c0,3.573-2.32,6.6-5.536,7.669
171 + c3.276,6.052,10.577,12.374,26.494,5.165c-0.608-1.137-0.957-2.435-0.957-3.815c0-4.466,3.62-8.086,8.085-8.086
172 + S94.257,28.342,94.257,32.808z M21.915,84.297h56.173v-7.658H21.915V84.297z"></path>
173 + </g>
174 +
175 +
176 + <g class="show">
177 + <g class="device" transform="translate(0,0)">
178 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
179 + <use xlink:href="#router" width="40" height="40"></use>
180 + </g>
181 +
182 + <g class="device" transform="translate(50,0)">
183 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
184 + <use xlink:href="#switch" width="40" height="40"></use>
185 + </g>
186 +
187 + <g class="device" transform="translate(100,0)">
188 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
189 + <use xlink:href="#roadm" width="40" height="40"></use>
190 + </g>
191 +
192 + <g class="device" transform="translate(0,50)">
193 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
194 + <use xlink:href="#node" width="40" height="40"></use>
195 + </g>
196 +
197 + <g class="device" transform="translate(50,50)">
198 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
199 + <use xlink:href="#host" width="40" height="40"></use>
200 + </g>
201 +
202 + <g class="device" transform="translate(100,50)">
203 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
204 + <use xlink:href="#bgpSpeaker" width="40" height="40"></use>
205 + </g>
206 +
207 + <g class="device" transform="translate(150,0)">
208 + <rect x="0" y="0" width="40" height="40" rx="4" class="iconBg"></rect>
209 + <use xlink:href="#unknown" width="40" height="40"></use>
210 + </g>
211 + </g>
212 + </g>
213 + </svg>
214 +</body>
215 +</html>
...@@ -65,10 +65,64 @@ ...@@ -65,10 +65,64 @@
65 .append('path').attr('d', bullhornData); 65 .append('path').attr('d', bullhornData);
66 } 66 }
67 67
68 + var glyphData = {
69 + unknown: "M-20 -15 a5 5 0 0 1 5 -5 h30 a5 5 0 0 1 5 5 v30 " +
70 + "a5 5 0 0 1 -5 5 h-30 a5 5 0 0 1 -5 -5 z ",
71 + router: "M-45 0 A45 45 0 0 1 45 0 A45 45 0 0 1 -45 0 M -35 -5 " +
72 + "l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M 35 -5 " +
73 + "l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z M -5 -8 " +
74 + "l 0 -12, -8 0, 13 -18, 13 18, -8 0, 0 12 z M -5 8 " +
75 + "l 0 12, -8 0, 13 18, 13 -18, -8 0, 0 -12 z ",
76 + bgpSpeaker: "M-45 -15 a45 35 0 0 1 90 0 Q45 22 0 45 Q-45 22 -45 -15 z " +
77 + "M -5 -26 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M 5 2" +
78 + " l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z ",
79 +
80 + switch: "M-45 -35 a10 10 0 0 1 10 -10 h70 a 10 10 0 0 1 10 10 v70 a 10 10 0 0 1 -10 10 h -70 a 10 10 0 0 1 -10 -10 z M 5 -29 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M 5 5 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M -5 -15 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z M -5 19 l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z",
81 +
82 +
83 + Xswitch: "M-45 -35 a10 10 0 0 1 10 -10 h70 a 10 10 0 0 1 10 10 v70 " +
84 + "a 10 10 0 0 1 -10 10 h -70 a 10 10 0 0 1 -10 -10 z M 5 -29 " +
85 + "l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M 5 5 " +
86 + "l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M -5 -15 " +
87 + "l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z M -5 19 " +
88 + "l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z " ,
89 + roadm: "M-45 -20 l25 -25 h40 l25 25 v40 l-25 25 h-40 l-25 -25 z " +
90 + "M 3 -29 l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M 3 5 " +
91 + "l 12 0, 0 -8, 18 13, -18 13, 0 -8, -12 0 z M -3 -15 " +
92 + "l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z M -3 19 " +
93 + "l -12 0, 0 -8, -18 13, 18 13, 0 -8, 12 0 z ",
94 + node: "M-40 45 a5 5 0 0 1 -5 -5 v-65 a5 5 0 0 1 5 -5 h80 " +
95 + "a5 5 0 0 1 5 5 v65 a5 5 0 0 1 -5 5 z M-41 -32.5 l11 -11 " +
96 + "a10 3 0 0 1 10 -2 h40 a10 3 0 0 1 10 2 l11 11 z M-39 -20 " +
97 + "a5 5 0 0 1 10 0 a5 5 0 0 1 -10 0 z ",
98 + host: "M-45 -40 a5 5 0 0 1 5 -5 h65 a5 5 0 0 1 5 5 v80 " +
99 + "a5 5 0 0 1 -5 5 h-65 a5 5 0 0 1 -5 -5 z M32.5 -41 l11 11 " +
100 + "a3 10 0 0 1 2 10 v40 a3 10 0 0 1 -2 10 l-11 11 z M-38 -36 " +
101 + "a2 2 0 0 1 2 -2 h56 a2 2 0 0 1 2 2 v26 a2 2 0 0 1 -2 2 h-56 " +
102 + "a2 2 0 0 1 -2 -2 z M-35 -35 h54 v10 h-54 z M-35 -22 h54 v10 " +
103 + "h-54 z M-13 15 a5 5 0 0 1 10 0 a5 5 0 0 1 -10 0 z "
104 + };
105 +
106 + var glyphParams = {
107 + viewBox: '-55 -55 110 110'
108 + };
109 +
110 + function defGlyphs(defs) {
111 + d3.map(glyphData).keys().forEach(function (key) {
112 + defs.append('symbol')
113 + .attr({
114 + id: key,
115 + viewBox: glyphParams.viewBox
116 + })
117 + .append('path').attr('d', glyphData[key]);
118 + });
119 + }
120 +
68 // === register the functions as a library 121 // === register the functions as a library
69 onos.ui.addLib('glyphs', { 122 onos.ui.addLib('glyphs', {
70 defBird: defBird, 123 defBird: defBird,
71 - defBullhorn: defBullhorn 124 + defBullhorn: defBullhorn,
125 + defGlyphs: defGlyphs
72 }); 126 });
73 127
74 }(ONOS)); 128 }(ONOS));
......
...@@ -30,9 +30,15 @@ ...@@ -30,9 +30,15 @@
30 fill: transparent; 30 fill: transparent;
31 } 31 }
32 32
33 +/* TODO: move glyphs into framework */
33 34
34 -#topo svg .glyph { 35 +#topo svg .glyphIcon {
35 - fill: white; 36 + fill: black;
37 + stroke: none;
38 + fill-rule: evenodd;
39 +}
40 +#topo svg .glyphIcon rect {
41 + fill: #ddd;
36 stroke: none; 42 stroke: none;
37 } 43 }
38 44
......
...@@ -80,7 +80,12 @@ ...@@ -80,7 +80,12 @@
80 w: 30, 80 w: 30,
81 h: 30, 81 h: 30,
82 xoff: -16, 82 xoff: -16,
83 - yoff: -14 83 + yoff: -14,
84 +
85 + device: {
86 + dim: 30,
87 + rx: 4
88 + }
84 }, 89 },
85 iconUrl: { 90 iconUrl: {
86 device: 'img/device.png', 91 device: 'img/device.png',
...@@ -1214,7 +1219,10 @@ ...@@ -1214,7 +1219,10 @@
1214 // start with the object as is 1219 // start with the object as is
1215 var node = device, 1220 var node = device,
1216 type = device.type, 1221 type = device.type,
1217 - svgCls = type ? 'node device ' + type : 'node device'; 1222 + svgCls = type ? 'node device ' + type : 'node device',
1223 + labels = device.labels || [];
1224 +
1225 + labels.unshift(''); // add 'no-label' to front of cycle
1218 1226
1219 // Augment as needed... 1227 // Augment as needed...
1220 node.class = 'device'; 1228 node.class = 'device';
...@@ -1222,6 +1230,9 @@ ...@@ -1222,6 +1230,9 @@
1222 positionNode(node); 1230 positionNode(node);
1223 1231
1224 // cache label array length 1232 // cache label array length
1233 + // TODO: need a uiConfig event from the server to set things
1234 + // like device labels count, host labels count, etc.
1235 + // The current method (here) is a little fragile
1225 network.deviceLabelCount = device.labels.length; 1236 network.deviceLabelCount = device.labels.length;
1226 return node; 1237 return node;
1227 } 1238 }
...@@ -1311,6 +1322,11 @@ ...@@ -1311,6 +1322,11 @@
1311 return 'img/' + d.type + '.png'; 1322 return 'img/' + d.type + '.png';
1312 } 1323 }
1313 1324
1325 + function iconGlyphUrl(d) {
1326 + var which = d.type || 'unknown';
1327 + return '#' + which;
1328 + }
1329 +
1314 // returns the newly computed bounding box of the rectangle 1330 // returns the newly computed bounding box of the rectangle
1315 function adjustRectToFitText(n) { 1331 function adjustRectToFitText(n) {
1316 var text = n.select('text'), 1332 var text = n.select('text'),
...@@ -1346,14 +1362,26 @@ ...@@ -1346,14 +1362,26 @@
1346 var idx = (deviceLabelIndex < d.labels.length) ? deviceLabelIndex : 0; 1362 var idx = (deviceLabelIndex < d.labels.length) ? deviceLabelIndex : 0;
1347 return d.labels[idx]; 1363 return d.labels[idx];
1348 } 1364 }
1349 - function niceLabel(label) { 1365 + function trimLabel(label) {
1350 - return (label && label.trim()) ? label : '.'; 1366 + return (label && label.trim()) || '';
1367 + }
1368 +
1369 + function emptyBox() {
1370 + return {
1371 + x: -2,
1372 + y: -2,
1373 + width: 4,
1374 + height: 4
1375 + };
1351 } 1376 }
1352 1377
1353 function updateDeviceLabel(d) { 1378 function updateDeviceLabel(d) {
1354 - var label = niceLabel(deviceLabel(d)), 1379 + var label = trimLabel(deviceLabel(d)),
1380 + noLabel = !label,
1355 node = d.el, 1381 node = d.el,
1356 - box; 1382 + box,
1383 + dx,
1384 + dy;
1357 1385
1358 node.select('text') 1386 node.select('text')
1359 .text(label) 1387 .text(label)
...@@ -1361,21 +1389,23 @@ ...@@ -1361,21 +1389,23 @@
1361 .transition() 1389 .transition()
1362 .style('opacity', 1); 1390 .style('opacity', 1);
1363 1391
1392 + if (noLabel) {
1393 + box = emptyBox();
1394 + dx = -config.icons.device.dim/2;
1395 + dy = -config.icons.device.dim/2;
1396 + } else {
1364 box = adjustRectToFitText(node); 1397 box = adjustRectToFitText(node);
1398 + dx = box.x + config.icons.xoff;
1399 + dy = box.y + config.icons.yoff;
1400 + }
1365 1401
1366 node.select('rect') 1402 node.select('rect')
1367 .transition() 1403 .transition()
1368 .attr(box); 1404 .attr(box);
1369 1405
1370 - node.select('rect.iconUnderlay') 1406 + node.select('g.deviceIcon')
1371 .transition() 1407 .transition()
1372 - .attr('x', box.x + config.icons.xoff) 1408 + .attr('transform', translate(dx, dy));
1373 - .attr('y', box.y + config.icons.yoff);
1374 -
1375 - node.select('image')
1376 - .transition()
1377 - .attr('x', box.x + config.icons.xoff + 2)
1378 - .attr('y', box.y + config.icons.yoff + 2);
1379 } 1409 }
1380 1410
1381 function updateHostLabel(d) { 1411 function updateHostLabel(d) {
...@@ -1436,7 +1466,7 @@ ...@@ -1436,7 +1466,7 @@
1436 node = nodeG.selectAll('.node') 1466 node = nodeG.selectAll('.node')
1437 .data(network.nodes, function (d) { return d.id; }); 1467 .data(network.nodes, function (d) { return d.id; });
1438 1468
1439 - // operate on existing nodes, if necessary 1469 + // TODO: operate on existing nodes
1440 // update host labels 1470 // update host labels
1441 //node .foo() .bar() ... 1471 //node .foo() .bar() ...
1442 1472
...@@ -1458,8 +1488,8 @@ ...@@ -1458,8 +1488,8 @@
1458 // augment device nodes... 1488 // augment device nodes...
1459 entering.filter('.device').each(function (d) { 1489 entering.filter('.device').each(function (d) {
1460 var node = d3.select(this), 1490 var node = d3.select(this),
1461 - icon = iconUrl(d), 1491 + label = trimLabel(deviceLabel(d)),
1462 - label = niceLabel(deviceLabel(d)), 1492 + noLabel = !label,
1463 box; 1493 box;
1464 1494
1465 // provide ref to element from backing data.... 1495 // provide ref to element from backing data....
...@@ -1480,41 +1510,8 @@ ...@@ -1480,41 +1510,8 @@
1480 node.select('rect') 1510 node.select('rect')
1481 .attr(box); 1511 .attr(box);
1482 1512
1483 - if (icon) { 1513 + addDeviceIcon(node, box, noLabel, iconGlyphUrl(d));
1484 - var cfg = config.icons;
1485 - node.append('rect')
1486 - .attr({
1487 - class: 'iconUnderlay',
1488 - x: box.x + config.icons.xoff,
1489 - y: box.y + config.icons.yoff,
1490 - width: cfg.w,
1491 - height: cfg.h,
1492 - rx: 4
1493 - }).style({
1494 - stroke: '#000',
1495 - fill: '#ddd'
1496 - });
1497 - node.append('svg:image')
1498 - .attr({
1499 - x: box.x + config.icons.xoff + 2,
1500 - y: box.y + config.icons.yoff + 2,
1501 - width: cfg.w - 4,
1502 - height: cfg.h - 4,
1503 - 'xlink:href': icon
1504 - });
1505 - }
1506 1514
1507 - // debug function to show the modelled x,y coordinates of nodes...
1508 - if (debug('showNodeXY')) {
1509 - node.select('rect').attr('fill-opacity', 0.5);
1510 - node.append('circle')
1511 - .attr({
1512 - class: 'debug',
1513 - cx: 0,
1514 - cy: 0,
1515 - r: '3px'
1516 - });
1517 - }
1518 }); 1515 });
1519 1516
1520 // TODO: better place for this configuration state 1517 // TODO: better place for this configuration state
...@@ -1604,6 +1601,67 @@ ...@@ -1604,6 +1601,67 @@
1604 // TODO: device node exits 1601 // TODO: device node exits
1605 } 1602 }
1606 1603
1604 + function addDeviceIcon(node, box, noLabel, iid) {
1605 + var cfg = config.icons.device,
1606 + dx,
1607 + dy,
1608 + g;
1609 +
1610 + if (noLabel) {
1611 + box = emptyBox();
1612 + dx = -cfg.dim/2;
1613 + dy = -cfg.dim/2;
1614 + } else {
1615 + box = adjustRectToFitText(node);
1616 + dx = box.x + config.icons.xoff;
1617 + dy = box.y + config.icons.yoff;
1618 + }
1619 +
1620 + g = node.append('g').attr('class', 'glyphIcon deviceIcon')
1621 + .attr('transform', translate(dx, dy));
1622 +
1623 + g.append('rect').attr({
1624 + x: 0,
1625 + y: 0,
1626 + rx: cfg.rx,
1627 + width: cfg.dim,
1628 + height: cfg.dim
1629 + });
1630 +
1631 + g.append('use').attr({
1632 + 'xlink:href': iid,
1633 + width: cfg.dim,
1634 + height: cfg.dim
1635 + });
1636 +
1637 +/*
1638 + if (icon) {
1639 + node.append('rect')
1640 + .attr({
1641 + class: 'iconUnderlay',
1642 + x: box.x + config.icons.xoff,
1643 + y: box.y + config.icons.yoff,
1644 + width: cfg.w,
1645 + height: cfg.h,
1646 + rx: 4
1647 + }).style({
1648 + stroke: '#000',
1649 + fill: '#ddd'
1650 + });
1651 + node.append('svg:image')
1652 + .attr({
1653 + x: box.x + config.icons.xoff + 2,
1654 + y: box.y + config.icons.yoff + 2,
1655 + width: cfg.w - 4,
1656 + height: cfg.h - 4,
1657 + 'xlink:href': icon
1658 + });
1659 + }
1660 +*/
1661 + }
1662 +
1663 +
1664 +
1607 function find(key, array) { 1665 function find(key, array) {
1608 for (var idx = 0, n = array.length; idx < n; idx++) { 1666 for (var idx = 0, n = array.length; idx < n; idx++) {
1609 if (array[idx].key === key) { 1667 if (array[idx].key === key) {
...@@ -2070,6 +2128,7 @@ ...@@ -2070,6 +2128,7 @@
2070 var defs = svg.append('defs'); 2128 var defs = svg.append('defs');
2071 gly.defBird(defs); 2129 gly.defBird(defs);
2072 gly.defBullhorn(defs); 2130 gly.defBullhorn(defs);
2131 + gly.defGlyphs(defs);
2073 } 2132 }
2074 2133
2075 // ============================== 2134 // ==============================
......