Транзакционная работа с БД для избежания блокировок.
[weathermon.git] / web / archive.js
1 urlbase="/meteo/cgi/";
2
3 archive_base="/meteo/archive";
4 current_base = "/meteo/graph";
5
6 var url = window.location.pathname;
7
8 if (url.startsWith(archive_base)) {
9   url = url.substr(archive_base.length);
10 }
11
12 var params = url.split('/');
13
14 var year = params[1];
15 var month = params[2];
16 var day = params[3];
17 var devid = params[4];
18 var sensor = params[5];
19 var param = params[6];
20
21 var properties;
22 var years;
23 var months;
24 var days;
25 var sensors;
26
27 function composeUrl() {
28   url = window.location.protocol+"//"+window.location.host+archive_base+"/";
29   if (year) {
30     url = url + year;
31     if (month) {
32       url = url + "/" + month;
33       if (day) {
34         url = url + "/" + day;
35         if (devid) {
36           url = url + "/" + devid;
37           if (sensor) {
38             url = url + "/" + sensor;
39             if (param) {
40               url = url + "/" + param;
41             }
42           }
43         }
44       }
45     }
46   }
47   history.pushState({}, null, url);
48 }
49
50 function selectChange() {
51   new_year = document.getElementById("year").value;
52   new_month = document.getElementById("month").value;
53   new_day = document.getElementById("day").value;
54   sensor_id = document.getElementById("sensor").value.split(".");
55   new_devid = sensor_id[0];
56   new_sensor = sensor_id[1];
57   new_param = sensor_id[2];
58   if (year != new_year) {
59     year = new_year;
60     GetMonths();
61   } else if (month != new_month) {
62     month = new_month;
63     GetDays();
64   } else if (day != new_day) {
65     day = new_day;
66     GetSensors();
67   } else if ((new_devid != devid) || (new_sensor != sensor) || (new_param != param)) {
68     devid = new_devid;
69     sensor = new_sensor;
70     param = new_param;
71     RefreshGraph();
72   }
73   composeUrl();
74 }
75
76 function processDataset(dataset,devid,sensorname,paramname) {
77   var scale = properties["scale"][devid+"."+sensorname+"."+paramname]
78   if (scale) {
79     var result=[];
80     for (idx in dataset) {
81       newRec = {};
82       newRec.t = dataset[idx].t
83       newRec.y = dataset[idx].y * scale[0];
84       result.push(newRec);
85     }  
86     return result;
87   } else { 
88     return dataset;
89   }
90 }
91
92 function drawGraph(graphData) {
93
94   document.getElementById("current").href = current_base+"/"+devid + "/" + sensor + "/" + param;
95
96   var div = document.getElementById("chartdiv");
97   var canvas = document.getElementById("chart");
98   
99   canvas.width = div.style.width;
100   canvas.height = div.style.height;
101
102   var ctx = canvas.getContext('2d');
103   var color = Chart.helpers.color;
104
105   var sensor_path = devid+"."+sensor+"."+param;
106
107   var y_label = properties["names"][sensor_path];
108   if (properties["units"][sensor_path]) {
109     y_label = y_label + ", " + properties["units"][sensor_path];
110   }
111
112   var cfg = {
113       type: 'bar',
114       data: {
115         datasets: [
116           {
117             label: properties["places"][sensor_path] + ' - ' + properties["names"][sensor_path],
118             backgroundColor: color(properties["colors"][sensor_path]).alpha(0.5).rgbString(),
119             borderColor: properties["colors"][sensor_path],
120             data: processDataset(graphData,devid,sensor,param),
121             type: 'line',
122             pointRadius: 0,
123             fill: true,
124             borderWidth: 2
125           }
126         ]      
127       },
128       options: {
129         legend: {
130           labels: {
131             fontColor: properties["fonts"]["legend"]["color"],
132             fontSize: properties["fonts"]["legend"]["size"],
133             fontStyle: properties["fonts"]["legend"]["style"],
134           }
135         },
136         scales: {
137           xAxes: [{
138             type: 'time',
139             distribution: 'series',
140             scaleLabel: {
141               fontColor: properties["fonts"]["axes"]["color"],
142               fontSize: properties["fonts"]["axes"]["size"],
143               fontStyle: properties["fonts"]["axes"]["style"],
144             }
145           }],
146           yAxes: [{
147             scaleLabel: {
148               display: true,
149               labelString: y_label,
150               fontColor: properties["fonts"]["axes"]["color"],
151               fontSize: properties["fonts"]["axes"]["size"],
152               fontStyle: properties["fonts"]["axes"]["style"],
153             }
154           }]
155         }  
156       }
157
158   }
159   var chart = new Chart(ctx, cfg);
160 }
161
162 function RefreshGraph() {
163
164   var req = new XMLHttpRequest();
165
166   req.onreadystatechange = function () {
167     if (this.readyState != 4) return; 
168     if (this.status != 200) {
169       setTimeout(RefreshGraph,30000);
170       return;
171     }
172     var graphData = JSON.parse(this.responseText);
173     drawGraph(graphData);
174   };
175   
176   req.open("GET", urlbase+"get-archive/"+year+"/"+month+"/"+day+"/"+devid+"/"+sensor+"/"+param, true);
177   req.withCredentials = true;
178   req.send();
179
180 }
181
182 function GetProperties() {
183   var req = new XMLHttpRequest();
184
185   req.onreadystatechange = function () {
186     if (this.readyState != 4) return; 
187     if (this.status != 200) {
188       setTimeout(GetProperties,30000);
189       return;
190     }
191     properties = JSON.parse(this.responseText);
192     GetYears();
193   };
194   
195   req.open("GET", urlbase+"props", true);
196   req.withCredentials = true;
197   req.send();
198
199 }
200
201 function fillSelector(id,data,value,nameFunc) {
202
203   var element = document.getElementById(id);
204   var html = "";
205   var line;
206   
207   for (i in data) {
208     if (nameFunc) {
209       line = "<option value=\""+data[i]+"\">"+nameFunc(data[i])+"</option>"
210     } else {
211       line = "<option value=\""+data[i]+"\">"+data[i]+"</option>"
212     }
213     html = html + line;
214   } 
215   
216   element.innerHTML = html;
217   if (value) {
218     element.value = value;
219   }
220   return element.value;
221
222 }
223
224 function GetYears() {
225   var req = new XMLHttpRequest();
226
227   req.onreadystatechange = function () {
228     if (this.readyState != 4) return; 
229     if (this.status != 200) {
230       setTimeout(GetYears,30000);
231       return;
232     }
233     years = JSON.parse(this.responseText);
234     year = fillSelector("year", years, year);
235     composeUrl();
236     if (year) {
237       GetMonths();
238     }
239   };
240   
241   req.open("GET", urlbase+"years", true);
242   req.withCredentials = true;
243   req.send();
244   
245 }
246
247 function GetMonths() {
248   var req = new XMLHttpRequest();
249
250   req.onreadystatechange = function () {
251     if (this.readyState != 4) return; 
252     if (this.status != 200) {
253       setTimeout(GetMonths,30000);
254       return;
255     }
256     months = JSON.parse(this.responseText);
257     month = fillSelector("month", months, month);
258     composeUrl();
259     if (month) {
260       GetDays();
261     }
262   };
263   
264   req.open("GET", urlbase+"months/"+year, true);
265   req.withCredentials = true;
266   req.send();
267   
268 }
269
270 function GetDays() {
271   var req = new XMLHttpRequest();
272
273   req.onreadystatechange = function () {
274     if (this.readyState != 4) return; 
275     if (this.status != 200) {
276       setTimeout(GetDays,30000);
277       return;
278     }
279     days = JSON.parse(this.responseText);
280     day = fillSelector("day", days, day);
281     composeUrl();
282     if (day) {
283       GetSensors();
284     }  
285   };
286   
287   req.open("GET", urlbase+"days/"+year+"/"+month, true);
288   req.withCredentials = true;
289   req.send();
290   
291 }
292
293 function SensorName(id) {
294   return properties["places"][id]+" - "+properties["names"][id];
295 }
296
297 function GetSensors() {
298   var req = new XMLHttpRequest();
299
300   req.onreadystatechange = function () {
301     if (this.readyState != 4) return; 
302     if (this.status != 200) {
303       setTimeout(GetSensors,30000);
304       return;
305     }
306     sensors = JSON.parse(this.responseText);
307     if (devid && sensor && param) {
308       sensor_id = devid+"."+sensor+"."+param;
309     } else {
310       sensor_id = null;
311     }  
312     sensor_id = fillSelector("sensor", sensors, sensor_id, SensorName).split(".");
313     devid = sensor_id[0];
314     sensor = sensor_id[1];
315     param = sensor_id[2];
316     composeUrl();
317     if (sensor_id) {
318       RefreshGraph();
319     }
320   };
321   
322   req.open("GET", urlbase+"sensors/"+year+"/"+month+"/"+day, true);
323   req.withCredentials = true;
324   req.send();
325   
326 }
327
328 setTimeout(GetProperties,100);