source: trunk/FACT++/www/smartfact/index.js@ 14171

Last change on this file since 14171 was 14144, checked in by tbretz, 13 years ago
Resize the graphics again after the text was rendered... some text elements might spawn two lines; allow a title instead of min/med/max in the file for graphics; overlay the graphics also when the file contents was invalid.
File size: 42.2 KB
Line 
1"use strict";
2
3var debug = false;
4
5var codedMap = "966676:6:A;68656364626Y?\\?;A=A<AGADAN4K4i5g5h5o506W?Z?]?_?>A@A?AJAIAFACAM4J4H4f5d5e5l5m5n516X?[?^?N?P?AA1ABAVAUAKAHAEAO4L4I4G4E4c5a5b5M6j5k5V6Y6\\6_6G?J?O?Q?S?2A4A3AYAXAWAbA_AnAkAhA3404F4D4B4`5^5_5J6K6L6S6T6W6Z6]6E?H?K?M?R?T?V?5A7A6A\\A[AZAeAdAaA^AmAjAgA24o3m3C4A4?4]5[5\\5G6H6I6P6Q6R6U6X6[6^6F?I?L?<?>?U?;@=@8Ah@9AMALA]ABCACfAcA`AoAlAiA4414n3l3<4@4>425Z5X5Y5D6E6F698N6O608E8H8K8H>K>N>?>B>=???A?<@>@@@i@k@j@PAOANAECDCCC<C9CZCWCTC=3:3734313=4;4943515o4W5U5V5A6B6C6687888m7n7C8F8I8F>I>L>=>@>C>E>@?B?D??@A@C@l@n@m@SARAQAHCGCFC?C>C;C8CYCVCSC<393633303n2:4846405n4l4T5R5S5>6?6@6384858j7k7l7o7D8G8J8G>J>M>>>A>D>4>6>C?3?5?B@2@4@o@_@0ALBKBTA0CoBIC8D7D@C=C:C[CXCUC>3;3835323o2m2k27454j3m4k4i4Q5O5P5C7<6=6g71828o8h7i7S9<8?8B8Q>T>W>@=C=F=e<h<5>7>9>4?6?8?3@5@7@`@b@a@OBNBMB3C2C1C;D:D9D_D\\DQCNCKCF3C3@3>2;282Z1W1l2j2h2k3i3g3j4h4f4N5L5M5@7A7B7d7e7f7l8m8n8P9Q9:8=8@8O>R>U>>=A=D=c<f<i<k<8>:><>7?9?;?6@8@:@c@e@d@RBQBPB6C5C4C>D=D<DbDaD^D[DPCMCJCE3B3?3=2:272Y1V1T1i2g2e2h3f3d3g4e4c4K5I5J5=7>7?7a7b7c7i8j8k8M9N9O9R9;8>8A8P>S>V>?=B=E=d<g<j<Z<\\<;>k=m=:?j>l>9@i?k?f@V@g@CBBBSBgBfB7CoCnC?DSDRDcD`D]DRCOCLCG3D3A3?2<292[1X1U1S1Q1f2d2b2e3c3a3d4b4`4H5F5G5:7;7<7^7_7`7f8g8h8J9K9L97:::=:@:C:F:I:I=L=O=7=:===n<1=[<]<_<l=n=0>k>m>o>j?l?n?W@Y@X@FBEBDBjBiBhB2D1D0DVDUDTDCE@EOELEIEXEUERE5222o1l1i1f1c1`1R1P1N1c2a2_2b3`3^3a4_4]4<5:5;5778797[7\\7]7c8d8e8G9H9I94:5:8:;:>:A:D:G:G=J=M=5=8=;=l<o<2=4=^<`<b<o=1>3>n>0?2?m?o?1@Z@\\@[@IBHBGBmBlBkB5D4D3DYDXDWDFEEEBE?ENEKEHEWETEQE4212n1k1h1e1b1_1]1O1M1K1`2^2\\2_3]3[3^4\\4Z4957585475767X7Y7Z7`8a8b8D9E9F91:2:3:6:9:<:?:B:E:H:H=K=N=6=9=<=m<0=3=d;f;a<H<J<2>b=d=1?a>c>0@`?b?]@D@^@:B9BJB^B]BnBfCeC6DJDIDZDnDmDGEDEAEPEMEJEYEVESE623202m1j1g1d1a1^1\\1[0L1J1?1]2[2Y2\\3Z3X3[4Y4W4654555172737U7V7W7]8^8_8A9B9C9e9o90:n9g:j:m:L:O:R:U:X:[:];`;c;T;W;Z;7<9<e;g;i;I<K<M<c=e=g=b>d>f>a?c?e?E@G@F@=B<B;BaB`B_BiChCgCMDLDKD1E0EoD9E7E<F9F6FaE^E[EjEgEdER0O0L0I0F0C0n0l0\\0Z0X0@1>1<1Z2X2V2Y3W3U3X4V4T4E5C5D5n6o607R7S7T7Z8[8\\8>9?9@9b9c9d9l9m9e:h:k:J:M:P:S:V:Y:[;^;a;R;U;X;6<8<:<;<h;j;l;L<N<P<f=h=j=e>g>i>d?f?h?N@Q@H@@B?B>BdBcBbBlCkCjCPDODND4E3E2E;E:E8E6E;F8F5F`E]EZEiEfEcEQ0N0K0H0E0B0m0k0j0Y0W0U0=1;191W2U2S2V3T3R3U4S4Q4B5@5A5k6l6m6O7P7Q7W8X8Y8;9<9=9_9`9a9j9k9\\:_:f:i:l:K:N:Q:T:W:Z:\\;_;b;S;V;Y;C<E<G<<<m;k;1<2<O<Q<S<i=[=P=h>X>Z>g?M@O@R@U@S@J@I@AB1B0BeBTB\\CmCAD@DQDiDhD5EdD<E4F2F0F=F:F7FbE_E\\EkEhEeES0P0M0J0G0D011o0h0g0e0V0T0`0:181Q2T2R2H2S3Q3P3R4P4K3?5=5>5c6i6j6h6M7N7L7U8V8T899:9W9]9^9\\9g9h9i9]:`:c:5;2;o:>;;;8;P;M;J;G;D;A;?<A<D<F<=<><n;o;3<5<R<T<Y=Z=Q=R=Y>[>\\>^>P@T@L@K@5B4B3B2BVBUB^C]CCDBDkDjDfDeD>E=E3F1FnElE@FCFFFIFLFOF;0>0A0205080513101i0f0d0c0b0_0I1H1D1P2O2G2F2D2O3N3M3J3H3a6b6e6f6g6I7J7K7R8S8397989V9Y9Z9[9f9^:a:d:4;1;n:=;:;7;O;L;I;F;C;@;@<B<0<4<U<V<X<`=]=\\=S=U=W=]>_>`>8B7B6BZBXBWB_CaC`CFDEDDDlDgDoEmE>FAFDFGFJFMF90<0?0003060714121a0^0]0G1C1B1N2L2E2C2B2@2L3I3`6d6E7F7G7H7O8Q8192969T9U9X96;3;0;?;<;9;Q;N;K;H;E;B;W<Y<^=_=a=T=V=X=\\B[BYBdCcCbCHDGD?FBFEFHFKFNF:0=0@0104070F1E1A1M2K2J2I2A2D7L8M8N8P809495961b:";
6var map = new Array(1440);
7
8function $(id) { return document.getElementById(id); }
9function $new(name) { return document.createElement(name); }
10function $txt(txt) { return document.createTextNode(txt); }
11function trim(str) { return str.replace(/^\s\s*/, "").replace(/\s*\s$/, ""); }
12function valid(str) { if (!str) return false; if (str.length==0) return false; return true;}
13function isSliding() { var z = $("body").visiblePage/*getAttribute("data-visible")*/; return $("table"+z) ? $("table"+z).offsetLeft!=0 : false; }
14function htmlDecode(input) { var e = $new('div'); e.innerHTML = input; return e.firstChild ? e.firstChild.nodeValue : input; }
15function setUTC(el, time) { var str = time.toUTCString(); var utc = str.substr(str.length-12, 8); el.innerHTML = "&#8226;&nbsp;"+utc+"&nbsp;UTC&nbsp;&#8226;"; }
16
17function cycleCol(el)
18{
19 var col = el.dotColor;//el.getAttribute("data-color");
20 col++;
21 col %= 31;
22 el.dotColor = col; //setAttribute("data-color", col);
23 if (col>16)
24 col = 31-col;
25 var hex = col.toString(16);
26 el.style.color = "#"+hex+"0"+hex+"0"+hex+"f";
27}
28
29function onload()
30{
31 try
32 {
33 var xmlLoad = new XMLHttpRequest();
34 xmlLoad.open('POST', "index.php?load", true);
35 xmlLoad.onload = function()
36 {
37 if (xmlLoad.status!=200)
38 {
39 //alert("ERROR[0] - HTTP request '"+xmlLoad.statusText+" ["+xmlLoad.status+"]");
40 //return;
41 }
42 if (xmlLoad.responseText.length>0)
43 alert(xmlLoad.responseText);
44 };
45 xmlLoad.send(null);
46 }
47 catch(e)
48 {
49 // FIXME: Add a message to the body.
50 alert("Your browser doesn't support dynamic reload.");
51 return;
52 }
53
54 var name = location.hash.length==0 ? "fact" : location.hash.substr(1);
55
56 var args = location.search.substr(1).split('&');
57
58 for (var i=0; i<args.length; i++)
59 {
60 switch (args[i])
61 {
62 //case "max": $("body").setAttribute("data-max", "yes"); continue;
63 //case "noslide": $("body").setAttribute("data-noslide", "yes"); continue;
64 case "max": $("body").displayMax = true; continue;
65 case "noslide": $("body").displayNoslide = true; continue;
66 case "sound": $("body").sound = true; continue;
67 }
68
69 var entry = args[i].split('=');
70 if (entry.length!=2)
71 continue;
72
73 switch (entry[0])
74 {
75 case "w": $("body").displayFixedWidth = entry[1]; break; //setAttribute("data-width", entry[1]); break;
76 case "h": $("body").displayFixedHeight = entry[1]; break; //setAttribute("data-height", entry[1]); break;
77 }
78 }
79
80 /*
81 alert("0 -- "+navigator.appCodeName+"\n"+
82 "1 -- "+navigator.appName+"\n"+
83 "2 -- "+navigator.appVersion+"\n"+
84 "3 -- "+navigator.platform+"\n"+
85 "4 -- "+navigator.userAgent);
86 */
87 loadPage(name, 0, 0);
88}
89
90function onresize()
91{
92 var z = $("body").visiblePage/*getAttribute("data-visible")*/;
93
94 //$("table"+z).style.width="100%";
95 $("image"+z).style.width="1px";
96 $("canvas"+z).width=1;
97
98 doresize(z);
99
100}
101
102function loadPage(name, z, dz)
103{
104 if (isSliding())
105 return;
106
107 var xmlPage = new XMLHttpRequest();
108 xmlPage.open('POST', "struct/"+name+'.page', true);
109 xmlPage.onload = function ()
110 {
111 if (xmlPage.status!=200)
112 {
113 alert("ERROR[0] - HTTP request '"+name+".page': "+xmlPage.statusText+" ["+xmlPage.status+"]");
114 //setTimeout("loadPage('+name+')", 5000);
115 /****** invalidate ******/
116 return;
117 }
118
119 if (!isSliding())
120 {
121 buildPage(name, xmlPage.responseText, z, dz);
122 changePage(z, z+dz);
123 }
124
125 //changePage(name, xmlHttp.resposeText);
126 //slideOut(name, xmlHttp.responseText);
127 //displayPage(name, xmlHttp.responseText);
128 //onresize(true);
129 };
130
131 xmlPage.send(null);
132
133 location.hash = name;
134}
135
136function sendCommand(command)
137{
138 var debug = false;
139
140 var uri = "index.php?";
141 if (debug==true)
142 uri += "debug&";
143 uri += command;
144
145 var xmlCmd = new XMLHttpRequest();
146 xmlCmd.open('POST', uri, true);
147 xmlCmd.onload = function ()
148 {
149 if (xmlCmd.status!=200)
150 {
151 alert("ERROR[1] - HTTP request: "+xmlCmd.statusText+" ["+xmlCmd.status+"]");
152 return;
153 }
154
155 if (xmlCmd.responseText.length==0)
156 {
157 alert("No proper acknowledgment of command execution received.");
158 return;
159 }
160
161 var txt = xmlCmd.responseText.split('\n');
162 switch (txt[0])
163 {
164 case "1": alert("dimctrl unreachable."); break;
165 case "2": /*success*/ break;
166 default: alert("Return code '"+txt[0]+"' unknown."); break;
167 }
168 if (txt.length>1)
169 alert(xmlCmd.responseText);
170 };
171 xmlCmd.send(null);
172}
173
174
175function submit(script)
176{
177 var inputs = document.getElementsByTagName("input");
178
179 var args = "start="+script+".dim";
180 for (var i=0; i<inputs.length; i++)
181 args += "&"+inputs[i].name+"="+inputs[i].value;
182
183 var selects = document.getElementsByTagName("select");
184 for (var i=0; i<selects.length; i++)
185 args += "&"+selects[i].name+"="+selects[i].value;
186
187 sendCommand(args);
188}
189
190function buildPage(name, text, oldz, dz)
191{
192 var fname = dz==0 ? "fact" : $("table"+oldz).pageName;//getAttribute("data-file");
193
194 var z = oldz + dz;
195
196 var lines = text.split('\n');
197
198 if (lines.length==0)
199 {
200 alert("buildPage - received data empty.");
201 return;
202 }
203
204 if (lines[0].length==0)
205 {
206 alert("buildPage - title missing");
207 return;
208 }
209
210 $("audio").date = new Date();
211
212 var title = lines[0];
213 var is_cmd = title[0]=='*';
214 if (is_cmd)
215 title = title.substr(1);
216
217 // ==================================================================
218
219 var th = $new("thead");
220 th.colSpan = 3;
221 th.width = "100%";
222
223 var htr = $new("tr");
224 th.appendChild(htr);
225
226 var htd = $new("td");
227 htd.setAttribute("class", "thead");
228 htd.colSpan = 3;
229 htd.width = "100%";
230 htr.appendChild(htd);
231
232 // -------------
233
234 var htab = $new("table");
235 htab.width = "100%";
236 htd.appendChild(htab);
237
238 var hhtr = $new("tr");
239 htab.appendChild(hhtr);
240
241 var htd0 = $new("td");
242 var htd1 = $new("td");
243 var htd2 = $new("td");
244 var htd3 = $new("td");
245 var htd4 = $new("td");
246 var htd5 = $new("td");
247 htd0.setAttribute("class", "tcell1");
248 htd1.setAttribute("class", "tcell2");
249 htd2.setAttribute("class", "tcell1");
250 htd2.setAttribute("width", "1px");
251 htd3.setAttribute("class", "tcell1");
252 htd3.setAttribute("width", "1px");
253 htd4.setAttribute("width", "1px");
254 htd5.setAttribute("width", "1px");
255 hhtr.appendChild(htd4);
256 hhtr.appendChild(htd3);
257 hhtr.appendChild(htd0);
258 hhtr.appendChild(htd1);
259 hhtr.appendChild(htd2);
260 hhtr.appendChild(htd5);
261
262 var div1 = $new("div");
263 var div2 = $new("div");
264 var div3 = $new("div");
265 var div4 = $new("div");
266 var div5 = $new("div");
267 div4.id = "warn"+z;
268 div5.id = "speaker"+z;
269 div2.setAttribute("class", "icon_white");
270 div4.setAttribute("class", "icon_color");
271 div5.setAttribute("class", "icon_color");
272 div2.setAttribute("style", "background-position:-396px 50%;");
273 div4.setAttribute("style", "background-position:-12px -12px;display:none;");
274 div5.setAttribute("style", "background-position:-189px -57px;");
275 div2.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage(fname, z, -dz); };
276 div4.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('error', z, +1); };
277
278 if (name=="fact")
279 {
280 div3.setAttribute("class", "icon_color");
281 div3.setAttribute("style", "background-position:-58px -146px;");
282 }
283 else
284 {
285 div3.setAttribute("class", "icon_white");
286 div3.setAttribute("style", "background-position:-575px 50%;");
287 div3.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('fact', z, -1); };
288 }
289
290 var sp0 = $new("span");
291 var sp1 = $new("span");
292 var sp2 = $new("span");
293 sp0.id = "ldot" +z;
294 sp1.id = "title"+z;
295 sp2.id = "rdot" +z;
296 sp1.setAttribute("style", "font-size:large;");
297 //sp0.setAttribute("data-color", "3");
298 //sp2.setAttribute("data-color", "3");
299 sp0.dotColor = 3;
300 sp2.dotColor = 3;
301 sp0.appendChild($txt(" \u2022 "));
302 sp1.appendChild($txt(title));
303 sp2.appendChild($txt(" \u2022 "));
304 if (is_cmd)
305 {
306 sp1.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; submit(name); this.style.backgroundColor=''; };
307 }
308 else
309 {
310 if (name!='control')
311 sp1.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.15)'; loadPage('control', z, +1); };
312 }
313
314 div1.setAttribute("style", "font-size:small;");
315 div1.id = "reporttime"+z;
316 div1.appendChild($txt("---"));
317
318 div1.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; sendCommand('stop'); this.style.backgroundColor=''; };
319
320 htd0.appendChild(sp0);
321 htd0.appendChild(sp1);
322 htd0.appendChild(sp2);
323
324 htd1.appendChild(div1);
325 if (dz!=0/* && z+dz!=0*/)
326 htd2.appendChild(div2); // back
327 htd3.appendChild(div3); // home
328 htd4.appendChild(div4); // Warning
329 htd5.appendChild(div5); // Warning
330
331 // ==================================================================
332
333 var tf = $new("tfoot");
334
335 var ftr = $new("tr");
336 tf.appendChild(ftr);
337
338 var ftd = $new("td");
339 ftd.setAttribute("class", "tfoot");
340 ftd.width = "100%";
341 ftd.colSpan = 3;
342 ftr.appendChild(ftd);
343
344 var ftab = $new("table");
345 ftab.width = "100%";
346 ftd.appendChild(ftab);
347
348 var ftdH = $new("td");
349 var ftd0 = $new("td");
350 var ftd1 = $new("td");
351 var ftd2 = $new("td");
352 var ftd3 = $new("td");
353 var ftd4 = $new("td");
354 ftdH.setAttribute("width", "1px");
355 ftd2.setAttribute("width", "1px");
356 ftd3.setAttribute("width", "1px");
357 ftd4.setAttribute("width", "1px");
358
359 ftdH.setAttribute("class", "tcell1");
360 ftd0.setAttribute("class", "tcell1");
361 ftd1.setAttribute("class", "tcell2");
362 ftd2.setAttribute("class", "tcell2");
363 ftd3.setAttribute("class", "tcell2");
364 ftd4.setAttribute("class", "tcell2");
365
366 ftab.appendChild(ftdH);
367 ftab.appendChild(ftd0);
368 ftab.appendChild(ftd1);
369 ftab.appendChild(ftd2);
370 ftab.appendChild(ftd3);
371 ftab.appendChild(ftd4);
372
373 var fdivH = $new("div");
374 var fdiv0 = $new("span");
375 var fdiv1 = $new("span");
376 var fdiv2 = $new("div");
377 var fdiv3 = $new("div");
378 var fdiv4 = $new("div");
379 ftd0.style.paddingLeft = "5px";
380 fdiv4.id="cmd"+z;
381
382 fdiv2.setAttribute("class", "icon_white");
383 fdiv3.setAttribute("class", "icon_white");
384 fdiv4.setAttribute("class", "icon_white");
385 fdiv2.setAttribute("style", "background-position:-72px 50%;");
386 fdiv4.setAttribute("style", "background-position:-432px 50%;");
387 fdiv2.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; sendCommand('stop'); this.style.backgroundColor=''; };
388 if (is_cmd)
389 {
390 fdiv3.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; submit(name); this.style.backgroundColor=''; };
391 fdiv3.setAttribute("style", "background-position:-109px 50%;");
392 }
393 else
394 {
395 fdiv3.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('control', z, +1); };
396 fdiv3.setAttribute("style", "background-position:-288px 50%;");
397 }
398
399 if (name.substr(0, 5)=="help-")
400 {
401 fdivH.setAttribute("class", "icon_color");
402 fdivH.setAttribute("style", "background-position:-408px -57px;");
403 //fdivH.setAttribute("style", "background-position:-13px -57px;");
404 }
405 else
406 {
407 fdivH.setAttribute("class", "icon_white");
408 fdivH.setAttribute("style", "background-position:-611px 50%;");
409 fdivH.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('help-'+name, z, +1); };
410 }
411 fdiv4.onclick = function () { this.style.backgroundColor='rgba(0,0,0,0.77)'; loadPage('scriptlog', z, +1); };
412
413
414 fdiv0.setAttribute("style", "font-size:large;");
415 fdiv1.setAttribute("style", "font-size:small;");
416 fdiv1.id = "localtime"+z;
417
418 fdiv0.appendChild($txt("logbook"));
419 fdiv1.appendChild($txt("loading..."));
420
421 ftdH.appendChild(fdivH);
422 ftd0.appendChild(fdiv0);
423 ftd1.appendChild(fdiv1);
424 ftd2.appendChild(fdiv2);
425 if (name!='control')
426 ftd3.appendChild(fdiv3);
427 if (name!='scriptlog')
428 ftd4.appendChild(fdiv4);
429
430 // ==================================================================
431
432 var tbody = $new("tbody");
433
434 for (var i=0; i<lines.length; i++)
435 {
436 lines[i] = trim(lines[i]);
437
438 if (lines[i][0] == '#')
439 lines.splice(i--, 1);
440 }
441
442 // Concatenate consecutive lines until they have at least two colons
443 for (var i=2; i<lines.length; i++)
444 {
445 if (lines[i].length==0)
446 continue;
447
448 while (i<lines.length)
449 {
450 var cols = lines[i-1].split('|');
451 if (cols.length>=3)
452 break;
453
454 lines[i-1] += lines[i].length==0 ? '<p/>' : " "+lines[i];
455 lines.splice(i,1);
456 }
457 }
458
459 var counter = 1;
460 for (var i=1; i<lines.length; i++)
461 {
462 lines[i] = trim(lines[i]);
463
464 if (lines[i].length==0)
465 continue;
466
467 var cols = lines[i].split('|');
468 if (cols.length != 3 && cols.length !=4)
469 {
470 alert("Wrong number of columns in line #"+i+" in '"+name+"': '"+lines[i]+"' N(cols)="+cols.length);
471 continue;
472 }
473
474 var check = cols[1].split("=");
475
476 if (check.length>1 && (check[0]=="camera" || check[0]=="hist"))
477 {
478 var data = cols[1].substring(check[0].length+1).split("/");
479
480 var tr = $new("tr");
481 tr.setAttribute("class", "row");
482 //tr.setAttribute("style", "margin:0;padding:0;");
483
484 var td = $new("td");
485 td.setAttribute("class", "container");
486 td.id = "container";
487 td.colSpan = 3;
488 tr.appendChild(td);
489
490 var canv = $new("canvas");
491 canv.id = "canvas"+z;
492 canv.width = "1";
493 canv.height = "1";
494 //canv.onclick = function () { save(); }
495 //canv.setAttribute("data-type", check[0]);
496 //canv.setAttribute("data-file", data[0]);
497 //canv.setAttribute("data-data", cols[1].substring(check[0].length+data[0].length+2));
498 canv.dataType = check[0];
499 canv.fileName = data[0];
500 canv.dataUnit = htmlDecode(cols[1].substring(check[0].length+data[0].length+2));
501// canv.setAttribute("style", "display:none;");
502 td.appendChild(canv);
503
504 var img = $new("img");
505 img.src = "img/dummy.png";//needed in firefox
506 img.id = "image"+z;
507 img.setAttribute("style", "width:1px;height:1px;display:none;");
508 td.appendChild(img);
509
510 tbody.appendChild(tr);
511 continue;
512 }
513
514 var tr = $new("tr");
515 tr.setAttribute("class", "row");
516
517 if (valid(cols[0]))
518 {
519 tr.linkName = cols[0];
520 tr.onclick = function () { this.style.background='#ccb'; loadPage(this.linkName, z, -1); };
521 }
522
523 if (valid(cols[3]))
524 {
525 tr.linkName = cols[3];
526 tr.onclick = function () { this.style.background='#cbb'; loadPage(this.linkName, z, +1); };
527 }
528
529 var td0 = $new("td");
530 td0.setAttribute("class", "tcol0");
531 tr.appendChild(td0);
532
533 if (check.length>0 && check[0]=="image")
534 {
535 var img = $new("img");
536 img.style.width="100%";
537 img.style.display="block";
538 img.src = "img/"+check[1];
539 td0.style.paddingLeft=0;
540 td0.style.border=0;
541 td0.colSpan=3;
542 td0.appendChild(img);
543
544 tbody.appendChild(tr);
545 continue;
546 }
547
548 if (valid(cols[0]))
549 {
550 var sp = $new("div");
551 sp.setAttribute("class", "icon_black");
552 sp.setAttribute("style", "background-position: -144px 50%;");
553 td0.appendChild(sp);
554 }
555
556 var td1 = $new("td");
557 td1.setAttribute("class", "tcol1");
558 td1.width = "100%";
559 tr.appendChild(td1);
560
561 var td2 = $new("td");
562 td2.setAttribute("class", "tcol2");
563 td2.width = "18px";
564
565 if (valid(cols[3]))
566 {
567 var sp = $new("div");
568 sp.setAttribute("class", "icon_black");
569 sp.setAttribute("style", "background-position: -108px 50%;");
570 td2.appendChild(sp);
571 }
572 tr.appendChild(td2);
573
574 var tab = $new("table");
575 tab.width = "100%";
576 td1.appendChild(tab);
577
578 var innertr = $new("tr");
579 tab.appendChild(innertr);
580
581 var cell1 = $new("td");
582 cell1.setAttribute("class", "tcell1");
583
584 var cell2 = $new("td");
585 cell2.setAttribute("class", valid(cols[1]) ? "tcell2" : "tcell2l");
586
587 if (check.length>0 && check[0]=="select")
588 {
589 var args = check[1].split('/');
590
591 if (args.length<2)
592 alert("Argument name missing for'"+check[1]+"'");
593 else
594 {
595 var div = $new("div");
596 div.innerHTML = args[0];
597 cell1.appendChild(div);
598
599 var input = $new("SELECT");
600 input.name = args[1];
601 for (var j=2; j<args.length; j++)
602 input.options.add(new Option(args[j]));
603 cell2.appendChild(input);
604 }
605
606 }
607 if (check.length>0 && check[0]=="input")
608 {
609 var opt = check[1].split('/');
610
611 if (opt.length<2)
612 alert("Argument name missing for'"+check[1]+"'");
613 else
614 {
615 var div = $new("div");
616 div.innerHTML = opt[0];
617 cell1.appendChild(div);
618
619 var input = $new("input");
620 input.name = opt[1];
621 input.type = "text";
622 input.maxlength = 80;
623 input.style.textAlign = "right";
624 if (opt.length>2)
625 input.value=opt[2];
626
627 cell2.appendChild(input);
628 }
629 }
630 if (check.length==0 || (check[0]!="input" && check[0]!="select"))
631 {
632 var div = $new("div");
633 div.innerHTML = cols[1];
634 cell1.appendChild(div);
635
636 if (cols.length>2 && cols[2].length>0)
637 {
638 cell2.id = "data"+z+"-"+counter;
639 cell2.dataFormat = cols[2];
640 cell2.appendChild($txt("---"));
641 counter++;
642 }
643 else
644 cell1.setAttribute("class", "description");
645 }
646
647 innertr.appendChild(cell1);
648 innertr.appendChild(cell2);
649
650 tbody.appendChild(tr);
651 }
652
653 // ==================================================================
654
655 if (debug == true)
656 {
657 tr = $new("tr");
658 tr.setAttribute("class", "row");
659
660 td = $new("td");
661 td.id = "debug"+z;
662 td.colSpan = 3;
663 tr.appendChild(td);
664
665 tbody.appendChild(tr);
666 }
667
668 // ==================================================================
669
670 var table = $("table"+z);
671 if (table)
672 $("body").removeChild(table);
673
674 table = $new("table");
675 table.id = "table"+z;
676 table.border = 0;
677 table.cellSpacing = 0;
678 table.cellPadding = "0px";
679 //table.setAttribute("style", "overflow:hidden;position:fixed;top:0px;left:"+window.innerWidth+"px;")
680 table.setAttribute("style",
681 "position:fixed;width:100%;top:0px;"+
682 "left:"+window.innerWidth+"px;");
683
684 table.appendChild(th);
685 table.appendChild(tbody);
686 table.appendChild(tf);
687
688 $("body").appendChild(table);
689
690 // ==================================================================
691
692 /*
693 // Scrollbar for just the body
694 table.style.position = "fixed";
695 th.style.position = "aboslute";
696 tf.style.position = "aboslute";
697 tbody.style.overflowY = "auto";
698 tbody.style.display = "block";
699 tbody.style.height = (window.innerHeight-th.clientHeight-tf.clientHeight)+"px";
700 tbody.id = "tbody"+z;
701 th.id = "thead"+z;
702 tf.id = "tfoot"+z;
703 */
704
705 // ==================================================================
706
707 table.pageName = name;//setAttribute("data-file", name);
708 doresize(z);
709}
710
711function doresize(z)
712{
713 var img = $("image"+z);
714 var canv = $("canvas"+z);
715 if (!img || !canv)
716 return;
717
718 var h = $("table"+z).offsetHeight;
719 if (h == 0)
720 return;
721
722 // ===========================================
723 /*
724 var tb = $("tbody"+z);
725 var hw = $("thead"+z).clientHeight;
726 var fw = $("tfoot"+z).clientHeight;
727
728 tb.style.height = (window.innerHeight-hw-fw)+"px";
729 */
730 // ===========================================
731
732 var fixedw = $("body").displayFixedWidth;//getAttribute("data-width");
733 var fixedh = $("body").displayFixedHeight;//getAttribute("data-height");
734
735 var W = fixedw>0 ? fixedw : window.innerWidth;
736 var H = fixedh>0 ? fixedh : window.innerHeight;
737
738 //var max = $("body").getAttribute("data-max")=="yes";
739 var max = $("body").displayMax;
740
741 var ih = max ? W : H - h + parseInt(img.style.height, 10);
742
743 // This might create the scroll bar
744
745 if (img.style.height!=ih+"px")
746 img.style.height = ih+"px";
747 if (canv.height!=ih)
748 canv.height = ih;
749
750 // now we can evaluate the correct view-port
751 // (-2 is the border size of the parent element 'container')
752 //var sW = (fixedw ? fixedw : $("table"+z).scrollWidth)-2;
753 var sW = fixedw ? fixedw : canv.parentNode.clientWidth;
754
755 if (img.style.width!=sW+"px")
756 img.style.width = sW+"px";
757 if (canv.width!=sW)
758 canv.width = sW;
759
760 // ------ debug -----
761 if (debug == true)
762 {
763 $('debug'+z).innerHTML = "";
764 $('debug'+z).innerHTML += "|W="+W +"/"+H;
765 $('debug'+z).innerHTML += "|H="+h+"/"+$("table"+z).offsetHeight+"/"+img.offsetHeight;
766 $('debug'+z).innerHTML += "|I="+img.style.height+"+"+H+"-"+h;
767 }
768}
769
770var intervalSlide = null;
771
772function changePage(oldz, newz)
773{
774 // No page displayed yet
775 if (oldz==newz)
776 {
777 $("table"+newz).style.left="0px";
778 $("body").visiblePage = newz; //.setAttribute("data-visible", newz);
779
780 doresize(0);
781
782 //setInterval(refresh_text, 1000);
783 //setInterval(refresh_graphics, 5000);
784
785 refresh_text();
786
787 // first: decode the pixel mapping!
788 var sum = 1036080;
789 for (var i=0; i<1440; i++)
790 {
791 var d0 = codedMap.charCodeAt(i*2) -48;
792 var d1 = codedMap.charCodeAt(i*2+1)-48;
793
794 map[i] = d0 | (d1<<6);
795 sum -= map[i];
796 }
797 if (sum!=0)
798 alert("Pixel mapping table corrupted!");
799
800 refresh_graphics();
801 return;
802 }
803
804 var W = window.innerWidth;
805 if (W==0 || $("body").displayNoslide)//$("body").getAttribute("data-noslide")=="yes")
806 {
807 $("body").visiblePage = newz;//setAttribute("data-visible", newz);
808 $("body").removeChild($("table"+oldz));
809 $("table"+newz).style.left="0px";
810 return;
811 }
812
813 if (newz>oldz)
814 $("table"+newz).style.left = W+"px";
815 else
816 $("table"+newz).style.left = (-W-1)+"px";
817
818 $("body").visiblePage = newz;//setAttribute("data-visible", newz);
819
820 // This is needed on my mobile to ensure that te browser
821 // doesn't try to zoom during shifting
822 $("table"+newz).style.position="fixed";
823 $("table"+oldz).style.position="fixed";
824
825 intervalSlide = setInterval(function (){doShift(oldz,newz);}, 75);
826}
827
828function doShift(oldz, newz)
829{
830 var t0 = $("table"+oldz);
831 var t1 = $("table"+newz);
832
833 if (t0.style.display=="none")
834 {
835 clearInterval(intervalSlide);
836 $("body").removeChild(t0);
837
838 t1.style.position="absolute";
839
840 // Now the scroll bar might have to appear or disappear
841 doresize(newz);
842 return;
843 }
844
845 var x0 = t0.offsetLeft;
846 var x1 = t1.offsetLeft;
847
848 var W = window.innerWidth;
849
850 if (newz<oldz)
851 {
852 x0 += W/5;
853 x1 += W/5;
854 }
855
856 if (newz>oldz)
857 {
858 x0 -= W/5;
859 x1 -= W/5;
860 }
861
862 if ((newz<oldz && x1>=0) || (newz>oldz && x1<=0))
863 {
864 t0.style.display="none";
865 x1 = 0;
866 }
867
868 t0.style.left = x0+"px";
869 t1.style.left = x1+"px";
870}
871
872var timeoutText = null;
873var timeoutGraphics = null;
874
875function refresh_text()
876{
877 var z=$("body").visiblePage;//getAttribute("data-visible");
878
879 var fname = $("table"+z).pageName;//getAttribute("data-file");
880
881 var is_help = fname.substr(0,5)=="help-";
882
883 // Is sliding, no file defined or just help text?
884 if (isSliding() || !valid(fname) || is_help)
885 {
886 if (is_help)
887 {
888 setUTC($("localtime"+z), new Date());
889 $("reporttime"+z).innerHTML="";
890 }
891
892 // invalidate?
893 timeoutText = setTimeout(refresh_text, 1000);
894 return;
895 }
896
897 var xmlText = new XMLHttpRequest();
898 xmlText.open('POST', "data/"+fname+'.data', true);
899 xmlText.onload = function ()
900 {
901 if (xmlText.status!=200)
902 {
903 alert("ERROR[1] - HTTP request '"+fname+".data': "+xmlText.statusText+" ["+xmlText.status+"]");
904 timeoutText = setTimeout(refresh_text, 10000);
905 return;
906 }
907
908 if (!isSliding())
909 {
910 cycleCol($("ldot"+z));
911 update_text(fname, xmlText.responseText);
912 doresize(z);
913 }
914 timeoutText = setTimeout(refresh_text, 3000);
915 };
916 xmlText.send(null);
917}
918
919var date0 = null;
920
921var test = 0;
922function update_text(fname, result)
923{
924 var z=$("body").visiblePage;//getAttribute("data-visible");
925 var table = $("table"+z);
926
927 if (table.pageName/*getAttribute("data-file")*/ != fname)
928 return;
929
930 var tokens = result.split('\n');
931
932 // ----------------------------------------------------
933
934 var rtime = $("reporttime"+z);
935 var ltime = $("localtime"+z);
936
937 var now = new Date();
938
939 var header = tokens[0].split('\t');
940
941 // File corrupted / should we remove the date?)
942 if ((header.length>5 || header.length==2 || header.length==0) && header[0].length!=13)
943 {
944 // we ignore corrupted files for one minute
945 if (date0==null || date0.getTime()+60000<now.getTime())
946 rtime.style.color = "darkred";
947
948 return;
949 }
950
951 // File OK
952 date0 = now;
953
954 var stamp = new Date();
955 stamp.setTime(header[0]);
956
957 // File older than 1min
958 if (stamp.getTime()+60000<now.getTime())
959 rtime.style.color = "darkred";
960 else
961 rtime.style.color = "";
962
963 setUTC(rtime, stamp);
964 setUTC(ltime, now);
965
966 // ----------------------------------------------------
967
968 $("warn"+z).style.display = header.length>=4 && header[3]=='1' ? "" : "none";
969
970 if (header.length>=5)
971 $("cmd"+z).style.backgroundColor = header[4]=='1' ? "darkgreen" : "darkred";
972
973 if (header.length>=3 && $("body").sound)
974 {
975 $("speaker"+z).style.display = "none";
976
977 var audio = $("audio");
978
979 var audio_date = new Date();
980 audio_date.setTime(header[1]);
981
982 // Time stamp of audio file must be newer than page load
983 // or last audio play respecitvely
984 if (audio_date>audio.date && header[2].length>0)
985 {
986 var name = "audio/"+header[2];
987
988 var mp3 = $new("SOURCE");
989 var ogg = $new("SOURCE");
990 mp3.src = name+".mp3";
991 ogg.src = name+".ogg";
992
993 audio.replaceChild(mp3, audio.firstChild);
994 audio.replaceChild(ogg, audio.lastChild);
995
996 audio.load();
997 audio.play();
998
999 audio.date = audio_date;
1000 }
1001 }
1002
1003 // ----------------------------------------------------
1004
1005 //var p = table.tBodies.length==3 ? 1 : 0;
1006 //var tbody = table.tBodies[p];
1007
1008 for (var line=1; line<tokens.length; line++)
1009 {
1010 if (tokens[line].length==0)
1011 continue;
1012
1013 var e = $("data"+z+"-"+line);
1014 if (!e)
1015 continue;
1016
1017 var form = e.dataFormat;//getAttribute("data-form");
1018 if (!form)
1019 continue;
1020
1021 var cols = tokens[line].split('\t');
1022 for (var col=1; col<cols.length; col++)
1023 form = form.replace("\$"+(col-1), cols[col].length==0 ? "&mdash;" : cols[col]);
1024
1025 if (cols.length<=1)
1026 form = "&mdash;";
1027
1028 form = form.replace(/<#(.*?)>/g, "<font color='$1'>");
1029 form = form.replace(/<([\+-])>/g, "<font size='$11'>");
1030 form = form.replace(/<\/([#\+-])>/g, "</font>");
1031 form = form.replace(/([0-9][0-9]):([0-9][0-9]):([0-9][0-9])/g,
1032 "<pre>$1</pre>:<pre>$2</pre>:<pre>$3</pre>");
1033 form = form.replace(/--:--:--/g, "<pre> </pre> <pre> </pre> <pre> </pre>");
1034
1035 var newe = $new("div");
1036 newe.innerHTML = form;
1037 e.replaceChild(newe, e.lastChild);
1038
1039 e.parentNode.parentNode.parentNode.parentNode.style.background=cols[0];
1040 }
1041}
1042
1043// http://billmill.org/static/canvastutorial/index.html
1044// http://www.netmagazine.com/tutorials/learning-basics-html5-canvas
1045// http://www.alistapart.com/articles/responsive-web-design/
1046
1047function refresh_graphics()
1048{
1049 var z = $("body").visiblePage;//getAttribute("data-visible");
1050
1051 var canvas = $("canvas"+z);
1052
1053 // Is sliding or no data file defined?
1054 var fname = canvas==null ? "" : canvas.fileName;//getAttribute("data-file");
1055 if (isSliding() || !valid(fname))
1056 {
1057 // invalidate?
1058 timeoutGraphics = setTimeout(refresh_graphics, 3000);
1059 return;
1060 }
1061
1062 var xmlGfx = new XMLHttpRequest();
1063 xmlGfx.open('POST', "data/"+fname, true);
1064 xmlGfx.onload = function ()
1065 {
1066 if (xmlGfx.status!=200)
1067 {
1068 alert("ERROR[2] - Request '"+fname+"': "+xmlGfx.statusText+" ["+xmlGfx.status+"]");
1069 timeoutGraphics = setTimeout(refresh_graphics, 10000);
1070 //****** invalidate ******
1071 return;
1072 }
1073
1074 if (!isSliding())
1075 {
1076 cycleCol($("rdot"+z));
1077 process_eventdata(xmlGfx.responseText);
1078 }
1079 timeoutGraphics = setTimeout(refresh_graphics, 5000)
1080 };
1081 xmlGfx.send(null);
1082}
1083
1084
1085function hueToRGB(hue)
1086{
1087 hue /= 3;
1088 hue %= 6;
1089
1090 if (hue<1) return parseInt(255*hue, 10);
1091 if (hue<3) return parseInt(255, 10);
1092 if (hue<4) return parseInt(255*(4-hue), 10);
1093
1094 return 0.
1095}
1096
1097function hueToHex(flt)
1098{
1099 var s = hueToRGB(flt).toString(16);
1100 return s.length==2 ? s : "0"+s;
1101}
1102
1103function HLStoRGB(hue)
1104{
1105 hue *= 14;
1106
1107 var sr = hueToHex(20-hue);
1108 var sg = hueToHex(14-hue);
1109 var sb = hueToHex(26-hue);
1110
1111 return sr+sg+sb;
1112}
1113
1114function color(col)
1115{
1116 if (col==65533)
1117 return HLStoRGB(0);
1118
1119 var hue = col/126;
1120 return HLStoRGB(hue);
1121}
1122
1123function toHex(str, idx)
1124{
1125 var ch = str[idx].toString(16);
1126 return ch.length==2 ? ch : "0"+ch;
1127}
1128
1129function drawHex(ctx, x, y, col)
1130{
1131 ctx.fillStyle = "#"+color(col);
1132
1133 ctx.save();
1134
1135 ctx.translate(x, y);
1136 ctx.scale(1/2, 1/3);
1137
1138 ctx.beginPath();
1139 ctx.moveTo( 1, 1);
1140 ctx.lineTo( 0, 2);
1141 ctx.lineTo(-1, 1);
1142 ctx.lineTo(-1, -1);
1143 ctx.lineTo( 0, -2);
1144 ctx.lineTo( 1, -1);
1145 ctx.fill();
1146
1147 ctx.restore();
1148}
1149
1150function drawDisc(ctx, x, y, r, col)
1151{
1152 ctx.fillStyle = "#"+color(col);
1153
1154 ctx.save();
1155
1156 ctx.translate(x, y);
1157
1158 ctx.beginPath();
1159 ctx.arc(0, 0, r, 0, Math.PI*2, true);
1160 ctx.fill();
1161
1162 ctx.restore();
1163}
1164
1165function beginDrawCam(scale)
1166{
1167 var z = $("body").visiblePage;//getAttribute("data-visible");
1168 var canv = $("canvas"+z);
1169
1170 var w = Math.min(canv.width/scale, canv.height/scale);
1171
1172 var ctx = canv.getContext("2d");
1173
1174 ctx.save();
1175 ctx.translate(canv.width/2, canv.height/2);
1176 ctx.scale(w*2, w*2);
1177
1178 return ctx;
1179}
1180
1181/**
1182 * @constructor
1183 */
1184function Position(s, ring, i)
1185{
1186 switch (s)
1187 {
1188 case 1: this.x = ring - i*0.5; this.y = + i; break;
1189 case 2: this.x = ring*0.5 - i; this.y = ring ; break;
1190 case 3: this.x = -ring*0.5 - i*0.5; this.y = ring - i; break;
1191 case 4: this.x = -ring + i*0.5; this.y = - i; break;
1192 case 5: this.x = -ring*0.5 + i; this.y = -ring ; break;
1193 case 0: this.x = ring*0.5 + i*0.5; this.y = -ring + i; break;
1194 }
1195 this.d = (function () { return this.x*this.x + this.y*this.y*3/4; });
1196}
1197
1198function drawFullCam(data)
1199{
1200 if (data.length!=40 && data.length!=160 && data.length!=320 && data.length!=1440)
1201 {
1202 alert("Camera - Received data has invalid size ("+data.length+"b)");
1203 return;
1204 }
1205
1206 var div = map.length/data.length;
1207 var off = data.length==320 ? 0.2 : 0;
1208
1209 var ctx = beginDrawCam(83);
1210 // ctx.rotate(Math.PI/3);
1211
1212 ctx.scale(1, Math.sqrt(3)/2);
1213 ctx.translate(-0.5, 0);
1214
1215 drawHex(ctx, 0, 0, data.charCodeAt(parseInt(map[0]/div+off, 10)));
1216
1217 var cnt = 1;
1218 for (var ring=1; ring<24; ring++)
1219 {
1220 for (var s=0; s<6; s++)
1221 {
1222 for (var i=1; i<=ring; i++)
1223 {
1224 var pos = new Position(s, ring, i);
1225 if (pos.d() - pos.x > 395.75)
1226 continue;
1227
1228 var p = parseInt(map[cnt]/div+off, 10);
1229
1230 drawHex(ctx, pos.x, pos.y, data.charCodeAt(p));
1231 cnt++;
1232 }
1233 }
1234 }
1235
1236 drawHex(ctx, 7, -22, data.charCodeAt(parseInt(map[1438]/div+off, 10)));
1237 drawHex(ctx, 7, 22, data.charCodeAt(parseInt(map[1439]/div+off, 10)));
1238
1239 ctx.restore();
1240}
1241
1242function drawCam(data)
1243{
1244 var ctx = beginDrawCam(27);
1245 ctx.rotate(Math.PI/6);
1246 ctx.scale(1, Math.sqrt(3)/2);
1247
1248 drawHex(ctx, 0, 0, data.charCodeAt(0));
1249
1250 var cnt = 1;
1251 for (var ring=1; ring<=7; ring++)
1252 {
1253 for (var s=0; s<6; s++)
1254 {
1255 for (var i=1; i<=ring; i++)
1256 {
1257 var pos = new Position(s, ring, i);
1258 if (pos.d() > 44)
1259 continue;
1260
1261 if (ring==7)
1262 {
1263 if (i==6 && (s==0 || s==3))
1264 continue;
1265 if (i==1 && (s==1 || s==4))
1266 continue;
1267 }
1268
1269 drawHex(ctx, pos.x, pos.y, data.charCodeAt(cnt++));
1270 }
1271 }
1272 }
1273
1274 ctx.restore();
1275}
1276
1277function drawCamLegend(canv, data)
1278{
1279 var unit = canv.dataUnit;//htmlDecode(canv.getAttribute("data-data"));
1280
1281 var umin = data[1];
1282 var umax = data[2];
1283
1284 var min = data[3]+unit
1285 var med = data[4]+unit;
1286 var max = data[5]+unit;
1287
1288 var v0 = parseFloat(umin);
1289 var v1 = parseFloat(umax);
1290
1291 var diff = v1-v0;
1292
1293 var cw = canv.width;
1294 //var ch = canv.height;
1295
1296 var ctx = canv.getContext("2d");
1297
1298 ctx.font = "8pt Arial";
1299 ctx.textAlign = "right";
1300 ctx.textBaseline = "top";
1301
1302 for (var i=0; i<11; i++)
1303 {
1304 ctx.strokeStyle = "#"+color(126*i/10);
1305 ctx.strokeText((v0+diff*i/10).toPrecision(3)+unit, cw-5, 125-i*12);
1306 }
1307
1308 var mw = Math.max(ctx.measureText(min).width,
1309 ctx.measureText(med).width,
1310 ctx.measureText(max).width);
1311
1312 ctx.textBaseline = "top";
1313 ctx.strokeStyle = "#000";
1314
1315 ctx.strokeText(min, 5+mw, 5+24);
1316 ctx.strokeText(med, 5+mw, 5+12);
1317 ctx.strokeText(max, 5+mw, 5);
1318}
1319
1320function drawGraph(canv, vals, data)
1321{
1322 var unit = canv.dataUnit;//htmlDecode(canv.getAttribute("data-data"));//.split("/");
1323
1324 var umin = vals[1]+unit;
1325 var umax = vals[2]+unit;
1326
1327 var stat = vals.length==4 ? vals[3] :
1328 vals[3]+unit+" / "+vals[4]+unit+" / "+vals[5]+unit;
1329
1330 var cw = canv.width;
1331 var ch = canv.height;
1332
1333 var ctx = canv.getContext("2d");
1334
1335 var dw = 3; // tick width
1336 var fs = 8; // font size
1337
1338 ctx.font = fs+"pt Arial";
1339 ctx.textAlign = "right";
1340
1341 var dim0 = ctx.measureText(umin);
1342 var dim1 = ctx.measureText(umax);
1343
1344 var tw = Math.max(dim0.width, dim1.width)+dw+2;
1345
1346 var ml = 5+tw; // margin left
1347 var mr = 10; // margin right
1348
1349 var mt = 5+2*fs+4; // margin top
1350 var mb = fs/2+4; // margin bottom
1351
1352 var nx = 20;
1353 var ny = 10;
1354
1355 var w = cw-ml-mr;
1356 var h = ch-mt-mb;
1357
1358 ctx.strokeStyle = "#666";
1359
1360 // --- data ---
1361 var cnt = 0;
1362 for (var j=1; j<data.length; j++)
1363 {
1364 if (data[j].length<2)
1365 continue;
1366
1367 ctx.beginPath();
1368 ctx.moveTo(ml, ch-mb-data[j].charCodeAt(0)/126*h);
1369 for (var i=1; i<data[j].length; i++)
1370 ctx.lineTo(ml+w/(data[j].length-1)*i, ch-mb-data[j].charCodeAt(i)/126*h);
1371
1372 // --- finalize data ---
1373 ctx.lineTo(cw-mr, ch-mb);
1374 ctx.lineTo(ml, ch-mb);
1375 ctx.fillStyle = "#"+color(100);
1376 ctx.stroke();
1377
1378 cnt++;
1379 }
1380 if (cnt==1)
1381 ctx.fill();
1382
1383 ctx.beginPath();
1384
1385 // --- grid ---
1386
1387 ctx.strokeStyle = "#eee";
1388
1389 for (var i=1; i<=nx; i++)
1390 {
1391 ctx.moveTo(ml+w*i/nx, ch-mb);
1392 ctx.lineTo(ml+w*i/nx, mt);
1393 }
1394 for (var i=0; i<ny; i++)
1395 {
1396 ctx.moveTo(ml, mt+h*i/ny);
1397 ctx.lineTo(ml+w, mt+h*i/ny);
1398 }
1399 ctx.stroke();
1400 ctx.closePath();
1401 ctx.beginPath();
1402
1403 ctx.strokeStyle = "#000";
1404
1405 // --- axes ---
1406 ctx.moveTo(ml, mt);
1407 ctx.lineTo(ml, ch-mb);
1408 ctx.lineTo(cw-mr, ch-mb);
1409
1410 for (var i=1; i<=nx; i++)
1411 {
1412 ctx.moveTo(ml+w*i/nx, ch-mb-dw);
1413 ctx.lineTo(ml+w*i/nx, ch-mb+dw);
1414 }
1415 for (var i=0; i<ny; i++)
1416 {
1417 ctx.moveTo(ml-dw, mt+h*i/ny);
1418 ctx.lineTo(ml+dw, mt+h*i/ny);
1419 }
1420 ctx.stroke();
1421 ctx.closePath();
1422
1423 ctx.textBaseline = "bottom";
1424 ctx.strokeText(umin, ml-dw-2, ch-1);
1425
1426 ctx.textBaseline = mt>fs/2 ? "middle" : "top";
1427 ctx.strokeText(umax, ml-dw-2, mt);
1428
1429 ctx.textBaseline = "top";
1430 ctx.textAlign = "center";
1431 ctx.strokeText(stat, ml+w/2, 5);
1432}
1433
1434function invalidateCanvas(canv)
1435{
1436 var ctx = canv.getContext("2d");
1437
1438 ctx.fillStyle = "rgba(255, 255, 255, 0.75)";
1439 ctx.fillRect(0, 0, canv.width, canv.height);
1440}
1441
1442function processGraphicsData(canv, result)
1443{
1444 if (result.length==0)
1445 return false;
1446
1447 var ctx = canv.getContext("2d");
1448 ctx.clearRect(0, 0, canv.width, canv.height);
1449
1450 var data = result.split('\x7f');
1451 if (data.length<2)
1452 return false;
1453
1454 var header = data[0].split('\n');
1455 if (header.length<4)
1456 return false;
1457
1458 switch (canv.dataType)
1459 {
1460 //case "camera": drawCam(result); break;
1461 case "hist":
1462 drawGraph(canv, header, data);
1463 break;
1464 case "camera":
1465 drawFullCam(data[1]);
1466 drawCamLegend(canv, header);
1467 break;
1468 }
1469
1470 var now = new Date();
1471 var tm = new Date();
1472 tm.setTime(header[0]);
1473
1474 if (tm.getTime()+60000<now.getTime())
1475 return false;
1476
1477 //$("image"+z).src = canv.toDataURL("image/png");
1478
1479 return true;
1480}
1481
1482function process_eventdata(result)
1483{
1484 var z = $("body").visiblePage;//getAttribute("data-visible");
1485 var canv = $("canvas"+z);
1486 if (!canv)
1487 return;
1488
1489 if (!processGraphicsData(canv, result))
1490 invalidateCanvas(canv);
1491}
1492
1493function save()
1494{
1495 var z = $("body").visiblePage;//getAttribute("data-visible");
1496
1497 var canvas = $("canvas"+z);
1498 var img = canvas.toDataURL("image/png");
1499
1500 img = img.replace("image/png", "image/octet-stream");
1501
1502 document.location.href = img;
1503}
1504
1505window['onload'] = onload;
Note: See TracBrowser for help on using the repository browser.