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