Merge branch 'VLAN-GUI' into VLAN-MultiSSID
[tomato.git] / release / src / router / www / bwm-graph.svg
blob07d3d07560c698f1070c12facfbab94881340f1c
1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3 <!--
4 Tomato GUI
5 Copyright (C) 2006-2010 Jonathan Zarate
6 http://www.polarcloud.com/tomato/
8 For use with Tomato Firmware only.
9 No part of this file may be used without permission.
10 -->
11 <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" onload="init(evt)"
12 onmousemove="mMove(evt)" onclick="mClick(evt)">
14 <style type='text/css'>
15 * {
16 cursor: pointer;
18 line {
19 stroke: #d0d0d0;
20 stroke-width: 1;
22 line.a {
23 stroke: #f0f0f0;
25 #crossX, #crossY {
26 stroke: #f77;
27 stroke-width: 1;
29 text {
30 font: 11px monospace;
31 fill: #000;
33 .tickH {
34 text-anchor: middle;
35 fill: #222;
37 #pointText {
38 text-anchor: end;
40 .back {
41 fill: #fff;
42 opacity: 0.8;
44 </style>
45 <script type='text/ecmascript'><![CDATA[
48 Hi there! What are you looking at? Messy isn't it?
50 ^_^
54 var week = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
55 var pointLoc = 0;
56 var vWidth = 760;
57 var vHeight = 300;
58 var crossH = 0;
59 var crossV = 0;
60 var maxV = 0;
61 var maxL = 0;
62 var time24 = 0;
63 var advX = 1;
64 var interval = 0;
65 var hours = 0;
66 var xpstVis = 1;
67 var ignoreNext = 0;
68 var eraseL = 0;
69 var samp = 1;
71 function E(id)
73 return document.getElementById(id);
76 function pad(n)
78 n = n.toString();
79 while (n.length < 2) n = '0' + n;
80 return n;
83 function xps(n)
85 n /= 1024;
86 return (n * 8).toFixed(2) + ' kbit/s (' + n.toFixed(2) + ' KB/s)';
89 function setText(e, text)
91 // Adobe/IE doesn't do textContent=
92 if (e.firstChild) e.removeChild(e.firstChild);
93 e.appendChild(document.createTextNode(text));
96 function init(evt)
98 var n;
100 if (typeof(svgDocument) == 'undefined') svgDocument = evt.target.ownerDocument;
102 crossX = E('crossX');
103 crossY = E('crossY');
104 polyRx = E('polyRx');
105 polyTx = E('polyTx');
106 pointTextBack = E('pointTextBack');
107 pointText = E('pointText');
108 pointG = E('pointGroup');
109 crossTextBack = E('crossTextBack');
110 crossText = E('crossText');
111 crossTime = E('crossTime');
112 maxText = E('maxText');
114 tickLines = [];
115 for (n = 0; n < 24; ++n) {
116 tickLines[n] = E('tick' + n);
118 tickHours = [];
119 for (n = 0; n < 12; ++n) {
120 tickHours[n] = E('h' + n);
123 xpst = [];
124 for (n = 0; n < 3; ++n)
125 xpst[n] = E('xpst' + n);
127 time24 = ((new Date(2000, 0, 1, 23, 0, 0, 0)).toLocaleString().indexOf('23') != -1);
129 top.updateSVG = updateSVG;
130 top.svgReady = 1;
131 top.initData();
134 function drawData(poly, data, mode, color)
136 var i;
137 var pt;
138 var x, y;
139 var d, j;
141 if (data.length == 0) return;
143 x = 0;
144 if (mode == 0) {
145 poly.setAttribute('fill-opacity', '0.5');
146 pt = '0,' + vHeight;
148 else {
149 poly.setAttribute('fill-opacity', '0');
150 pt = '';
152 poly.setAttribute('stroke', color);
153 poly.setAttribute('fill', color);
155 for (i = data.length - maxL; i < data.length; ++i) {
156 if (i < 0) {
157 d = 0;
159 else if (i >= samp) {
160 d = 0;
161 for (j = samp - 1; j >= 0; --j) {
162 d += data[i - j];
164 d /= (dataDiv * samp);
166 else {
167 d = data[i] / dataDiv;
169 y = (vHeight - Math.floor((d * vHeight) / maxV))
170 pt += ' ' + Math.floor(x) + ',' + y;
171 x += advX;
173 pt += ' ' + (vWidth + 5) + ',' + y + ' ' + (vWidth + 10) + ',' + vHeight;
174 poly.setAttribute('points', pt);
177 function updateSVG(rxData, txData, maxValue, mode, rxColor, txColor, intv, maxLen, dataD, avgSamp, clock)
179 var x, y, z, i;
180 var v, e;
182 maxV = maxValue;
183 interval = intv;
184 maxL = maxLen;
185 advX = vWidth / maxL;
186 dataDiv = dataD;
187 samp = avgSamp;
189 tockD = clock;
190 // tockD = new Date();
191 tock = tockD.getTime();
193 if (intv < 60) {
194 // realtime
195 x = z = (vWidth / 5);
196 for (i = 0; i < 4; ++i) {
197 tickLines[i].setAttribute('x1', Math.round(x));
198 tickLines[i].setAttribute('x2', Math.round(x));
199 x += z;
202 else {
203 advM = (60 / interval) * advX;
204 x = (60 - tockD.getMinutes()) * advM;
205 v = advM * 60;
206 for (i = 0; i < 24; ++i) {
207 z = Math.round(x);
208 y = (new Date(tock - (Math.round((vWidth - z - 1) / advX) * interval * 1000))).getHours();
209 x += v;
211 e = tickLines[i];
212 e.setAttribute('x1', z);
213 e.setAttribute('x2', z);
214 e.setAttribute('class', (y & 1) ? 'a' : 'b');
216 if ((y & 1) == 0) {
217 e = tickHours[i >> 1];
218 e.setAttribute('x', z);
219 z = y % 24;
220 if (!time24) {
221 if (z < 12) {
222 if (z == 0) z = 12;
223 z += ' am';
225 else {
226 z -= 12;
227 if (z == 0) z = 12;
228 z += ' pm';
231 setText(e, z);
236 if (maxV <= 0) {
237 polyRx.setAttribute('points', '');
238 polyTx.setAttribute('points', '');
239 return;
242 if (crossV > 0) drawCross(crossH, vHeight - Math.floor((crossV / maxV) * vHeight));
243 drawData(polyRx, rxData, mode, rxColor);
244 drawData(polyTx, txData, mode, txColor);
246 setText(maxText, xps(maxV) + ' >');
248 setText(xpst[0], xps(maxV * 0.75));
249 setText(xpst[1], xps(maxV * 0.5));
250 setText(xpst[2], xps(maxV * 0.25));
252 if (eraseL > 0) {
253 if (--eraseL == 0) pointG.setAttribute('visibility', 'hidden');
257 function vY(y)
259 return maxV - (maxV * (y / vHeight))
262 function pointTime(x)
264 var t, hh, h, s;
266 t = new Date(tock - (Math.round((vWidth - x - 1) / advX) * interval * 1000));
267 h = t.getHours();
268 s = week[t.getDay()] + ' ';
269 if (time24) {
270 s += pad(h) + ':' + pad(t.getMinutes());
272 else {
273 hh = h % 12;
274 s += pad((hh == 0) ? 12 : hh) + ':' + pad(t.getMinutes()) + ((h < 12) ? ' am' : ' pm');
277 return s;
280 function mMove(evt)
282 var x;
284 if (maxV <= 0) return;
285 if (evt.clientX > (vWidth - 120)) {
286 if (pointLoc == 0) {
287 if (evt.clientY < 30) {
288 pointLoc = 1;
289 pointText.setAttribute('y', '98%');
290 pointTextBack.setAttribute('y', '94%');
293 else {
294 if (evt.clientY > (vHeight - 30)) {
295 pointLoc = 0;
296 pointText.setAttribute('y', '5%');
297 pointTextBack.setAttribute('y', '1%');
302 setText(pointText, pointTime(evt.clientX) + ' / ' + xps(vY(evt.clientY)));
304 x = pointText.getComputedTextLength();
305 pointTextBack.setAttribute('x', (vWidth - x) - 22);
306 pointTextBack.setAttribute('width', x + 20);
307 if (eraseL == 0) pointG.setAttribute('visibility', 'visible');
308 eraseL = 5;
311 function setXY(e, x, y)
313 e.setAttribute('x', x);
314 e.setAttribute('y', y);
317 function drawCross(x, y)
319 var n;
321 crossX.setAttribute('x1', x - 10);
322 crossX.setAttribute('x2', x + 10);
323 crossX.setAttribute('y1', y);
324 crossX.setAttribute('y2', y);
326 crossY.setAttribute('x1', x);
327 crossY.setAttribute('x2', x);
328 crossY.setAttribute('y1', y - 10);
329 crossY.setAttribute('y2', y + 10);
331 n = Math.max(crossText.getComputedTextLength(), crossTime.getComputedTextLength()) + 20;
332 crossTextBack.setAttribute('width', n);
334 if (x > (vWidth - n - 10)) {
335 crossText.setAttribute('style', 'text-anchor:end');
336 crossTime.setAttribute('style', 'text-anchor:end');
337 crossTextBack.setAttribute('x', (x - n) - 10);
338 x -= 20;
340 else {
341 crossText.setAttribute('style', '');
342 crossTime.setAttribute('style', '');
343 crossTextBack.setAttribute('x', x + 10);
344 x += 20;
347 crossTextBack.setAttribute('y', y - 17);
348 setXY(crossTime, x, y - 5);
349 setXY(crossText, x, y + 10);
352 function mClick(evt)
354 if (ignoreNext) {
355 ignoreNext = 0;
356 return;
358 if (maxV <= 0) return;
360 crossH = evt.clientX;
361 crossV = vY(evt.clientY);
362 setText(crossText, xps(crossV));
363 setText(crossTime, pointTime(crossH));
364 drawCross(evt.clientX, evt.clientY);
366 E('cross').setAttribute('visibility', (evt.clientY > (vHeight - 20)) ? 'hidden' : 'visible');
369 function toggleXpst()
371 E('xpst').setAttribute('visibility', (xpstVis ^= 1) ? 'visible' : 'hidden');
372 ignoreNext = 1;
375 ]]></script>
376 <rect x="0" y="0" width="100%" height="100%" style="fill:#fff" />
378 <line x1="0" y1="50%" x2="100%" y2="50%" />
379 <line x1="0" y1="25%" x2="100%" y2="25%" />
380 <line x1="0" y1="75%" x2="100%" y2="75%" />
382 <line x1="0" y1="0%" x2="0" y2="100%" id="tick0" />
383 <line x1="0" y1="0%" x2="0" y2="100%" id="tick1" />
384 <line x1="0" y1="0%" x2="0" y2="100%" id="tick2" />
385 <line x1="0" y1="0%" x2="0" y2="100%" id="tick3" />
386 <line x1="0" y1="0%" x2="0" y2="100%" id="tick4" />
387 <line x1="0" y1="0%" x2="0" y2="100%" id="tick5" />
388 <line x1="0" y1="0%" x2="0" y2="100%" id="tick6" />
389 <line x1="0" y1="0%" x2="0" y2="100%" id="tick7" />
390 <line x1="0" y1="0%" x2="0" y2="100%" id="tick8" />
391 <line x1="0" y1="0%" x2="0" y2="100%" id="tick9" />
392 <line x1="0" y1="0%" x2="0" y2="100%" id="tick10" />
393 <line x1="0" y1="0%" x2="0" y2="100%" id="tick11" />
394 <line x1="0" y1="0%" x2="0" y2="100%" id="tick12" />
395 <line x1="0" y1="0%" x2="0" y2="100%" id="tick13" />
396 <line x1="0" y1="0%" x2="0" y2="100%" id="tick14" />
397 <line x1="0" y1="0%" x2="0" y2="100%" id="tick15" />
398 <line x1="0" y1="0%" x2="0" y2="100%" id="tick16" />
399 <line x1="0" y1="0%" x2="0" y2="100%" id="tick17" />
400 <line x1="0" y1="0%" x2="0" y2="100%" id="tick18" />
401 <line x1="0" y1="0%" x2="0" y2="100%" id="tick19" />
402 <line x1="0" y1="0%" x2="0" y2="100%" id="tick20" />
403 <line x1="0" y1="0%" x2="0" y2="100%" id="tick21" />
404 <line x1="0" y1="0%" x2="0" y2="100%" id="tick22" />
405 <line x1="0" y1="0%" x2="0" y2="100%" id="tick23" />
407 <text x="0" y="98%" class="tickH" id="h0" />
408 <text x="0" y="98%" class="tickH" id="h1" />
409 <text x="0" y="98%" class="tickH" id="h2" />
410 <text x="0" y="98%" class="tickH" id="h3" />
411 <text x="0" y="98%" class="tickH" id="h4" />
412 <text x="0" y="98%" class="tickH" id="h5" />
413 <text x="0" y="98%" class="tickH" id="h6" />
414 <text x="0" y="98%" class="tickH" id="h7" />
415 <text x="0" y="98%" class="tickH" id="h8" />
416 <text x="0" y="98%" class="tickH" id="h9" />
417 <text x="0" y="98%" class="tickH" id="h10" />
418 <text x="0" y="98%" class="tickH" id="h11" />
419 <text x="0" y="98%" class="tickH" id="h12" />
421 <g id="xpst">
422 <text x="18" y="25%" id="xpst0" />
423 <text x="18" y="50%" id="xpst1" />
424 <text x="18" y="75%" id="xpst2" />
425 </g>
427 <polyline id="polyTx" style="stroke-width:1" points="" />
428 <polyline id="polyRx" style="stroke-width:1" points="" />
430 <g id="pointGroup" visibility="hidden">
431 <rect x="490" y="0" width="268" height="15" id="pointTextBack" class="back" />
432 <text x="99%" y="12" id="pointText" />
433 </g>
435 <rect x="0" y="0" width="15" height="100%" id="maxTextBack" class="back" onclick="toggleXpst()"/>
436 <text x="-2%" y="12" transform="rotate(-90)" text-anchor="end" id="maxText" onclick="toggleXpst()"/>
438 <g id="cross" visibility="hidden">
439 <line x1="0" y1="0" x2="0" y2="0" id="crossX" />
440 <line x1="0" y1="0" x2="0" y2="0" id="crossY" />
441 <rect x="0" y="-100" width="10" height="35" id="crossTextBack" class="back" />
442 <text x="0" y="-50" id="crossTime" />
443 <text x="0" y="0" id="crossText" />
444 </g>
446 </svg>