fix some crap
[matches/MCTX3420.git] / testing / MCTXWeb / public_html / static / mctx.graph.js
1 /**
2  * Graph sensor and/or actuator values
3  */
4
5 //TODO: Clean this file up, I bow to Jeremy's superior JavaScript knowledge
6
7
8 mctx.graph = {};
9 mctx.graph.api = {};
10 mctx.graph.api.sensors = mctx.api + "sensors";
11 mctx.graph.api.actuators = mctx.api + "actuators";
12 mctx.sensors = {};
13 mctx.actuators = {};
14 mctx.graph.dependent = null;
15 mctx.graph.independent = null;
16 mctx.graph.timer = null;
17 mctx.graph.running = false;
18
19 /**
20  * Helper - Calculate pairs of (dependent, independent) values
21  * Given input as (time, value) pairs for dependent and independent
22  * Appends each value pair to the result
23  * @returns result
24  */
25 function dataMerge(dependent, independent, result) {
26         var j = 0;
27         for (var i = 0; i < dependent.length-1; ++i) {
28                 var start = dependent[i][0];
29                 var end = dependent[i+1][0];
30                 var average = 0, n = 0;
31                 for (; j < independent.length; ++j) {
32                         if (independent[j][0] < start)
33                                 continue;
34                         else if (independent[j][0] >= end)
35                                 break;
36                         average += independent[j][1];
37                         n += 1;
38                 }
39                 if (n > 0) {
40                         average /= n;
41                         result.push([dependent[i][1], average]);
42                 }
43         }
44         return result;
45 }
46
47 /**
48  * Helper function adds the sensors and actuators to a form
49  * @param input_type is it a radio? or is it a checkbox?
50  * @param check_first determines whether the first item is checked or not
51  * @param group which group this input belongs to (name field)
52  */
53 $.fn.deployDevices = function(input_type, check_first, group) {
54   var container = this;
55   var apply = function(dict, prefix) {
56     $.each(dict, function(key, val) {
57       var attributes = {
58           'type' : input_type, 'value' : key, 'alt' : val,
59           'class' : prefix, 'name' : group, 
60           'id' : prefix + '_' + val //Unique id (name mangling)
61       };
62       var entry = $("<input/>", attributes);
63       var label = $("<label/>", {'for' : prefix + '_' + val, 'text' : val}); 
64       entry.prop("checked", check_first);
65       check_first = false;
66       container.append(entry).append(label);
67     });
68   }
69   
70   apply(mctx.sensors, 'sensors');
71   apply(mctx.actuators, 'actuators');
72 };
73
74 /**
75  * Identify sensors/actuators
76  * @returns itself (Is this right?)
77  */
78 $.fn.setDevices = function() {
79   // Query for sensors and actuators
80   return $.ajax({
81     url : mctx.api + 'identify', 
82     data : {'sensors' : 1, 'actuators' : 1}
83   }).done(function (data) {
84     mctx.sensors = $.extend(mctx.sensors, data.sensors);
85     mctx.actuators = $.extend(mctx.actuators, data.actuators);
86     
87     //Always set the 'time' option to be checked
88     $("#xaxis input").prop('checked', true);  
89     $("#xaxis").deployDevices("radio", false, 'xaxis');
90     $("#yaxis").deployDevices("checkbox", true, 'yaxis');
91     $("#current_time").val(data.running_time);
92     //Add event listeners for when the inputs are changed
93     $(".change input").change(function () {
94       $("#graph").setGraph();
95     });
96   });
97 };
98
99 function graphUpdater() {
100   var urls = {
101     'sensors' : mctx.graph.api.sensors,
102     'actuators' : mctx.graph.api.actuators
103   }
104   
105   var updater = function () {
106     var time_limit = 20;
107     var responses = [];
108     var ctime =  $("#current_time");
109     
110     var xaxis = mctx.graph.xaxis;
111     var yaxis = mctx.graph.yaxis;
112     var start_time = mctx.graph.start_time;
113     var end_time = mctx.graph.end_time;
114     var devices = mctx.graph.devices;
115     
116     if (xaxis.size() < 1 || yaxis.size() < 1) {
117       mctx.graph.running = false;
118       return;
119     }
120     
121     $.each(devices, function(key, val) {
122       if (val.urltype in urls) {
123         var parameters = {id : val.id};
124         if (start_time != null) {
125           parameters.start_time = start_time;
126         }
127         if (end_time != null) {
128           parameters.end_time = end_time;
129         }
130         responses.push($.ajax({url : urls[val.urltype], data : parameters})
131         .done(function(json) {
132           //alert("Hi from " + json.name);
133           var dev = val.data;
134           for (var i = 0; i < json.data.length; ++i) {
135             if (dev.length <= 0 || json.data[i][0] > dev[dev.length-1][0]) {
136               dev.push(json.data[i]);
137             }
138           }
139           ctime.val(json.running_time);
140           //alert(devices[json.name].data);
141         }));
142       }
143     });
144
145     //... When the response is received, then() will happen (I think?)
146     $.when.apply(this, responses).then(function () {
147       var plot_data = [];
148       yaxis.each(function() {
149         //alert("Add " + $(this).val() + " to plot");
150         if (xaxis.attr("alt") === "time") {
151           //alert("Against time");
152           plot_data.push(devices[$(this).attr("alt")].data);
153         } else {
154           var result = []
155           dataMerge(devices[xaxis.attr("alt")].data, devices[$(this).attr("alt")].data, result);
156           /*
157           var astr = "[";
158           for (var i = 0; i < result.length; ++i)
159             astr += "[" + result[i][0] + "," + result[i][1] + "]" + ",";
160           astr += "]";
161           alert(astr);
162           */
163           plot_data.push(result);
164         }
165       });
166       
167       $.plot("#graph", plot_data);
168       if (mctx.graph.running) {
169         mctx.graph.timer = setTimeout(updater, 1000);
170       }
171     }, function () {mctx.graph.running=false; alert("Graph crashed");});
172   };
173   
174   mctx.graph.running = true;
175   updater();
176   return this;
177 }
178
179 /**
180  * Sets the graphs to graph stuff.
181  * @returns {$.fn}
182  */
183 $.fn.setGraph = function () {
184   // Determine which actuator/sensors to plot
185   var xaxis = $("#xaxis input[name=xaxis]:checked");
186   var yaxis = $("#yaxis input[name=yaxis]:checked");
187   if (xaxis.size() < 1 || yaxis.size() < 1) {
188     //nothing to plot...
189     return;
190   }
191   
192   var start_time = $("#start_time").val();
193   var end_time = $("#end_time").val();
194   if (!$.isNumeric(start_time)) {
195     start_time = null;
196   }
197   if (!$.isNumeric(end_time)) {
198     end_time = null;
199   }
200
201   var devices = {};
202   var populateDict = function () {
203     var dict = {};
204     dict['urltype'] = $(this).attr("class");
205     dict['id'] = $(this).attr("value");
206     dict['data'] = [];
207     dict['start_time'] = start_time;
208     dict['end_time'] = end_time;
209     devices[$(this).attr("alt")] = dict;
210   };
211   xaxis.each(populateDict);
212   yaxis.each(populateDict);
213   
214   mctx.graph.xaxis = xaxis;
215   mctx.graph.yaxis = yaxis;
216   mctx.graph.start_time = start_time;
217   mctx.graph.end_time = end_time;
218   mctx.graph.devices = devices;
219   
220   if (!mctx.graph.running) {
221     $("#graph-run").val("Pause");
222     graphUpdater();
223   }
224   
225   return this;
226 };
227
228 $.fn.runButton = function() {
229   //alert($(this).val());
230   if ($(this).val() === "Run") {
231     $("#graph").setGraph();
232     $(this).val("Pause");
233   }
234   else {
235     mctx.graph.running = false;
236     clearTimeout(mctx.graph.timer);
237     $(this).val("Run");
238   }
239 };

UCC git Repository :: git.ucc.asn.au