##// END OF EJS Templates
Interval calculated internally, no more needed in metadata
Juan C. Espinoza -
r32:0d03afbbef2d
parent child
Show More
@@ -1,637 +1,647
1 1
2 2 var icon = {
3 3 'width': 20,
4 4 'path': 'M18.303,4.742l-1.454-1.455c-0.171-0.171-0.475-0.171-0.646,0l-3.061,3.064H2.019c-0.251,0-0.457,0.205-0.457,0.456v9.578c0,0.251,0.206,0.456,0.457,0.456h13.683c0.252,0,0.457-0.205,0.457-0.456V7.533l2.144-2.146C18.481,5.208,18.483,4.917,18.303,4.742 M15.258,15.929H2.476V7.263h9.754L9.695,9.792c-0.057,0.057-0.101,0.13-0.119,0.212L9.18,11.36h-3.98c-0.251,0-0.457,0.205-0.457,0.456c0,0.253,0.205,0.456,0.457,0.456h4.336c0.023,0,0.899,0.02,1.498-0.127c0.312-0.077,0.55-0.137,0.55-0.137c0.08-0.018,0.155-0.059,0.212-0.118l3.463-3.443V15.929z M11.241,11.156l-1.078,0.267l0.267-1.076l6.097-6.091l0.808,0.808L11.241,11.156z',
5 5 'ascent': 20,
6 6 'descent': 2,
7 7 };
8 8
9 9 function list2dict(values) {
10 10
11 11 var o = {};
12 12 $.each(values, function () {
13 13 o[this.name] = this.value;
14 14 });
15 15 return o;
16 16 };
17 17 /* In this class is defined all the function to RTI plot */
18 18 class PcolorBuffer {
19 19 constructor({ div, data }) {
20 20 this.div = document.getElementById(div);
21 21 this.n = 0;
22 22 this.divs = [];
23 23 this.wait = false;
24 24 this.lastRan = Date.now();
25 25 this.lastFunc = null;
26 26 this.zbuffer = [];
27 27 this.xbuffer = [];
28 28 this.empty = Array(data.metadata.yrange.length).fill(null);
29 29 this.timespan = 12;
30 30 this.metadata = data.metadata;
31 31 this.setup(data);
32 32 }
33 33 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
34 34 setup(data) {
35 35 this.last = data.time.slice(-1);
36 var diffArr = [];
37 for(var i=0; i<data.time.length-1; i++){
38 diffArr.push(data.time[i+1]-data.time[i]);
39 }
40 this.interval = Math.round(Math.min.apply(null, diffArr)*100 / 100);
36 41 if (data.time.length == 1) {
37 42 var values = { 'time': data.time, 'data': data['data'].map(function (x) { return [x] }) };
38 43 } else {
39 var values = this.fill_gaps(data.time, data['data'], data.metadata.interval, data['data'].length);
44 var values = this.fill_gaps(data.time, data['data'], this.interval, data['data'].length);
40 45 }
41 46 var t = values.time.map(function (x) {
42 47 var a = new Date(x * 1000);
43 48 // This condition is used to change from UTC to LT
44 49 if (data.metadata.localtime == true){
45 50 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
46 51 }
47 52 return a;
48 53 });
49 54
50 55 var label;
51 56 if (data.metadata.localtime == true){
52 57 label = "[LT]";
53 58
54 59 }
55 60 else{
56 61 label = "[UTC]";
57 62 }
58 63
59 64 for (var i = 0; i < data['data'].length; i++) {
60 65 var layout = {
61 66 height: 350,
62 67 xaxis: {
63 68 title: 'Time ' + label,
64 69 showgrid: false,
65 70 linewidth: 2,
66 71 size: 12,
67 72 mirror: true,
68 73 },
69 74 yaxis: {
70 75 title: data.metadata.ylabel || 'km',
71 76 showgrid: false,
72 77 linewidth: 2,
73 78 size: 12,
74 79 mirror: true,
75 80 },
76 81 titlefont: {
77 82 size: 16,
78 83 },
79 84 margin: {
80 85 t: 30,
81 86 }
82 87 };
83 88 var iDiv = document.createElement('div');
84 89 iDiv.id = 'plot-' + i;
85 90 //iDiv.className += iDiv.className ? ' col-lg-6 col-md-6 col-sm-12' : 'col-lg-6 col-md-12 col-sm-12';
86 91 this.zbuffer.push([]);
87 92 this.n = this.n + 1;
88 93 this.div.appendChild(iDiv);
89 94 this.divs.push(iDiv.id);
90 95 var trace = {
91 96 z: values.data[i],
92 97 x: t,
93 98 y: data.metadata.yrange,
94 99 colorscale: this.metadata.colormap || 'Jet',
95 100 transpose: true,
96 101 type: 'heatmap'
97 102 };
98 103
99 104 if (this.metadata.zmin) { trace.zmin = this.metadata.zmin }
100 105 if (this.metadata.zmax) { trace.zmax = this.metadata.zmax }
101 106
102 107 layout.title = 'Ch ' + i + ' - ' + t.slice(-1).toLocaleString();
103 108 var conf = {
104 109 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
105 110 modeBarButtonsToAdd: [{
106 111 name: 'Edit plot',
107 112 icon: icon,
108 113 click: function (gd) {
109 114 var div = gd.id;
110 115 $('input[id=id_plotdiv]').val(div);
111 116 $('#setup').modal('show');
112 117 }
113 118 }],
114 119 displaylogo: false,
115 120 showTips: true
116 121 };
117 122 Plotly.newPlot('plot-' + i, [trace], layout, conf);
118 123 }
119 124 }
120 125
121 126 getSize() {
122 127 var div = document.getElementById(this.divs[0]);
123 128 var t = this.xbuffer.slice(-1)[0];
124 129 var n = 0;
125 130 var timespan = this.timespan * 1000 * 60 * 60;
126 131
127 132 while ((t - div.data[0].x[n]) > timespan) {
128 133 n += 1;
129 134 }
130 135 return n;
131 136 }
132 137
133 138 fill_gaps(xBuffer, zBuffer, interval, N) {
134 139
135 140 var x = [xBuffer[0]];
136 141 var z = [];
137 142 var last;
138 143
139 144 for (var j = 0; j < N; j++) {
140 145 z.push([zBuffer[j][0]]);
141 146 }
142 147
143 148 for (var i = 1; i < xBuffer.length; i++) {
144 149 var cnt = 0;
145 150 last = x[x.length-1];
146 151 while (Math.abs(parseFloat(xBuffer[i]) - last ) > 1.5 * parseFloat(interval)) {
147 152 cnt += 1;
148 153 last = last + interval;
149 154 x.push(last);
150 155 for (var j = 0; j < N; j++) {
151 156 z[j].push(this.empty);
152 157 }
153 158 // Avoid infinite loop
154 159 if (cnt == 100) { break; }
155 160 }
156 161 x.push(xBuffer[i]);
157 162 for (var j = 0; j < N; j++) {
158 163 z[j].push(zBuffer[j][i]);
159 164 }
160 165 }
161 166 return { 'time': x, 'data': z };
162 167 }
163 168
164 169 plot() {
165 170 // add new data to plots and empty buffers
166 171 var N = this.getSize();
167 172 console.log('Plotting...');
168 173 for (var i = 0; i < this.n; i++) {
169 174 var div = document.getElementById(this.divs[i]);
170 175 if (N > 0) {
171 176 div.data[0].z = div.data[0].z.slice(N, )
172 177 div.data[0].x = div.data[0].x.slice(N, )
173 178 }
174 179 Plotly.extendTraces(div, {
175 180 z: [this.zbuffer[i]],
176 181 x: [this.xbuffer]
177 182 }, [0]);
178 183 this.zbuffer[i] = [];
179 184 }
180 185 this.xbuffer = [];
181 186 }
182 187 //This function just add the last data and is used if previously was used setup()
183 188 update(obj) {
184 189
185 190 // fill data gaps
186 191 var cnt = 0;
187 192
188 while (Math.abs(parseFloat(obj.time[0]) - this.last) > 1.5 * parseFloat(obj.metadata.interval)) {
193 while (Math.abs(parseFloat(obj.time[0]) - this.last) > 1.5 * parseFloat(this.interval)) {
189 194 cnt += 1;
190 this.last += obj.metadata.interval;
195 this.last += this.interval;
191 196 var newt = new Date((this.last) * 1000);
192 197 // This condition is used to change from UTC to LT
193 198 if (obj.metadata.localtime == true){
194 199 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
195 200 }
196 201 this.xbuffer.push(newt);
197 202 for (var i = 0; i < obj['data'].length; i++) {
198 203 this.zbuffer[i].push(this.empty);
199 204 }
200 205 // Avoid infinite loop
201 206 if (cnt == 100) { break; }
202 207 }
203 208
204 209 // update buffers
205 210 this.last = parseFloat(obj.time[0]);
206 211 var t = new Date(obj.time[0] * 1000);
207 212 // This condition is used to change from UTC to LT
208 213 if (obj.metadata.localtime == true){
209 214 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
210 215 }
211 216 this.xbuffer.push(t);
212 217 for (var i = 0; i < obj['data'].length; i++) {
213 218 this.zbuffer[i].push(obj['data'][i]);
214 219 var div = document.getElementById(this.divs[i]);
215 220 Plotly.relayout(div, {
216 221 title: 'Ch ' + i + ' - ' + t.toLocaleString(),
217 222 });
218 223 }
219 224
220 225 if (!this.wait) {
221 226 this.plot();
222 227 this.wait = true;
223 228 } else {
224 229 clearTimeout(this.lastFunc)
225 230 this.lastFunc = setTimeout(function (scope) {
226 231 if ((Date.now() - scope.lastRan) >= 30000) {
227 232 scope.plot()
228 233 scope.lastRan = Date.now()
229 234 }
230 235 }, 30000 - (Date.now() - this.lastRan), this)
231 236 }
232 237 }
233 238 // With this function You can change parameters in your plot
234 239 restyle(values) {
235 240
236 241 var values = list2dict(values);
237 242 var div = document.getElementById(values.plotdiv);
238 243
239 244 Plotly.relayout(div, {
240 245 yaxis: {
241 246 range: [values.ymin, values.ymax],
242 247 title: this.metadata.ylabel || 'km',
243 248 linewidth: 2,
244 249 size: 12,
245 250 mirror: true,
246 251 }
247 252
248 253 });
249 254
250 255 Plotly.restyle(div, {
251 256 zmin: values.zmin,
252 257 zmax: values.zmax,
253 258 colorscale: values.colormap
254 259 });
255 260 }
256 261 }
257 262 /* In this class is defined all the function to SPC plot */
258 263 class Pcolor {
259 264 constructor({ div, data }) {
260 265 this.div = document.getElementById(div);
261 266 this.n = 0;
262 267 this.divs = [];
263 268 this.metadata = data.metadata;
264 269 this.setup(data);
265 270 }
266 271 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
267 272 setup(data) {
268 273 for (var i = 0; i < data['data'].length; i++) {
269 274 var layout = {
270 275 margin: {
271 276 t:30,
272 277 },
273 278 height: 320,
274 279 xaxis: {
275 280 title: data.metadata.xlabel || 'Velocity',
276 281 showgrid: false,
277 282 zeroline: false,
278 283 linewidth: 2,
279 284 mirror: true,
280 285 size: 12,
281 286 },
282 287 yaxis: {
283 288 title: data.metadata.ylabel || 'km',
284 289 showgrid: false,
285 290 linewidth: 2,
286 291 mirror: 'all',
287 292 size: 12,
288 293 },
289 294 titlefont: {
290 295 size: 14
291 296 },
292 297 };
293 298 var iDiv = document.createElement('div');
294 299 iDiv.id = 'plot-' + i;
295 300 iDiv.className += iDiv.className ? ' col-md-5' : 'col-md-5';
296 301 this.n = this.n + 1;
297 302 this.div.appendChild(iDiv);
298 303 this.divs.push(iDiv.id);
299 304 var iDiv = document.createElement('div');
300 305 iDiv.className = 'col-md-1';
301 306 this.div.appendChild(iDiv);
302 307 var trace1 = {
303 308 z: data['data'][i],
304 309 y: data.metadata.yrange,
305 310 x: data.metadata.xrange,
306 311 colorscale: this.metadata.colormap || 'Jet',
307 312 transpose: true,
308 313 type: 'heatmap'
309 314 };
310 315
311 316 if (this.metadata.zmin) {
312 317 trace1.zmin = this.metadata.zmin
313 318 }
314 319 if (this.metadata.zmax) {
315 320 trace1.zmax = this.metadata.zmax;
316 321 }
317 322
318 323 var t = new Date(data.time * 1000);
319 324 if (data.metadata.localtime == true){
320 325 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
321 326 }
322 327 if ('titles' in data.metadata){
323 328 layout.title = data.metadata.titles[i] + ' ' + t.toLocaleString();
324 329 }else{
325 330 layout.title = 'Ch ' + i + ': ' + t.toLocaleString();
326 331 }
327 332 var conf = {
328 333 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
329 334 modeBarButtonsToAdd: [{
330 335 name: 'Edit plot',
331 336 icon: icon,
332 337 click: function (gd) {
333 338 var div = gd.id;
334 339 $('input[id=id_plotdiv]').val(div);
335 340 $('#setup').modal('show');
336 341 }
337 342 }],
338 343 displaylogo: false,
339 344 showTips: true
340 345 };
341 346
342 347 var traces = [trace1]
343 348
344 349 Plotly.newPlot('plot-' + i, traces, layout, conf);
345 350 }
346 351 }
347 352
348 353 plot(obj) {
349 354 this.data = obj;
350 355 // add new data to plots and empty buffers
351 356 console.log('Plotting...');
352 357 var t = new Date(obj.time[0] * 1000);
353 358 // This condition is used to change from UTC to LT
354 359 if (obj.metadata.localtime == true){
355 360 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
356 361 }
357 362 for (var i = 0; i < this.n; i++) {
358 363 var div = document.getElementById(this.divs[i]);
359 364
360 365 if ('titles' in obj.metadata){
361 366 var title = obj.metadata.titles[i] + ' ' + t.toLocaleString();
362 367 }else{
363 368 var title = 'Ch ' + i + ': ' + t.toLocaleString();
364 369 }
365 370
366 371 Plotly.relayout(div, {
367 372 title: title,
368 373 });
369 374
370 375 Plotly.restyle(div, {
371 376 z: [obj['data'][i]],
372 377 x: [obj.xrange]
373 378 }, [0]);
374 379 }
375 380 }
376 381
377 382 update(data) {
378 383 this.plot(data);
379 384 }
380 385
381 386 restyle(values) {
382 387
383 388 var values = list2dict(values);
384 389 var div = document.getElementById(values.plotdiv);
385 390
386 391 Plotly.relayout(div, {
387 392 yaxis: {
388 393 title: this.metadata.ylabel || 'km',
389 394 linewidth: 2,
390 395 range: [values.ymin, values.ymax]
391 396 },
392 397 xaxis: {
393 398 title: this.metadata.xlabel || 'Velocity',
394 399 linewidth: 2,
395 400 mirror: true,
396 401 range: [values.xmin, values.xmax]
397 402 }
398 403 });
399 404
400 405 Plotly.restyle(div, {
401 406 zmin: values.zmin,
402 407 zmax: values.zmax,
403 408 colorscale: values.colormap
404 409 });
405 410 }
406 411 }
407 412
408 413 class ScatterBuffer {
409 414 constructor({ div, data }) {
410 415 this.div = document.getElementById(div);
411 416 this.n = 0;
412 417 this.wait = false;
413 418 this.lastRan = Date.now();
414 419 this.lastFunc = null;
415 420 this.ybuffer = [];
416 421 this.xbuffer = [];
417 422 this.timespan = 12;
418 423 this.metadata = data.metadata;
419 424 this.setup(data);
420 425 }
421 426 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
422 427 setup(data) {
423 428
424 //this.data = data;
425 429 var traces = [];
426 430 this.last = data.time.slice(-1);
431 var diffArr = [];
432 for(var i=0; i<data.time.length-1; i++){
433 diffArr.push(data.time[i+1]-data.time[i]);
434 }
435 this.interval = Math.round(Math.min.apply(null, diffArr)*100 / 100);
436
427 437 if (data.time.length == 1) {
428 438 var values = { 'time': data.time, 'data': data['data'] };
429 439 } else {
430 var values = this.fill_gaps(data.time, data['data'], data.metadata.interval, data['data'].length);
440 var values = this.fill_gaps(data.time, data['data'], this.interval, data['data'].length);
431 441 }
432 442
433 443 var t = values.time.map(function (x) {
434 444 var a = new Date(x * 1000);
435 445 // This condition is used to change from UTC to LT
436 446 if (data.metadata.localtime == true){
437 447 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
438 448 }
439 449 return a;
440 450 });
441 451
442 452 for (var i = 0; i < data['data'].length; i++) {
443 453
444 454 this.n = this.n + 1;
445 455 this.ybuffer.push([]);
446 456 var trace = {
447 457 x: t,
448 458 y: values.data[i],
449 459 mode: 'lines',
450 460 type: 'scatter',
451 461 name: 'Channel ' + i,
452 462 connectgaps: false,
453 463 };
454 464
455 465 traces.push(trace);
456 466 }
457 467
458 468 var label;
459 469 if (data.metadata.localtime == true){
460 470 label = "[LT]";
461 471
462 472 }
463 473 else{
464 474 label = "[UTC]";
465 475 }
466 476
467 477 var layout = {
468 478 height: 300,
469 479 title: t.slice(-1).toLocaleString(),
470 480 font: {
471 481 size: 12,
472 482 },
473 483 xaxis: {
474 484 title: 'Time ' + label,
475 485 size: 12,
476 486 linewidth: 2,
477 487 mirror: true,
478 488 },
479 489 yaxis: {
480 490 title: data.metadata.ylabel || 'dB',
481 491 linewidth: 2,
482 492 mirror: true,
483 493 },
484 494 titlefont: {
485 495 size: 16,
486 496 },
487 497 margin: {
488 498 t: 30,
489 499 }
490 500 };
491 501
492 502 if (data.metadata.ymin) { layout.yaxis.range = [data.metadata.ymin, data.metadata.ymax] }
493 503
494 504 var conf = {
495 505 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
496 506 modeBarButtonsToAdd: [{
497 507 name: 'Edit plot',
498 508 icon: icon,
499 509 click: function (gd) {
500 510 $('#setup').modal('show');
501 511 }
502 512 }],
503 513 displaylogo: false,
504 514 showTips: true
505 515 };
506 516 Plotly.newPlot('plot', traces, layout, conf);
507 517 }
508 518
509 519 getSize() {
510 520 var t = this.xbuffer.slice(-1)[0];
511 521 var n = 0;
512 522 var timespan = this.timespan * 1000 * 60 * 60;
513 523
514 524 while ((t - this.div.data[0].x[n]) > timespan) {
515 525 n += 1;
516 526 }
517 527 return n;
518 528 }
519 529
520 530 fill_gaps(xBuffer, yBuffer, interval, N) {
521 531
522 532 var x = [xBuffer[0]];
523 533 var y = [];
524 534
525 535 for (var j = 0; j < N; j++) {
526 536 y.push([yBuffer[j][0]]);
527 537 }
528 538
529 539 var last;
530 540
531 541 for (var i = 1; i < xBuffer.length; i++) {
532 542 var cnt = 0;
533 543 last = x.slice(-1)[0];
534 544 while (Math.abs(parseFloat(xBuffer[i]) - last) > 1.5 * parseFloat(interval)) {
535 545 cnt += 1;
536 546 last = last + interval;
537 547 x.push(last);
538 548 for (var j = 0; j < N; j++) {
539 549 y[j].push(null);
540 550 }
541 551 // Avoid infinite loop
542 552 if (cnt == 50) { break; }
543 553 }
544 554 x.push(xBuffer[i]);
545 555
546 556 for (var j = 0; j < N; j++) {
547 557 y[j].push(yBuffer[j][i]);
548 558 }
549 559 }
550 560 return { 'time': x, 'data': y };
551 561 }
552 562
553 563 plot() {
554 564 // add new data to plots and empty buffers
555 565 var xvalues = [];
556 566 var yvalues = [];
557 567 var traces = [];
558 568 var N = this.getSize();
559 569 console.log('Plotting...');
560 570 for (var i = 0; i < this.n; i++) {
561 571 if (N > 0) {
562 572 this.div.data[i].y = this.div.data[i].y.slice(N, )
563 573 this.div.data[i].x = this.div.data[i].x.slice(N, )
564 574 }
565 575 yvalues.push(this.ybuffer[i]);
566 576 xvalues.push(this.xbuffer);
567 577 traces.push(i);
568 578 this.ybuffer[i] = [];
569 579 }
570 580 Plotly.extendTraces(this.div, {
571 581 y: yvalues,
572 582 x: xvalues
573 583 }, traces);
574 584 this.xbuffer = [];
575 585 }
576 586 //This function just add the last data and is used if previously was used setup()
577 587 update(obj) {
578 588 // fill data gaps
579 589 var cnt = 0;
580 while (Math.abs(parseFloat(obj.time[0]) - this.last ) > 1.5 * parseFloat(obj.metadata.interval)) {
590 while (Math.abs(parseFloat(obj.time[0]) - this.last ) > 1.5 * parseFloat(this.interval)) {
581 591 cnt += 1;
582 this.last += obj.metadata.interval;
592 this.last += this.interval;
583 593 var newt = new Date((this.last) * 1000);
584 594 // This condition is used to change from UTC to LT
585 595 if (obj.metadata.localtime == true){
586 596 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
587 597 }
588 598 this.xbuffer.push(newt);
589 599 for (var i = 0; i < this.n; i++) {
590 600 this.ybuffer[i].push(null);
591 601 }
592 602 // Avoid infinite loop
593 603 if (cnt == 100) { break; }
594 604 }
595 605
596 606 // update buffers
597 607 this.last = parseFloat(obj.time[0]);
598 608 var t = new Date(obj.time[0] * 1000);
599 609 // This condition is used to change from UTC to LT
600 610 if (obj.metadata.localtime == true){
601 611 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
602 612 }
603 613 this.xbuffer.push(t);
604 614 for (var i = 0; i < this.n; i++) {
605 615 this.ybuffer[i].push(obj['data'][i][0]);
606 616 }
607 617
608 618 Plotly.relayout(this.div, {
609 619 title: t.toLocaleString(),
610 620 });
611 621
612 622 if (!this.wait) {
613 623 this.plot();
614 624 this.wait = true;
615 625 } else {
616 626 clearTimeout(this.lastFunc)
617 627 this.lastFunc = setTimeout(function (scope) {
618 628 if ((Date.now() - scope.lastRan) >= 30000) {
619 629 scope.plot()
620 630 scope.lastRan = Date.now()
621 631 }
622 632 }, 30000 - (Date.now() - this.lastRan), this)
623 633 }
624 634 }
625 635
626 636 restyle(values) {
627 637
628 638 var values = list2dict(values);
629 639 Plotly.relayout(this.div, {
630 640 yaxis: {
631 641 range: [values.ymin, values.ymax],
632 642 title: this.metadata.ylabel || 'dB'
633 643 }
634 644
635 645 });
636 646 }
637 647 }
General Comments 0
You need to be logged in to leave comments. Login now