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

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