20af9cb1033ecaa358f0f9d535ad2f6523b1df36
[collection4.git] / share / collection.js
1 /**
2  * collection4 - collection.js
3  * Copyright (C) 2010  Florian octo Forster
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  * 
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA  02110-1301  USA
19  *
20  * Authors:
21  *   Florian octo Forster <ff at octo.it>
22  **/
23
24 var c4 =
25 {
26   instances: []
27 };
28
29 function instance_get_params (graph) /* {{{ */
30 {
31   var graph_selector = graph.graph_selector;
32   var inst_selector = graph.instance_selector;
33   var selector = {};
34
35   if (graph_selector.host == inst_selector.host)
36   {
37     selector.host = graph_selector.host;
38   }
39   else
40   {
41     selector.graph_host = graph_selector.host;
42     selector.inst_host = inst_selector.host;
43   }
44
45   if (graph_selector.plugin == inst_selector.plugin)
46   {
47     selector.plugin = graph_selector.plugin;
48   }
49   else
50   {
51     selector.graph_plugin = graph_selector.plugin;
52     selector.inst_plugin = inst_selector.plugin;
53   }
54
55   if (graph_selector.plugin_instance == inst_selector.plugin_instance)
56   {
57     selector.plugin_instance = graph_selector.plugin_instance;
58   }
59   else
60   {
61     selector.graph_plugin_instance = graph_selector.plugin_instance;
62     selector.inst_plugin_instance = inst_selector.plugin_instance;
63   }
64
65   if (graph_selector.type == inst_selector.type)
66   {
67     selector.type = graph_selector.type;
68   }
69   else
70   {
71     selector.graph_type = graph_selector.type;
72     selector.inst_type = inst_selector.type;
73   }
74
75   if (graph_selector.type_instance == inst_selector.type_instance)
76   {
77     selector.type_instance = graph_selector.type_instance;
78   }
79   else
80   {
81     selector.graph_type_instance = graph_selector.type_instance;
82     selector.inst_type_instance = inst_selector.type_instance;
83   }
84
85   return (selector);
86 } /* }}} instance_get_params */
87
88 function ident_clone (ident) /* {{{ */
89 {
90   var ret = {};
91
92   ret.host = ident.host;
93   ret.plugin = ident.plugin;
94   ret.plugin_instance = ident.plugin_instance;
95   ret.type = ident.type;
96   ret.type_instance = ident.type_instance;
97
98   return (ret);
99 } /* }}} ident_clone */
100
101 function graph_get_defs (graph)
102 {
103   if (!graph.def)
104   {
105     var params = ident_clone (graph.graph_selector);
106     params.action = "graph_def_json";
107
108     $.ajax({
109       url: "collection.fcgi",
110       async: false,
111       dataType: 'json',
112       data: params,
113       success: function (data)
114       {
115         if (!data)
116           return;
117
118         graph.def = data;
119       }});
120   }
121
122   if (graph.def)
123     return (graph.def);
124   return;
125 } /* graph_get_defs */
126
127 function instance_draw (inst, def, data)
128 {
129   var x_data = [];
130   var y_data = [];
131   var i;
132
133   if (!inst || !def || !data)
134     return;
135
136   for (i = 0; i < data.length; i++)
137   {
138     var ds = data[i];
139
140     var j;
141     var x = [];
142     var y = [];
143     var x_val;
144
145     x_val = ds.first_value_time;
146
147     for (j = 0; j < ds.data.length; j++)
148     {
149       var y_val = ds.data[j];
150
151       x.push (x_val);
152       y.push (y_val);
153
154       x_val += ds.interval;
155     }
156
157     x_data.push (x);
158     y_data.push (y);
159   }
160
161   inst.raphael.clear ();
162   if (def.title)
163     inst.raphael.g.text (250, 15, def.title);
164   if (def.vertical_label)
165     inst.raphael.g.text (5, 100, def.vertical_label).rotate (270);
166   inst.raphael.g.linechart(50, 25, 500, 150, x_data, y_data, {axis: "0 0 1 1"});
167 }
168
169 function json_graph_update (index)
170 {
171   var inst;
172   var def;
173   var params;
174
175   inst = c4.instances[index];
176   if (!inst)
177     return;
178
179   def = graph_get_defs (inst);
180   if (!def)
181     return;
182
183   if (!inst.raphael)
184     inst.raphael = Raphael ("c4-graph" + index);
185
186   params = instance_get_params (inst);
187   params.action = "instance_data_json";
188   params.begin = inst.begin;
189   params.end = inst.end;
190
191   $.getJSON ("collection.fcgi", params,
192       function (data)
193       {
194         instance_draw (inst, def, data);
195       }); /* getJSON */
196 } /* json_graph_update */
197
198 function format_instance(inst)
199 {
200   return ("<li class=\"instance\"><a href=\"" + location.pathname
201       + "?action=show_instance;" + inst.params + "\">" + inst.description
202       + "</a></li>");
203 }
204
205 function format_instance_list(instances)
206 {
207   var ret = "<ul class=\"instance_list\">";
208   var i;
209
210   if (instances.length == 0)
211     return ("");
212
213   for (i = 0; i < instances.length; i++)
214     ret += format_instance (instances[i]);
215   
216   ret += "</ul>";
217
218   return (ret);
219 }
220
221 function format_graph(graph)
222 {
223   return ("<li class=\"graph\">" + graph.title + format_instance_list (graph.instances) + "</li>");
224 }
225
226 function update_search_suggestions ()
227 {
228   var term = $("#search-input").val ();
229   if (term.length < 2)
230   {
231     $("#search-suggest").hide ();
232     return (true);
233   }
234
235   $("#search-suggest").show ();
236   $.getJSON ("collection.fcgi",
237     { "action": "search_json", "q": term},
238     function(data)
239     {
240       var i;
241       $("#search-suggest").html ("");
242       for (i = 0; i < data.length; i++)
243       {
244         var graph = data[i];
245         $("#search-suggest").append (format_graph (graph));
246       }
247     }
248   );
249 } /* update_search_suggestions */
250
251 function zoom_redraw (jq_obj) /* {{{ */
252 {
253   var url = jq_obj.data ("base_url");
254
255   if ((jq_obj == null) || (url == null))
256     return (false);
257
258   if (jq_obj.data ('begin') != null)
259     url += ";begin=" + jq_obj.data ('begin');
260   if (jq_obj.data ('end') != null)
261     url += ";end=" + jq_obj.data ('end');
262
263   jq_obj.attr ("src", url);
264   return (true);
265 } /* }}} function zoom_redraw */
266
267 function zoom_reset (graph_id, diff) /* {{{ */
268 {
269   var jq_obj;
270   var end;
271   var begin;
272
273   jq_obj = $("#" + graph_id);
274   if (jq_obj == null)
275     return (false);
276
277   end = new Number ((new Date ()).getTime () / 1000);
278   begin = new Number (end - diff);
279
280   jq_obj.data ('begin', begin.toFixed (0));
281   jq_obj.data ('end', end.toFixed (0));
282
283   return (zoom_redraw (jq_obj));
284 } /* }}} function zoom_reset */
285
286 function zoom_hour (graph_id) /* {{{ */
287 {
288   zoom_reset (graph_id, 3600);
289 } /* }}} function zoom_hour */
290
291 function zoom_day (graph_id) /* {{{ */
292 {
293   zoom_reset (graph_id, 86400);
294 } /* }}} function zoom_day */
295
296 function zoom_week (graph_id) /* {{{ */
297 {
298   zoom_reset (graph_id, 7 * 86400);
299 } /* }}} function zoom_week */
300
301 function zoom_month (graph_id) /* {{{ */
302 {
303   zoom_reset (graph_id, 31 * 86400);
304 } /* }}} function zoom_month */
305
306 function zoom_year (graph_id) /* {{{ */
307 {
308   zoom_reset (graph_id, 366 * 86400);
309 } /* }}} function zoom_year */
310
311 function zoom_relative (graph_id, factor_begin, factor_end) /* {{{ */
312 {
313   var jq_obj;
314   var end;
315   var begin;
316   var diff;
317
318   jq_obj = $("#" + graph_id);
319   if (jq_obj == null)
320     return (false);
321
322   begin = jq_obj.data ('begin');
323   end = jq_obj.data ('end');
324   if ((begin == null) || (end == null))
325     return (zoom_day (graph_id));
326
327   begin = new Number (begin);
328   end = new Number (end);
329
330   diff = end - begin;
331   if ((diff <= 300) && (factor_begin > 0.0) && (factor_end < 0.0))
332     return (true);
333
334   jq_obj.data ('begin', begin + (diff * factor_begin));
335   jq_obj.data ('end', end + (diff * factor_end));
336
337   return (zoom_redraw (jq_obj));
338 } /* }}} function zoom_relative */
339
340 function zoom_reference (graph_id) /* {{{ */
341 {
342   var jq_obj;
343   var end;
344   var begin;
345
346   jq_obj = $("#" + graph_id);
347   if (jq_obj == null)
348     return (false);
349
350   begin = jq_obj.data ('begin');
351   end = jq_obj.data ('end');
352   if ((begin == null) || (end == null))
353     return (false);
354
355   $(".graph-img img").each (function ()
356   {
357     $(this).data ('begin', begin);
358     $(this).data ('end', end);
359     zoom_redraw ($(this));
360   });
361 } /* }}} function zoom_reference */
362
363 function zoom_earlier (graph_id) /* {{{ */
364 {
365   return (zoom_relative (graph_id, -0.2, -0.2));
366 } /* }}} function zoom_earlier */
367
368 function zoom_later (graph_id) /* {{{ */
369 {
370   return (zoom_relative (graph_id, +0.2, +0.2));
371 } /* }}} function zoom_later */
372
373 function zoom_in (graph_id) /* {{{ */
374 {
375   return (zoom_relative (graph_id, +0.2, -0.2));
376 } /* }}} function zoom_earlier */
377
378 function zoom_out (graph_id) /* {{{ */
379 {
380   return (zoom_relative (graph_id, (-1.0 / 3.0), (1.0 / 3.0)));
381 } /* }}} function zoom_earlier */
382
383 $(document).ready(function() {
384     /* $("#layout-middle-right").html ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>"); */
385     $("#search-form").append ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>");
386     $("#search-suggest").hide ();
387
388     $("#search-input").blur (function()
389     {
390       window.setTimeout (function ()
391       {
392         $("#search-suggest").hide ();
393       }, 500);
394     });
395
396     $("#search-input").focus (function()
397     {
398       var term = $("#search-input").val ();
399       if (term.length < 2)
400       {
401         $("#search-suggest").hide ();
402       }
403       else
404       {
405         $("#search-suggest").show ();
406       }
407     });
408
409     $("#search-input").keyup (function()
410     {
411       update_search_suggestions ();
412     });
413
414     var graph_count = 0;
415     $(".graph-img").each (function (index, elem)
416     {
417       var id = "graph" + graph_count;
418       graph_count++;
419
420       $(this).find ("img").each (function (img_index, img_elem)
421       {
422         var base_url;
423
424         $(this).attr ("id", id);
425
426         base_url = $(this).attr ("src").replace (/;(begin|end)=[^;]*/g, '');
427         $(this).data ("base_url", base_url);
428       });
429
430       $(this).append ("<div class=\"graph-buttons presets\">"
431         + "<div class=\"graph-button\" onClick=\"zoom_hour  ('"+id+"');\">H</div>"
432         + "<div class=\"graph-button\" onClick=\"zoom_day   ('"+id+"');\">D</div>"
433         + "<div class=\"graph-button\" onClick=\"zoom_week  ('"+id+"');\">W</div>"
434         + "<div class=\"graph-button\" onClick=\"zoom_month ('"+id+"');\">M</div>"
435         + "<div class=\"graph-button\" onClick=\"zoom_year  ('"+id+"');\">Y</div>"
436         + "<div class=\"graph-button\" onClick=\"zoom_reference ('"+id+"');\">!</div>"
437         + "</div>"
438         + "<div class=\"graph-buttons navigation\">"
439         + "<div class=\"graph-button\" onClick=\"zoom_earlier ('"+id+"');\">←</div>"
440         + "<div class=\"graph-button\" onClick=\"zoom_out     ('"+id+"');\">−</div>"
441         + "<div class=\"graph-button\" onClick=\"zoom_in      ('"+id+"');\">+</div>"
442         + "<div class=\"graph-button\" onClick=\"zoom_later   ('"+id+"');\">→</div>"
443         + "</div>"
444         );
445     });
446
447     var i;
448     for (i = 0; i < c4.instances.length; i++)
449     {
450       json_graph_update (i);
451     }
452 });
453
454 /* vim: set sw=2 sts=2 et fdm=marker : */