source: trunk/FACT++/www/viewer/index.js@ 17729

Last change on this file since 17729 was 17728, checked in by tbretz, 11 years ago
Added marker for selected pixel; added runinfo and trigger info; updated position of autocomplete dialog
File size: 32.4 KB
Line 
1'use strict';
2
3var editor1;
4var editor2;
5var plot;
6
7function debug(txt)
8{
9 var dbg = document.getElementById("debug");
10 dbg.appendChild(document.createTextNode(txt));
11 dbg.appendChild(document.createElement("br"));
12}
13
14function setupAccordion(accordion, container, inactive)
15{
16 function onAccordion(event, ui)
17 {
18 if (ui.oldHeader.length==0)
19 $(container).slideDown(400);
20 else
21 $(container).slideUp(400);
22 }
23
24 var config = { collapsible: true };
25
26 if (inactive)
27 {
28 config.active = false;
29 $(container).hide();
30 }
31
32 var acc = $(accordion);
33
34 acc.accordion(config);
35 acc.on("accordionbeforeactivate", onAccordion);
36}
37
38function onResize(event, ui)
39{
40 if (!ui.size)
41 return;
42
43 $(event.target.id).css({marginRight:'2px'});
44
45 var editor = event.target.id=="textcontainer1" ? editor1 : editor2;
46
47 editor.setSize("100%", ui.size.height);
48 editor.refresh();
49}
50
51function onResizeCenter(event, ui)
52{
53 var w = document.getElementById("cameracontainer").clientWidth/4;
54
55 var offy = 0;
56 var offx = 5;
57
58 var cont = document.getElementById("center").childNodes[0];
59
60 var nn;
61 if (cont)
62 {
63 nn = parseInt(cont.id[cont.id.length-1]);
64
65 document.getElementById("camera"+nn).height=parseInt(w*2);
66 document.getElementById("camera"+nn).width=parseInt(w*2);
67 }
68
69 if (nn!=1)
70 {
71 document.getElementById("camera1").height=parseInt(w)-offy;
72 document.getElementById("camera1").width=parseInt(w)-offx;
73 }
74
75 if (nn!=2)
76 {
77 document.getElementById("camera2").height=parseInt(w)-offy;
78 document.getElementById("camera2").width=parseInt(w)-offx;
79 }
80
81 if (nn!=3)
82 {
83 document.getElementById("camera3").height=parseInt(w)-offy;
84 document.getElementById("camera3").width=parseInt(w)-offx;
85 }
86
87 if (nn!=4)
88 {
89 document.getElementById("camera4").height=parseInt(w)-offy;
90 document.getElementById("camera4").width=parseInt(w)-offx;
91 }
92
93 document.getElementById("center").width=parseInt(w*2);
94
95 document.getElementById("cont1").width=parseInt(w);
96 document.getElementById("cont2").width=parseInt(w);
97 document.getElementById("cont3").width=parseInt(w);
98 document.getElementById("cont4").width=parseInt(w);
99
100 document.getElementById("cont1").height=parseInt(w);
101 document.getElementById("cont2").height=parseInt(w);
102 document.getElementById("cont3").height=parseInt(w);
103 document.getElementById("cont4").height=parseInt(w);
104
105 drawFullCam("camera1");
106 drawFullCam("camera2");
107 drawFullCam("camera3");
108 drawFullCam("camera4");
109}
110
111function createEditor(textarea)
112{
113 var editor;
114
115 var config =
116 {
117 //value: "function myScript(){return 100;}\n",
118 mode: { name: "text/typescript", globalVars: true },
119 lineNumbers: true,
120 styleActiveLine: true,
121 matchBrackets: true,
122 indentUnit: 4,
123 foldGutter: true,
124 gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
125 extraKeys: {
126 //"Ctrl-D": "duplicateLine",
127 //"Alt--": "goToBracket",
128 //"Ctrl-H": "findPrev",
129 "Ctrl-Down": "autocomplete",
130 "Tab": "indentAuto",
131 "Ctrl-Y": "deleteLine",
132 "Ctrl-.": function(cm) {
133 cm.foldCode(cm.getCursor());
134 },
135 "F11": function(cm) {
136 editor.setOption("fullScreen", !editor.getOption("fullScreen"));
137 },
138 "Ctrl-R": function(cm) {
139 editor.execCommand("replace");
140 },
141 "Esc": function(cm) {
142 if (editor.getOption("fullScreen")) editor.setOption("fullScreen", false);
143 },
144 "Enter": function(cm) {
145 editor.execCommand("indentAuto");
146 editor.execCommand("newlineAndIndent");
147 },
148 }
149
150 };
151
152 editor = CodeMirror.fromTextArea(document.getElementById(textarea), config);
153 editor.setOption("theme", "blackboard");
154
155 return editor;
156}
157
158function colorizeHTML(textarea)
159{
160 var config =
161 {
162 //value: "function myScript(){return 100;}\n",
163 mode: { name: "text/typescript", globalVars: true },
164 readOnly: true,
165 };
166
167 CodeMirror.fromTextArea(document.getElementById(textarea), config);
168}
169
170function disableControls(disabled)
171{
172 $('#submit').prop('disabled', disabled);
173 $('#event').prop('disabled', disabled);
174 $('#pixel').prop('disabled', disabled);
175 $('#cbpx').prop('disabled', disabled);
176 $('#cbpx-c').prop('disabled', disabled);
177 $('#cbpx-b').prop('disabled', disabled);
178 $('#cbpx-p').prop('disabled', disabled);
179 $('#cbpx-x').prop('disabled', disabled);
180 $('#file').prop('disabled', disabled);
181}
182
183function onReady()
184{
185 //$('input,select').keypress(function(event) { return event.keyCode != 13; });
186
187 //colorizeHTML("code0");
188 //colorizeHTML("code1");
189
190 $("#accordion").accordion({collapsible:true,active:false,heightStyle:'content'});
191 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
192 if (location.href.search('debug')==-1)
193 $("#accordion").find('h3').filter(':contains(Debug)').hide();
194
195 $("#textcontainer1").resizable({handles:"s",autoHide:true,});
196 $("#textcontainer1").on("resize", onResize);
197
198 $("#textcontainer2").resizable({handles:"s",autoHide:true,});
199 $("#textcontainer2").on("resize", onResize);
200
201 $("#cameracontainer").on("resize", onResizeCenter);
202 onResizeCenter();
203
204 $("#cont1").click(onClickNew);
205 $("#cont2").click(onClickNew);
206 $("#cont3").click(onClickNew);
207 $("#cont4").click(onClickNew);
208
209 $("#camera1").click(onClick);
210 $("#camera2").click(onClick);
211 $("#camera3").click(onClick);
212 $("#camera4").click(onClick);
213
214 editor1 = createEditor("editor1");
215 editor2 = createEditor("editor2");
216
217 setupAccordion('#accordion5', '#editorcontainer1', true);
218 setupAccordion('#accordion1', '#editorcontainer2');
219
220 $('#accordion5').on("accordionactivate", function() { $('#editorcontainer1fake').hide(); editor1.refresh(); });
221 $('#accordion1').on("accordionactivate", function() { $('#editorcontainer2fake').hide(); editor2.refresh(); });
222
223 setupAccordion('#accordion2', '#cameracontainer');
224 setupAccordion('#accordion3', '#waveformcontainer');
225 setupAccordion('#accordion4', '#helpcontainer', true);
226
227 $("#selectfile1").on('change', onFile);
228 $("#selectfile2").on('change', onFile);
229
230 $(document).ajaxStart(function() { disableControls(true) }).ajaxStop(function() { disableControls(false); });
231
232
233 $.ajax({
234 type: "POST",
235 cache: false,
236 url: "index.php",
237 success: onFilelistReceived,
238 error: function(xhr) { if (xhr.status==0) alert("ERROR[0] - Request failed!"); else alert("ERROR[0] - "+xhr.statusText+" ["+xhr.status+"]"); }
239 });
240}
241
242function onFileSelect(event, ui)
243{
244 onSubmit(ui.item.value);
245}
246
247function onFilelistReceived(result)
248{
249 var dbg = document.getElementById("debug");
250
251 var pre = document.createElement("pre");
252 pre.appendChild(document.createTextNode(rc));
253 dbg.appendChild(pre);
254
255 var rc;
256 try
257 {
258 rc = JSON.parse(result);
259 }
260 catch (e)
261 {
262 alert("ERROR[0] - Decoding answer:\n"+e);
263 return;
264 }
265
266 var opts =
267 {
268 source: rc,
269 select: onFileSelect,
270 position: { my: "right top", at: "right bottom", collision: "flipfit" },
271 };
272
273 $("#file").autocomplete(opts);
274 document.getElementById("file").value = "2014/04/17-181";
275
276 onSubmit("2014/04/17-181");
277}
278
279function setZoom(xfrom, xto, yfrom, yto)
280{
281 var xaxis = plot.getXAxes()[0];
282 var yaxis = plot.getYAxes()[0];
283
284 if (xfrom!==undefined)
285 xaxis.options.min = xfrom;
286 if (xto!==undefined)
287 xaxis.options.max = xto;
288
289 if (yfrom!==undefined)
290 yaxis.options.min = yfrom;
291 if (yto!==undefined)
292 yaxis.options.max = yto;
293
294 plot.setupGrid();
295 plot.draw();
296 plot.clearSelection();
297}
298
299function processCameraData(id, data)
300{
301 var canv = document.getElementById(id);
302
303 canv.dataAbs = [ ];
304 for (var i=0; i<1440; i++)
305 if (data[i]!==undefined && data[i]!==null)
306 canv.dataAbs[i] = data[i];
307
308 canv.min = Math.min.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
309 canv.max = Math.max.apply(Math, canv.dataAbs.filter(function(e){return !isNaN(e)}));
310
311 canv.dataRel = [ ];
312 for (var i=0; i<1440; i++)
313 if (data[i]!==undefined && data[i]!==null)
314 canv.dataRel[i] = (data[i]-canv.min)/canv.max;
315
316 var n = id[id.length-1];
317
318 if (document.getElementById("cameraminon"+n).checked)
319 document.getElementById("cameramin"+n).value = canv.min;
320 if (document.getElementById("cameramaxon"+n).checked)
321 document.getElementById("cameramax"+n).value = canv.max;
322}
323
324
325function onDataReceived(rc)
326{
327 var err = document.getElementById("error");
328 var dbg = document.getElementById("debug");
329 var con = document.getElementById("console");
330
331 var pre = document.createElement("pre");
332 pre.appendChild(document.createTextNode(rc));
333 dbg.appendChild(pre);
334
335 try
336 {
337 rc = JSON.parse(rc);
338 }
339 catch (e)
340 {
341 alert("ERROR[1] - Decoding answer:\n"+e);
342 return;
343 }
344
345 var evt = rc.event;
346 var file = rc.file;
347
348 document.getElementById("event").max = file.numEvents;
349 var el = document.getElementById("numevents");
350 if (el.firstChild)
351 el.removeChild(el.firstChild);
352 el.appendChild(document.createTextNode(file.numEvents));
353
354 var infotxt = "<pre>";
355 infotxt += "\nStart time: "+new Date(file.runStart*24*3600*1000).toUTCString();
356 infotxt += "\nEnd time: "+new Date(file.runEnd*24*3600*1000).toUTCString();
357 infotxt += "\nRun type: "+file.runType;
358 if (file.drsFile>=0)
359 infotxt += " [drs-step "+file.drsFile+"]";
360
361 $("#runinfo").html(infotxt);
362 $("#eventinfo").html("Trigger: "+evt.trigger.join(' | ')+" [0x"+evt.triggerType.toString(16)+"]");
363
364 if (rc.ret)
365 {
366 while (con.lastChild)
367 con.removeChild(con.lastChild);
368 }
369
370 if (rc.err)
371 {
372 while (err.lastChild)
373 err.removeChild(err.lastChild);
374
375 err.appendChild(document.createTextNode("Javascript runtime exception: "+rc.err.file+":"+rc.err.lineNumber));
376 err.appendChild(document.createTextNode("\n"));
377 err.appendChild(document.createTextNode(rc.err.sourceLine));
378 err.appendChild(document.createTextNode("\n"));
379 err.appendChild(document.createTextNode(rc.err.trace));
380
381 var editor = rc.err.file=="main" ? editor2 : editor1;
382 editor.setCursor(rc.err.lineNumber-1, 1);
383
384 $("#accordion").find('h3').filter(':contains(Runtime)').show();
385 $("#accordion").accordion("option", "active", 0);
386 }
387
388 var canv = document.getElementById("camera1");
389
390 if (rc.debug!==undefined)
391 {
392 con.appendChild(document.createTextNode(rc.debug));
393
394 debug("return "+JSON.stringify(rc.ret));
395 debug("");
396 debug("Execution times:");
397 debug("Time Javascripts = "+(rc.timeJs[0]*1000).toFixed(2)+","+(rc.timeJs[1]*1000).toFixed(2)+","+(rc.timeJs[2]*1000).toFixed(2)+ " [ms]");
398 }
399
400 if (rc.ret!==undefined && Array.isArray(rc.ret))
401 {
402 if (!Array.isArray(rc.ret[0]))
403 processCameraData("camera1", rc.ret);
404 else
405 processCameraData("camera1", rc.ret[0]);
406
407 if (rc.ret.length>1)
408 processCameraData("camera2", rc.ret[1]);
409
410 if (rc.ret.length>2)
411 processCameraData("camera3", rc.ret[2]);
412
413 if (rc.ret.length>3)
414 processCameraData("camera4", rc.ret[3]);
415 }
416
417 // We have to redraw all of them to display the changed pixel value
418 onCameraMinMax(1);
419 onCameraMinMax(2);
420 onCameraMinMax(3);
421 onCameraMinMax(4);
422
423 //if (canv.dataAbs && evt)
424 // document.getElementById("value").value = canv.dataAbs[evt.pixel];
425
426 debug("Total time = "+(rc.timePhp*1000).toFixed(1)+" ms");
427 debug("Peak memory = "+rc.memory+" MiB");
428
429 if (Array.isArray(rc.waveform))
430 {
431 var waveform = document.getElementById("waveform");
432
433 var data = [[],[],[],[]];
434
435 var min = [];
436 var max = [];
437 if (Array.isArray(rc.waveform) && rc.waveform.length==evt.numRoi)
438 {
439 min.push(Math.min.apply(Math, rc.waveform));
440 max.push(Math.max.apply(Math, rc.waveform));
441
442 for (var i=0; i<evt.numRoi; i++)
443 data[0][i] = [ i, rc.waveform[i] ];
444 }
445
446 for (var j=0; j<4; j++)
447 {
448 var ref = rc.waveform[j];
449
450 if (Array.isArray(ref) && ref.length==evt.numRoi)
451 {
452 min.push(Math.min.apply(Math, ref));
453 max.push(Math.max.apply(Math, ref));
454
455 for (var i=0; i<evt.numRoi; i++)
456 data[j][i] = [ i, ref[i] ];
457
458 }
459 }
460
461 waveform.ymin = Math.min.apply(Math, min);
462 waveform.ymax = Math.max.apply(Math, max);
463 waveform.xmin = 0;
464 waveform.xmax = evt.numRoi;
465
466 if (document.getElementById("waveformminon").checked)
467 document.getElementById("waveformmin").value = waveform.ymin;
468 if (document.getElementById("waveformmaxon").checked)
469 document.getElementById("waveformmax").value = waveform.ymax;
470
471 var ymin = document.getElementById("waveformminon").checked ? waveform.ymin : parseInt(document.getElementById("waveformmin").value);
472 var ymax = document.getElementById("waveformmaxon").checked ? waveform.ymax : parseInt(document.getElementById("waveformmax").value);
473
474 var opts =
475 {
476 xaxis: {
477 min: waveform.xmin-1,
478 max: waveform.xmax+1,
479 },
480 yaxis: {
481 min: ymin-5,
482 max: ymax+5,
483 },
484 series: {
485 lines: {
486 show: true
487 },
488 points: {
489 show: true,
490 symbol: 'cross',
491 }
492 },
493 selection: {
494 mode: "xy"
495 },
496 grid: {
497 hoverable: true,
498 }
499 };
500
501 plot = $.plot("#waveform", data, opts);
502
503 waveform = $('#waveform');
504 waveform.bind("plotselected", function (event, ranges)
505 {
506 setZoom(ranges.xaxis.from, ranges.xaxis.to,
507 ranges.yaxis.from, ranges.yaxis.to);
508 });
509
510 waveform.dblclick(function ()
511 {
512 var waveform = document.getElementById("waveform");
513 setZoom(waveform.xmin-1, waveform.xmax+1, waveform.ymin-5, waveform.ymax+5);
514 });
515 waveform.bind("plothover", function (event, pos, item)
516 {
517 if (!item)
518 {
519 $("#tooltip").fadeOut(100);
520 return;
521 }
522
523 var x = item.datapoint[0].toFixed(2);
524 var y = item.datapoint[1].toFixed(2);
525 //item.series.label
526
527 var tooltip = $("#tooltip");
528 tooltip.html(parseInt(x) + " / " + y);
529 tooltip.css({top: item.pageY-20, left: item.pageX+5});
530 tooltip.fadeIn(200);
531 });
532 }
533
534 //$("#accordion").accordion("refresh");
535}
536
537function onSubmit(file, pixelOnly)
538{
539 if (!file)
540 file = document.getElementById("file").value;
541
542 var dbg = document.getElementById("debug");
543 while (dbg.lastChild)
544 dbg.removeChild(dbg.lastChild);
545
546 var active = $("#accordion").accordion("option", "active");
547 if (active==0)
548 {
549 $("#accordion").accordion("option", "active", false);
550 $("#accordion").find('h3').filter(':contains(Runtime)').hide();
551 }
552
553 var event = document.getElementById("event").value;
554 var pixel = document.getElementById("pixel").value;
555 var source1 = editor1.getValue();
556 var source2 = editor2.getValue();
557
558 var uri = "file="+file+"&event="+event+"&pixel="+map[pixel];
559 uri += "&source1="+encodeURIComponent(source1);
560 if (!pixelOnly)
561 uri += "&source2="+encodeURIComponent(source2);
562
563 $.ajax({
564 type: "POST",
565 cache: false,
566 url: "index.php",
567 data: uri,
568 success: onDataReceived,
569 error: function(xhr) { if (xhr.status==0) alert("ERROR[1] - Request failed!"); else alert("ERROR[1] - "+xhr.statusText+" ["+xhr.status+"]"); }
570 });
571}
572
573function onFile(event, ui)
574{
575 var f = event.target.files[0];
576 if (!f)
577 return;
578
579 if (!f.type.match('text/plain') && !f.type.match('application/javascript'))
580 {
581 alert("ERROR - Unknown file type.");
582 return;
583 }
584
585 var id = event.target.id;
586 var editor = id[id.length-1]=='1' ? editor1 : editor2;
587
588 var reader = new FileReader();
589
590 // Closure to capture the file information.
591 reader.onload = (function(theFile) { return function(e) { editor.setValue(e.target.result); }; })(f);
592 // onloadstart
593 // onloadend
594 // onprogress
595
596 // Read in the text file
597 reader.readAsText(f);
598}
599
600function onMarker()
601{
602 drawFullCam("camera1");
603 drawFullCam("camera2");
604 drawFullCam("camera3");
605 drawFullCam("camera4");
606}
607
608function onEvent()
609{
610 onSubmit();
611}
612
613function onPixel()
614{
615 var p = parseInt(document.getElementById("pixel").value);
616
617 var cbpx = map[p];
618
619 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
620 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
621 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
622 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
623 document.getElementById("cbpx").value = parseInt(cbpx);
624
625 onSubmit("", true);
626}
627
628function onCBPX()
629{
630 var c = parseInt(document.getElementById("cbpx-c").value);
631 var b = parseInt(document.getElementById("cbpx-b").value);
632 var p = parseInt(document.getElementById("cbpx-p").value);
633 var x = parseInt(document.getElementById("cbpx-x").value);
634
635 var cbpx = c*360 + b*36 + p*9 + x;
636
637 document.getElementById("cbpx").value = parseInt(cbpx);
638 document.getElementById("pixel").value = map.indexOf(cbpx);
639
640 onSubmit("", true);
641}
642
643function onHW()
644{
645 var cbpx = parseInt(document.getElementById("cbpx").value);;
646
647 document.getElementById("cbpx-c").value = parseInt((cbpx/360));
648 document.getElementById("cbpx-b").value = parseInt((cbpx/36)%10);
649 document.getElementById("cbpx-p").value = parseInt((cbpx/9)%4);
650 document.getElementById("cbpx-x").value = parseInt((cbpx%9));
651
652 document.getElementById("pixel").value = map.indexOf(cbpx);
653
654 onSubmit("", true);
655}
656
657function isInside(x, y, mouse)
658{
659 var dist = Math.sqrt((mouse.x-x)*(mouse.x-x)+(mouse.y-y)*(mouse.y-y));
660 return dist<0.5;
661
662 /*
663 ctx.translate(x, y);
664 ctx.scale(1/2, 1/3);
665
666 ctx.beginPath();
667 ctx.moveTo( 1, 1);
668 ctx.lineTo( 0, 2);
669 ctx.lineTo(-1, 1);
670 ctx.lineTo(-1, -1);
671 ctx.lineTo( 0, -2);
672 ctx.lineTo( 1, -1);
673 ctx.fill();
674
675 ctx.restore();
676 */
677}
678
679function getIndex(id, mouse)
680{
681 var canv = document.getElementById(id);
682
683 var scale = 83;
684
685 var w = Math.min(canv.width/scale, canv.height/scale);
686
687 //ctx.translate(canv.width/2, canv.height/2);
688 //ctx.scale(w*2, w*2);
689 //ctx.scale(1, Math.sqrt(3)/2);
690 //ctx.translate(-0.5, 0);
691
692 mouse.x -= canv.width/2;
693 mouse.y -= canv.height/2;
694 mouse.x /= w*2;
695 mouse.y /= w*2;
696 mouse.y /= Math.sqrt(3)/2;
697 mouse.x -= -0.5;
698
699 if (isInside(0, 0, mouse))
700 return 0;
701
702 var cnt = 1;
703 for (var ring=1; ring<24; ring++)
704 {
705 for (var s=0; s<6; s++)
706 {
707 for (var i=1; i<=ring; i++)
708 {
709 var pos = new Position(s, ring, i);
710 if (pos.d() - pos.x > 395.75)
711 continue;
712
713 if (isInside(pos.x, pos.y, mouse))
714 return cnt;
715 cnt++;
716 }
717 }
718 }
719
720 if (isInside(7, -22, mouse))
721 return 1438;
722 if (isInside(7, 22, mouse))
723 return 1439;
724
725 return -1;
726}
727
728var inprogress = 0;
729function moveAnimate(n, target)
730{
731 if (inprogress==n || inprogress<0)
732 return;
733
734 inprogress = target ? -n : n;
735
736 var element = $("#camera"+n); //Allow passing in either a JQuery object or selector
737 var newParent = $(target ? target : "#cont"+n); //Allow passing in either a JQuery object or selector
738
739 var oldOffset = element.offset();
740
741 var newOffset = newParent.offset();
742
743 var w = newParent.width();
744 var h = newParent.height();
745
746 var temp = element.appendTo('body');
747 temp.css('position', 'absolute')
748 .css('left', oldOffset.left)
749 .css('top', oldOffset.top)
750 .css('zIndex', 400);
751
752 temp.animate( {'top': newOffset.top, 'left':newOffset.left, 'width':w, 'height': h},
753 'slow', function()
754 {
755 temp = temp.appendTo(newParent);
756 temp.css('position', 'default');
757 temp.css('width', 'default');
758 temp.css('height', 'default');
759 temp.css('left', '0');
760 temp.css('top', '0');
761
762 var canv = document.getElementById("camera"+n);
763
764 canv.width = w;
765 canv.height = h;
766
767 drawFullCam("camera"+n);
768
769 inprogress = 0;
770 });
771}
772
773function onClickNew(event)
774{
775 var id = event.target.id;
776 var n = parseInt(id[id.length-1]);
777
778 if (id.substr(0, 3)=="cam")
779 {
780 var cont = document.getElementById("center").childNodes[0];
781 if (cont)
782 {
783 var nn = parseInt(cont.id[cont.id.length-1]);
784 moveAnimate(nn);
785 }
786 moveAnimate(n, "#center");
787
788 }
789 else
790 moveAnimate(n);
791}
792
793function onClick(event)
794{
795 var cont = document.getElementById("center").childNodes[0];
796 if (!cont)
797 return;
798
799 if (cont.id!=event.target.id)
800 return;
801
802 // get click position relative to canvas
803 var rect = event.target.getBoundingClientRect();
804
805 var x = event.clientX - rect.left;
806 var y = event.clientY - rect.top;
807
808 var mouse = { x: x, y: y };
809
810 // convert click position to pixel index
811 var index = getIndex(event.target.id, mouse);
812 if (index<0)
813 return;
814
815 document.getElementById("pixel").value = index;
816
817 onPixel();
818}
819
820function getClickPosition(event)
821{
822 var rect = event.target.getBoundingClientRect();
823
824 var x = event.clientX - rect.left;
825 var y = event.clientY - rect.top;
826
827 return { x: x, y: y };
828}
829
830function onCameraMinMax(n)
831{
832 var canv = document.getElementById("camera"+n);
833
834 canv.zmin = document.getElementById("cameramin"+n).value;
835 canv.zmax = document.getElementById("cameramax"+n).value;
836
837 drawFullCam("camera"+n);
838}
839
840function onCameraMinMaxOn(n)
841{
842 var canv = document.getElementById("camera"+n);
843
844 var redraw;
845 if (document.getElementById("cameraminon"+n).checked)
846 {
847 document.getElementById("cameramin"+n).setAttribute("disabled", "true");
848 document.getElementById("cameramin"+n).value = canv.min;
849 redraw = true;
850 }
851 else
852 document.getElementById("cameramin"+n).removeAttribute("disabled");
853
854 if (document.getElementById("cameramaxon"+n).checked)
855 {
856 document.getElementById("cameramax"+n).setAttribute("disabled", "true");
857 document.getElementById("cameramax"+n).value = canv.max;
858 redraw = true;
859 }
860 else
861 document.getElementById("cameramax"+n).removeAttribute("disabled");
862
863 if (redraw)
864 onCameraMinMax(n);
865}
866
867function onWaveformMinMax()
868{
869 var wf = document.getElementById("waveform");
870
871 var xmin, xmax, ymin, ymax;
872
873 var redraw;
874 if (!document.getElementById("waveformminon").checked)
875 ymin = document.getElementById("waveformmin").value;
876 if (!document.getElementById("waveformmaxon").checked)
877 ymax = document.getElementById("waveformmax").value;
878
879 setZoom(xmin, xmax, ymin, ymax);
880
881}
882
883function onWaveformMinMaxOn()
884{
885 var wf = document.getElementById("waveform");
886
887 var xmin, xmax, ymin, ymax;
888
889 var redraw;
890 if (document.getElementById("waveformminon").checked)
891 {
892 document.getElementById("waveformmin").setAttribute("disabled", "true");
893 document.getElementById("waveformmin").value = wf.ymin;
894 ymin = wf.ymin-5;
895 }
896 else
897 document.getElementById("waveformmin").removeAttribute("disabled");
898
899 if (document.getElementById("waveformmaxon").checked)
900 {
901 document.getElementById("waveformmax").setAttribute("disabled", "true");
902 document.getElementById("waveformmax").value = wf.ymax;
903 ymax = wf.ymax+5;
904 }
905 else
906 document.getElementById("waveformmax").removeAttribute("disabled");
907
908 setZoom(xmin, xmax, ymin, ymax);
909}
910
911//document.addEventListener("click", getClickPosition, false);
912
913$(document).ready(onReady);
914
915// ================================== Pixel mapping =================================================
916
917var map = new Array(1440);
918
919function initPixelMap()
920{
921 var 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:";
922 // first: decode the pixel mapping!
923 var sum = 1036080;
924 for (var i=0; i<1440; i++)
925 {
926 var d0 = codedMap.charCodeAt(i*2) -48;
927 var d1 = codedMap.charCodeAt(i*2+1)-48;
928
929 map[i] = d0 | (d1<<6);
930 sum -= map[i];
931 }
932 if (sum!=0)
933 alert("Pixel mapping table corrupted!");
934}
935
936initPixelMap();
937
938// ================================== Camera Display ================================================
939
940var coord = new Array(1440);
941function initCameraCoordinates()
942{
943 coord[0] = [0, 0];
944 var cnt = 1;
945 for (var ring=1; ring<24; ring++)
946 {
947 for (var s=0; s<6; s++)
948 {
949 for (var i=1; i<=ring; i++)
950 {
951 var pos = new Position(s, ring, i);
952 if (pos.d() - pos.x > 395.75)
953 continue;
954
955 coord[cnt++] = [ pos.x, pos.y];
956 }
957 }
958 }
959
960 coord[1438] = [7, -22];
961 coord[1439] = [7, 22];
962}
963
964initCameraCoordinates();
965
966function hueToRGB(hue)
967{
968 hue /= 3;
969 hue %= 6;
970
971 if (hue<1) return parseInt(255*hue, 10);
972 if (hue<3) return parseInt(255, 10);
973 if (hue<4) return parseInt(255*(4-hue), 10);
974
975 return 0.
976}
977
978function hueToHex(flt)
979{
980 var s = hueToRGB(flt).toString(16);
981 return s.length==2 ? s : "0"+s;
982}
983
984function HLStoRGB(hue)
985{
986 if (isNaN(hue))
987 return "fff";
988
989 if (hue<0)
990 return "eef"; // 555
991
992 if (hue>1)
993 return "700"; // 666
994
995 hue *= 14;
996
997 var sr = hueToHex(20-hue);
998 var sg = hueToHex(14-hue);
999 var sb = hueToHex(26-hue);
1000
1001 return sr+sg+sb;
1002}
1003
1004function outlineHex(ctx)
1005{
1006 ctx.scale(1/2, 1/3);
1007
1008 ctx.beginPath();
1009 ctx.moveTo( 1, 1);
1010 ctx.lineTo( 0, 2);
1011 ctx.lineTo(-1, 1);
1012 ctx.lineTo(-1, -1);
1013 ctx.lineTo( 0, -2);
1014 ctx.lineTo( 1, -1);
1015 ctx.lineTo( 1, 1);
1016}
1017
1018function drawHex(ctx, x, y, col, min, max)
1019{
1020 if (col===undefined || col===null)
1021 return;
1022
1023 var lvl = (col-min)/(max-min);
1024
1025 ctx.fillStyle = "#"+HLStoRGB(lvl);
1026
1027 ctx.save();
1028 ctx.translate(x, y);
1029 outlineHex(ctx);
1030 ctx.fill();
1031 ctx.restore();
1032}
1033
1034function Position(s, ring, i)
1035{
1036 switch (s)
1037 {
1038 case 1: this.x = ring - i*0.5; this.y = + i; break;
1039 case 2: this.x = ring*0.5 - i; this.y = ring ; break;
1040 case 3: this.x = -ring*0.5 - i*0.5; this.y = ring - i; break;
1041 case 4: this.x = -ring + i*0.5; this.y = - i; break;
1042 case 5: this.x = -ring*0.5 + i; this.y = -ring ; break;
1043 case 0: this.x = ring*0.5 + i*0.5; this.y = -ring + i; break;
1044 }
1045 this.d = (function () { return this.x*this.x + this.y*this.y*3/4; });
1046}
1047
1048var positions = [ ];
1049
1050
1051function drawFullCam(id)
1052{
1053 var canv = document.getElementById(id);
1054 if (!canv)
1055 return;
1056
1057 var ctx = canv.getContext("2d");
1058
1059 ctx.clearRect(0, 0, canv.width, canv.height);
1060
1061 // ======================= Draw Graphics ======================
1062
1063 var data = canv.dataRel;
1064 if (!data)
1065 return;
1066
1067 var pixel = document.getElementById('pixel').value;
1068
1069 var min = (canv.zmin-canv.min)/canv.max;
1070 var max = (canv.zmax-canv.min)/canv.max;
1071
1072 var scale = 83;
1073
1074 var w = Math.min(canv.width/scale, canv.height/scale);
1075
1076 ctx.save();
1077 ctx.translate(canv.width/2, canv.height/2);
1078 ctx.scale(w*2, w*2);
1079 // ctx.rotate(Math.PI/3);
1080
1081 ctx.scale(1, Math.sqrt(3)/2);
1082 ctx.translate(-0.5, 0);
1083
1084 for (var i=0; i<1440; i++)
1085 drawHex(ctx, coord[i][0], coord[i][1], data[map[i]], min, max);
1086
1087 if (document.getElementById('marker').checked)
1088 {
1089 // Draw marker
1090 ctx.save();
1091
1092 ctx.lineWidth = 0.25;
1093 ctx.fillStyle = "#000";
1094
1095 ctx.translate(coord[pixel][0], coord[pixel][1]);
1096 outlineHex(ctx);
1097 ctx.stroke();
1098
1099 ctx.restore();
1100 }
1101
1102 ctx.restore();
1103
1104 // ======================= Draw Legend ======================
1105
1106 var pval = canv.dataAbs[pixel].toFixed(1);
1107 var lmin = parseFloat(canv.min).toFixed(1);
1108 var lmax = parseFloat(canv.max).toFixed(1);
1109
1110 var v0 = parseFloat(canv.zmin);
1111 var v1 = parseFloat(canv.zmax);
1112
1113 var diff = v1-v0;
1114
1115 var cw = canv.width;
1116 //var ch = canv.height;
1117
1118 ctx.font = "8pt Arial";
1119 ctx.textAlign = "right";
1120 ctx.textBaseline = "top";
1121
1122 for (var i=0; i<11; i++)
1123 {
1124 ctx.strokeStyle = "#"+HLStoRGB(i/10);
1125 ctx.strokeText((v0+diff*i/10).toPrecision(3), cw-5, 125-i*12);
1126 }
1127
1128 var mw = Math.max(ctx.measureText(lmin).width,
1129 ctx.measureText(pval).width,
1130 ctx.measureText(lmax).width);
1131
1132 ctx.textBaseline = "top";
1133 ctx.strokeStyle = "#000";
1134
1135 ctx.strokeText(lmax, 5+mw, 5+24);
1136 ctx.strokeText(pval, 5+mw, 5+12);
1137 ctx.strokeText(lmin, 5+mw, 5);
1138}
1139
Note: See TracBrowser for help on using the repository browser.