Обработка неопределенных значений в веб-интерфейсе.
[weathermon.git] / openwrt-web / meteo / 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 cfg = {
106       type: 'bar',
107       data: {
108         datasets: [
109           {
110             label: properties["names"][devid+"."+sensor+"."+param],
111             backgroundColor: color(properties["colors"][devid+"."+sensor+"."+param]).alpha(0.5).rgbString(),
112             borderColor: properties["colors"][devid+"."+sensor+"."+param],
113             data: processDataset(graphData,devid,sensor,param),
114             type: 'line',
115             pointRadius: 0,
116             fill: true,
117             borderWidth: 2
118           }
119         ]      
120       },
121       options: {
122         animation: {
123           duration: 0,
124         },
125         hover: {
126           animationDuration: 0,
127         },
128         responsiveAnimationDuration: 0,
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: properties["names"][devid+"."+sensor+"."+param] + ", " + properties["units"][devid+"."+sensor+"."+param],
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.send();
178
179 }
180
181 function GetProperties() {
182   var req = new XMLHttpRequest();
183
184   req.onreadystatechange = function () {
185     if (this.readyState != 4) return; 
186     if (this.status != 200) {
187       setTimeout(GetProperties,30000);
188       return;
189     }
190     properties = JSON.parse(this.responseText);
191     GetYears();
192   };
193   
194   req.open("GET", urlbase+"props", true);
195   req.send();
196
197 }
198
199 function fillSelector(id,data,value,nameFunc) {
200
201   var element = document.getElementById(id);
202   var html = "";
203   var line;
204   
205   for (i in data) {
206     if (nameFunc) {
207       line = "<option value=\""+data[i]+"\">"+nameFunc(data[i])+"</option>"
208     } else {
209       line = "<option value=\""+data[i]+"\">"+data[i]+"</option>"
210     }
211     html = html + line;
212   } 
213   
214   element.innerHTML = html;
215   if (value) {
216     element.value = value;
217   }
218   return element.value;
219
220 }
221
222 function GetYears() {
223   var req = new XMLHttpRequest();
224
225   req.onreadystatechange = function () {
226     if (this.readyState != 4) return; 
227     if (this.status != 200) {
228       setTimeout(GetYears,30000);
229       return;
230     }
231     years = JSON.parse(this.responseText);
232     year = fillSelector("year", years, year);
233     composeUrl();
234     if (year) {
235       GetMonths();
236     }
237   };
238   
239   req.open("GET", urlbase+"years", true);
240   req.send();
241   
242 }
243
244 function GetMonths() {
245   var req = new XMLHttpRequest();
246
247   req.onreadystatechange = function () {
248     if (this.readyState != 4) return; 
249     if (this.status != 200) {
250       setTimeout(GetMonths,30000);
251       return;
252     }
253     months = JSON.parse(this.responseText);
254     month = fillSelector("month", months, month);
255     composeUrl();
256     if (month) {
257       GetDays();
258     }
259   };
260   
261   req.open("GET", urlbase+"months/"+year, true);
262   req.send();
263   
264 }
265
266 function GetDays() {
267   var req = new XMLHttpRequest();
268
269   req.onreadystatechange = function () {
270     if (this.readyState != 4) return; 
271     if (this.status != 200) {
272       setTimeout(GetDays,30000);
273       return;
274     }
275     days = JSON.parse(this.responseText);
276     day = fillSelector("day", days, day);
277     composeUrl();
278     if (day) {
279       GetSensors();
280     }  
281   };
282   
283   req.open("GET", urlbase+"days/"+year+"/"+month, true);
284   req.send();
285   
286 }
287
288 function SensorName(id) {
289   return properties["names"][id];
290 }
291
292 function GetSensors() {
293   var req = new XMLHttpRequest();
294
295   req.onreadystatechange = function () {
296     if (this.readyState != 4) return; 
297     if (this.status != 200) {
298       setTimeout(GetSensors,30000);
299       return;
300     }
301     sensors = JSON.parse(this.responseText);
302     if (devid && sensor && param) {
303       sensor_id = devid+"."+sensor+"."+param;
304     } else {
305       sensor_id = null;
306     }  
307     sensor_id = fillSelector("sensor", sensors, sensor_id, SensorName).split(".");
308     devid = sensor_id[0];
309     sensor = sensor_id[1];
310     param = sensor_id[2];
311     composeUrl();
312     if (sensor_id) {
313       RefreshGraph();
314     }
315   };
316   
317   req.open("GET", urlbase+"sensors/"+year+"/"+month+"/"+day, true);
318   req.send();
319   
320 }
321
322 setTimeout(GetProperties,100);