@cryptotaxi247 / netdata-1 / commits / 29ecdb6a8

converted newline to LF

Costa Tsaousis (ktsaou) committed Mar 12, 2015 at 23:36 UTC 29ecdb6a8fc035eae3fdcc66c491c77af8e3429b
1 file changed +1015 -1015
web/index.js
+1015 -1015
@@ -1,1015 +1,1015 @@
1 -var page_is_visible = 1;
2 -
3 -var TARGET_THUMB_GRAPH_WIDTH = 500; // thumb charts width will range from 0.5 to 1.5 of that
4 -var MINIMUM_THUMB_GRAPH_WIDTH = 400; // thumb chart will generally try to be wider than that
5 -var TARGET_THUMB_GRAPH_HEIGHT = 180; // the height of the thumb charts
6 -
7 -var THUMBS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
8 -var THUMBS_POINTS_DIVISOR = 4;
9 -var THUMBS_STACKED_POINTS_DIVISOR = 10;
10 -
11 -var GROUPS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
12 -var GROUPS_POINTS_DIVISOR = 4;
13 -var GROUPS_STACKED_POINTS_DIVISOR = 10;
14 -
15 -var MAINCHART_MAX_TIME_TO_SHOW = 600; // how much time the main chart will present by default?
16 -var MAINCHART_POINTS_DIVISOR = 10; // how much detailed will the main chart be by default? 1 = finest, higher is faster
17 -var MAINCHART_STACKED_POINTS_DIVISOR = 20; // how much detailed will the main chart be by default? 1 = finest, higher is faster
18 -
19 -var MAINCHART_CONTROL_HEIGHT = 75; // how tall the control chart will be
20 -var MAINCHART_CONTROL_DIVISOR = 2; // how much detailed will the control chart be? 1 = finest, higher is faster
21 -var MAINCHART_INITIAL_SELECTOR= 40; // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
22 -
23 -var CHARTS_REFRESH_IDLE = 100;
24 -var CHARTS_CHECK_NO_FOCUS = 500;
25 -
26 -var MODE_THUMBS = 1;
27 -var MODE_MAIN = 2;
28 -var MODE_GROUP_THUMBS = 3;
29 -var mode; // one of the MODE_* values
30 -
31 -var mycharts = new Array();
32 -var mainchart;
33 -
34 -// html for the main menu
35 -var mainmenu = "";
36 -var categoriesmainmenu = "";
37 -var familiesmainmenu = "";
38 -var chartsmainmenu = "";
39 -
40 -
41 -// ------------------------------------------------------------------------
42 -// common HTML generation
43 -
44 -function thumbChartActions(i, c, nogroup) {
45 - var name = c.name;
46 - if(!nogroup) name = c.family;
47 -
48 - var refinfo = "the chart is drawing ";
49 - if(c.group == 1) refinfo += "every single point collected (" + c.update_every + "s each).";
50 - else refinfo += ((c.group_method == "average")?"the average":"the max") + " value for every " + (c.group * c.update_every) + " seconds of data";
51 -
52 - var html = "<div class=\"btn-group btn-group\" data-toggle=\"tooltip\" title=\"" + refinfo + "\">"
53 - + "<button type=\"button\" class=\"btn btn-default\" onclick=\"javascript: return;\"><span class=\"glyphicon glyphicon-info-sign\"></span></button>"
54 - + "</div>"
55 - + "<div class=\"btn-group btn-group\"><button type=\"button\" class=\"btn btn-default disabled\"><small>&nbsp;&nbsp; " + name + "</small></button>";
56 -
57 - if(!nogroup) {
58 - var ingroup = 0;
59 - var ingroup_detail = 0;
60 -
61 - $.each(mycharts, function(i, d) {
62 - if(d.family == c.family) {
63 - ingroup++;
64 - if(d.isdetail) ingroup_detail++;
65 - }
66 - });
67 -
68 - var hidden = "";
69 - if(ingroup_detail) hidden = ", including " + ingroup_detail + " charts not shown now";
70 -
71 - html += "<button type=\"button\" data-toggle=\"tooltip\" title=\"Show all " + ingroup + " charts in group '" + c.family + "'" + hidden + "\" class=\"btn btn-default\" onclick=\"initGroupGraphs('" + c.family +"');\"><span class=\"glyphicon glyphicon-th-large\"></span></button>";
72 - }
73 -
74 - html += "<button type=\"button\" data-toggle=\"tooltip\" title=\"show chart '" + c.name + "' in fullscreen\" class=\"btn btn-default\" onclick=\"initMainChartIndex(" + i +");\"><span class=\"glyphicon glyphicon-resize-full\"></span></button>"
75 - + "<button type=\"button\" data-toggle=\"tooltip\" title=\"set options for chart '" + c.name + "'\" class=\"btn btn-default disabled\" onclick=\"alert('Not implemented yet!');\"><span class=\"glyphicon glyphicon-cog\"></span></button>"
76 - + "<button type=\"button\" data-toggle=\"tooltip\" title=\"ignore chart '" + c.name + "'\" class=\"btn btn-default\" onclick=\"disableChart(" + i + ");\"><span class=\"glyphicon glyphicon-trash\"></span></button>"
77 - + "</div>";
78 -
79 - return html;
80 -}
81 -
82 -function mylog(txt) {
83 - console.log(txt);
84 -}
85 -
86 -function chartssort(a, b) {
87 - if(a.priority == b.priority) {
88 - if(a.name < b.name) return -1;
89 - }
90 - else if(a.priority < b.priority) return -1;
91 -
92 - return 1;
93 -}
94 -
95 -
96 -// ------------------------------------------------------------------------
97 -// MAINGRAPH = fullscreen view of 1 graph
98 -
99 -// copy the chart c to mainchart
100 -// switch to main graphs screen
101 -function initMainChart(c) {
102 - if(mainchart) cleanThisChart(mainchart);
103 -
104 - mainchart = $.extend(true, {}, c);
105 - mainchart.enabled = true;
106 - mainchart.refreshCount = 0;
107 - mainchart.last_updated = 0;
108 - mainchart.chartOptions.explorer = null;
109 - mainchart.chart = null;
110 -
111 - mainchart.chartOptions.width = screenWidth();
112 - mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
113 - if(mainchart.chartOptions.height < 300) mainchart.chartOptions.height = 300;
114 -
115 - mainchart.div = 'maingraph';
116 - mainchart.time_to_show = (mainchart.last_entry_t - mainchart.first_entry_t) / MAINCHART_INITIAL_SELECTOR;
117 - if(mainchart.time_to_show < MAINCHART_INITIAL_SELECTOR) mainchart.time_to_show = MAINCHART_INITIAL_SELECTOR;
118 - calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, 0);
119 -
120 - // copy it to the hidden chart
121 - mainchart.hiddenchart = $.extend(true, {}, mainchart);
122 - mainchart.hiddenchart.chartOptions.height = MAINCHART_CONTROL_HEIGHT;
123 - mainchart.hiddenchart.div = 'maingraph_control';
124 - mainchart.hiddenchart.non_zero = 0;
125 -
126 - // initialize the div
127 - showChartIsLoading(mainchart.div, mainchart.name, mainchart.chartOptions.width, mainchart.chartOptions.height);
128 - document.getElementById(mainchart.hiddenchart.div).innerHTML = "<table><tr><td align=\"center\" width=\"" + mainchart.hiddenchart.chartOptions.width + "\" height=\"" + mainchart.hiddenchart.chartOptions.height + "\" style=\"vertical-align:middle\"><h4><span class=\"label label-default\">Please wait...</span></h4></td></tr></table>";
129 - //showChartIsLoading(mainchart.hiddenchart.div, mainchart.hiddenchart.name, mainchart.hiddenchart.chartOptions.width, mainchart.hiddenchart.chartOptions.height);
130 -
131 - // set the radio buttons
132 - setMainChartGroupMethod(mainchart.group_method, 'no-refresh');
133 - setMainChartMax('normal');
134 -
135 - $('#group' + mainchart.group).trigger('click');
136 - setMainChartGroup(mainchart.group, 'no-refresh');
137 -
138 - switchToMainGraph();
139 -}
140 -
141 -function refreshHiddenChart(doNext) {
142 - if(refresh_mode == REFRESH_PAUSED && mainchart.hiddenchart.last_updated != 0) {
143 - if(typeof doNext == "function") doNext();
144 - return;
145 - }
146 -
147 - // is it too soon for a refresh?
148 - var now = new Date().getTime();
149 - if((now - mainchart.hiddenchart.last_updated) < (mainchart.hiddenchart.group * mainchart.hiddenchart.update_every * 1000)) {
150 - if(typeof doNext == "function") doNext();
151 - return;
152 - }
153 -
154 - if(mainchart.dashboard && mainchart.hiddenchart.refreshCount > 50) {
155 - mainchart.dashboard.clear();
156 - mainchart.control_wrapper.clear();
157 - mainchart.hidden_wrapper.clear();
158 -
159 - mainchart.dashboard = null;
160 - mainchart.control_wrapper = null;
161 - mainchart.hidden_wrapper = null;
162 - mainchart.hiddenchart.last_updated = 0;
163 - }
164 -
165 - if(!mainchart.dashboard) {
166 - var controlopts = $.extend(true, {}, mainchart.chartOptions, {
167 - lineWidth: 1,
168 - height: mainchart.hiddenchart.chartOptions.height,
169 - chartArea: {'width': '98%'},
170 - hAxis: {'baselineColor': 'none', viewWindowMode: 'maximized'},
171 - vAxis: {'title': null},
172 - });
173 -
174 - mainchart.dashboard = new google.visualization.Dashboard(document.getElementById('maingraph_dashboard'));
175 - mainchart.control_wrapper = new google.visualization.ControlWrapper({
176 - controlType: 'ChartRangeFilter',
177 - containerId: 'maingraph_control',
178 - options: {
179 - filterColumnIndex: 0,
180 - ui: {
181 - chartType: mainchart.chartType,
182 - chartOptions: controlopts,
183 - minRangeSize: (MAINCHART_MAX_TIME_TO_SHOW * 1000) / MAINCHART_POINTS_DIVISOR,
184 - }
185 - },
186 - });
187 - mainchart.hidden_wrapper = new google.visualization.ChartWrapper({
188 - chartType: mainchart.chartType,
189 - containerId: 'maingraph_hidden',
190 - options: {
191 - isStacked: mainchart.chartOptions.isStacked,
192 - width: mainchart.hiddenchart.chartOptions.width,
193 - height: mainchart.hiddenchart.chartOptions.height,
194 - //chartArea: {'height': '80%', 'width': '100%'},
195 - //hAxis: {'slantedText': false},
196 - //legend: {'position': 'none'}
197 - },
198 - });
199 -
200 - mainchart.hiddenchart.refreshCount = 0;
201 - }
202 -
203 - // load the data for the control and the hidden wrappers
204 - // calculate the group and points to show for the control chart
205 - calculateChartPointsToShow(mainchart.hiddenchart, MAINCHART_CONTROL_DIVISOR, 0, -1);
206 -
207 - $.ajax({
208 - url: generateChartURL(mainchart.hiddenchart),
209 - dataType:"json",
210 - cache: false
211 - })
212 - .done(function(jsondata) {
213 - if(!jsondata || jsondata.length == 0) return;
214 -
215 - mainchart.control_data = new google.visualization.DataTable(jsondata);
216 -
217 - if(mainchart.hiddenchart.last_updated == 0) {
218 - google.visualization.events.addListener(mainchart.control_wrapper, 'ready', mainchartControlReadyEvent);
219 - mainchart.dashboard.bind(mainchart.control_wrapper, mainchart.hidden_wrapper);
220 - }
221 - if(refresh_mode != REFRESH_PAUSED) {
222 - mainchart.control_wrapper.setState({range: {
223 - start: new Date((Math.round(new Date().getTime() / 1000) - mainchart.hiddenchart.time_to_show) * 1000),
224 - end: new Date()
225 - }});
226 - }
227 -
228 - mainchart.dashboard.draw(mainchart.control_data);
229 - mainchart.hiddenchart.last_updated = new Date().getTime();
230 - mainchart.hiddenchart.refreshCount++;
231 - })
232 - .always(function() {
233 - if(typeof doNext == "function") doNext();
234 - });
235 -}
236 -
237 -function mainchartControlReadyEvent() {
238 - google.visualization.events.addListener(mainchart.control_wrapper, 'statechange', mainchartControlStateHandler);
239 - //mylog(mainchart);
240 -}
241 -
242 -function mainchartControlStateHandler() {
243 - // setMainChartPlay('pause');
244 -
245 - var state = mainchart.control_wrapper.getState();
246 - mainchart.after = Math.round(state.range.start.getTime() / 1000);
247 - mainchart.before = Math.round(state.range.end.getTime() / 1000);
248 -
249 - calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, 0);
250 - //mylog('group = ' + mainchart.group + ', points_to_show = ' + mainchart.points_to_show + ', dt = ' + (mainchart.before - mainchart.after));
251 -
252 - $('#group' + mainchart.group).trigger('click');
253 - mainchart.last_updated = 0;
254 -
255 - if(refresh_mode != REFRESH_PAUSED) pauseGraphs();
256 -}
257 -
258 -function initMainChartIndex(i) {
259 - if(mode == MODE_GROUP_THUMBS)
260 - initMainChart(group_charts[i]);
261 -
262 - else if(mode == MODE_THUMBS)
263 - initMainChart(mycharts[i]);
264 -
265 - else
266 - initMainChart(mycharts[i]);
267 -}
268 -
269 -function initMainChartIndexOfMyCharts(i) {
270 - initMainChart(mycharts[i]);
271 -}
272 -
273 -var last_main_chart_max='normal';
274 -function setMainChartMax(m) {
275 - if(!mainchart) return;
276 -
277 - if(m == 'toggle') {
278 - if(last_main_chart_max == 'maximized') m = 'normal';
279 - else m = 'maximized';
280 - }
281 -
282 - if(m == "maximized") {
283 - mainchart.chartOptions.theme = 'maximized';
284 - //mainchart.chartOptions.axisTitlesPosition = 'in';
285 - //mainchart.chartOptions.legend = {position: 'none'};
286 - mainchart.chartOptions.hAxis.title = null;
287 - mainchart.chartOptions.hAxis.viewWindowMode = 'maximized';
288 - mainchart.chartOptions.vAxis.viewWindowMode = 'maximized';
289 - mainchart.chartOptions.chartArea = {'width': '98%', 'height': '100%'};
290 - }
291 - else {
292 - mainchart.chartOptions.hAxis.title = null;
293 - mainchart.chartOptions.theme = null;
294 - mainchart.chartOptions.hAxis.viewWindowMode = null;
295 - mainchart.chartOptions.vAxis.viewWindowMode = null;
296 - mainchart.chartOptions.chartArea = {'width': '80%', 'height': '90%'};
297 - }
298 - $('.mainchart_max_button').button(m);
299 - last_main_chart_max = m;
300 - mainchart.last_updated = 0;
301 -}
302 -
303 -function setMainChartGroup(g, norefresh) {
304 - if(!mainchart) return;
305 -
306 - mainchart.group = g;
307 -
308 - if(!mainchart.before && !mainchart.after)
309 - calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, mainchart.group);
310 - else
311 - calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, mainchart.group);
312 -
313 - if(!norefresh) {
314 - mainchart.last_updated = 0;
315 - }
316 -}
317 -
318 -var last_main_chart_avg = null;
319 -function setMainChartGroupMethod(g, norefresh) {
320 - if(!mainchart) return;
321 -
322 - if(g == 'toggle') {
323 - if(last_main_chart_avg == 'max') g = 'average';
324 - else g = 'max';
325 - }
326 -
327 - mainchart.group_method = g;
328 -
329 - $('.mainchart_avg_button').button(g);
330 -
331 - if(!norefresh) {
332 - mainchart.last_updated = 0;
333 - }
334 -
335 - last_main_chart_avg = g;
336 -}
337 -
338 -function setMainChartPlay(p) {
339 - if(!mainchart) return;
340 -
341 - if(p == 'toggle') {
342 - if(refresh_mode != REFRESH_ALWAYS) p = 'play';
343 - else p = 'pause';
344 - }
345 -
346 - if(p == 'play') {
347 - //mainchart.chartOptions.explorer = null;
348 - mainchart.after = 0;
349 - mainchart.before = 0;
350 - calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, 0);
351 - $('#group' + mainchart.group).trigger('click');
352 - mainchart.last_updated = 0;
353 - mainchart.hiddenchart.last_updated = 0;
354 - playGraphs();
355 - }
356 - else {
357 - //mainchart.chartOptions.explorer = {
358 - // 'axis': 'horizontal',
359 - // 'maxZoomOut': 1,
360 - //};
361 - //mainchart.last_updated = 0;
362 -
363 - //if(!refreshChart(mainchart, pauseGraphs))
364 - pauseGraphs();
365 - }
366 -}
367 -
368 -
369 -// ------------------------------------------------------------------------
370 -// Chart resizing
371 -
372 -function screenWidth() {
373 - return (($(window).width() * 0.95) - 50);
374 -}
375 -
376 -// calculate the proper width for the thumb charts
377 -function thumbWidth() {
378 - var cwidth = screenWidth();
379 - var items = Math.round(cwidth / TARGET_THUMB_GRAPH_WIDTH);
380 - if(items < 1) items = 1;
381 -
382 - if(items > 1 && (cwidth / items) < MINIMUM_THUMB_GRAPH_WIDTH) items--;
383 -
384 - return Math.round(cwidth / items) - 1;
385 -}
386 -
387 -function groupChartSizes() {
388 - var s = { width: screenWidth() / 2, height: ($(window).height() - 130) / 3 - 10};
389 - if(s.width < MINIMUM_THUMB_GRAPH_WIDTH * 1.5) s.width = screenWidth();
390 -
391 - var count = 0;
392 - if(group_charts) $.each(group_charts, function(i, c) {
393 - if(c.enabled) count++;
394 - });
395 -
396 - if(count == 0) {
397 - s.width = TARGET_THUMB_GRAPH_WIDTH;
398 - s.height = TARGET_THUMB_GRAPH_HEIGHT;
399 - }
400 - if(count < 4) {
401 - s.width = screenWidth();
402 - s.height = ($(window).height() - 130) / count - 10;
403 - }
404 - else if(count == 4) {
405 - s.height = ($(window).height() - 130) / 2 - 10;
406 - }
407 -
408 - if(s.height < TARGET_THUMB_GRAPH_HEIGHT * 1.5)
409 - s.height = TARGET_THUMB_GRAPH_HEIGHT * 1.5;
410 -
411 - return s;
412 -}
413 -
414 -// resize all charts
415 -// if the thumb charts need resize in their width, reset them
416 -function resizeCharts() {
417 - var width = screenWidth();
418 -
419 - if(mainchart) {
420 - mainchart.chartOptions.width = width;
421 - mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
422 - mainchart.last_updated = 0;
423 -
424 - mainchart.hidden_wrapper.setOption('width', width);
425 - mainchart.control_wrapper.setOption('ui.chartOptions.width', width);
426 - mainchart.hiddenchart.chartOptions.width = width;
427 - mainchart.hiddenchart.last_updated = 0;
428 - }
429 -
430 - width = thumbWidth();
431 - $.each(mycharts, function(i, c) {
432 - if(c.enabled && c.chartOptions.width != width) {
433 - cleanThisChart(c);
434 - c.chartOptions.width = width;
435 - calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
436 - showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
437 - c.last_updated = 0;
438 - }
439 - });
440 -
441 - if(group_charts) $.each(group_charts, function(i, c) {
442 - var sizes = groupChartSizes();
443 -
444 - if(c.enabled && (c.chartOptions.width != sizes.width || c.chartOptions.height != sizes.height)) {
445 - cleanThisChart(c);
446 - c.chartOptions.width = sizes.width;
447 - c.chartOptions.height = sizes.height;
448 - calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
449 - showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
450 - c.last_updated = 0;
451 - }
452 - });
453 -}
454 -
455 -var resize_request = false;
456 -window.onresize = function(event) {
457 - resize_request = true;
458 -};
459 -
460 -
461 -// ------------------------------------------------------------------------
462 -// Core of the thread refreshing the charts
463 -
464 -var REFRESH_PAUSED = 0;
465 -var REFRESH_ALWAYS = 1;
466 -
467 -var refresh_mode = REFRESH_PAUSED;
468 -var last_refresh = 0;
469 -function playGraphs() {
470 - if(refresh_mode == REFRESH_ALWAYS) return;
471 -
472 - //mylog('PlayGraphs()');
473 - refresh_mode = REFRESH_ALWAYS;
474 - $('.mainchart_play_button').button('play');
475 -
476 - // check if the thread died due to a javascript error
477 - var now = new Date().getTime();
478 - if((now - last_refresh) > 5000) {
479 - // it died or never started
480 - //mylog('It seems the refresh thread died. Restarting it.');
481 - chartsRefresh();
482 - }
483 -}
484 -
485 -function pauseGraphs() {
486 - if(refresh_mode == REFRESH_PAUSED) return;
487 -
488 - //mylog('PauseGraphs()');
489 - refresh_mode = REFRESH_PAUSED;
490 - $('.mainchart_play_button').button('pause');
491 -}
492 -
493 -var interval = null;
494 -function checkRefreshThread() {
495 - if(interval == null) {
496 - interval = setInterval(checkRefreshThread, 2000);
497 - return;
498 - }
499 -
500 - var now = new Date().getTime();
501 - if(now - last_refresh > 10000) {
502 - mylog('Refresh thread died. Restarting it.');
503 - chartsRefresh();
504 - }
505 -}
506 -
507 -// refresh the proper chart
508 -// this is an internal function.
509 -// never call it directly, or new javascript threads will be spawn
510 -var timeout = null;
511 -function chartsRefresh() {
512 - last_refresh = new Date().getTime();
513 -
514 - if(!page_is_visible) {
515 - timeout = setTimeout(triggerRefresh, CHARTS_CHECK_NO_FOCUS);
516 - return;
517 - }
518 -
519 - if(resize_request) {
520 - resizeCharts();
521 - resize_request = false;
522 - // refresh_mode = REFRESH_ALWAYS;
523 - }
524 -
525 - if(refresh_mode == REFRESH_PAUSED) {
526 - if(mode == MODE_MAIN && mainchart.last_updated == 0) {
527 - mainChartRefresh();
528 - return;
529 - }
530 - }
531 -
532 - if(mode == MODE_THUMBS) thumbChartsRefresh();
533 - else if(mode == MODE_GROUP_THUMBS) groupChartsRefresh();
534 - else if(mode == MODE_MAIN) mainChartRefresh();
535 - else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
536 -}
537 -
538 -// callback for refreshing the charts later
539 -// this is an internal function.
540 -// never call it directly, or new javascript threads will be spawn
541 -function triggerRefresh() {
542 - //mylog('triggerRefresh()');
543 -
544 - // cleanup has to take place when the charts are not refreshed
545 - // since the refreshing thread is in this function, it means
546 - // nothing is being refreshed.
547 - cleanupCharts();
548 -
549 - if(mode == MODE_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
550 - else if(mode == MODE_GROUP_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
551 - else if(mode == MODE_MAIN) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
552 - else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
553 -}
554 -
555 -// refresh the main chart
556 -// make sure we don't loose the refreshing thread
557 -function mainChartRefresh() {
558 - //mylog('mainChartRefresh()');
559 -
560 - if(mode != MODE_MAIN || !mainchart) {
561 - triggerRefresh();
562 - return;
563 - }
564 -
565 - if(refresh_mode == REFRESH_PAUSED && mainchart.last_updated != 0) {
566 - hiddenChartRefresh();
567 - return;
568 - }
569 -
570 - if(!refreshChart(mainchart, hiddenChartRefresh))
571 - hiddenChartRefresh();
572 -}
573 -
574 -function hiddenChartRefresh() {
575 - refreshHiddenChart(triggerRefresh);
576 -}
577 -
578 -function roundRobinRefresh(charts, startat) {
579 - var refreshed = false;
580 -
581 - // find a chart to refresh
582 - var all = charts.length;
583 - var cur = startat;
584 - var count = 0;
585 -
586 - for(count = 0; count < all ; count++, cur++) {
587 - if(cur >= all) cur = 0;
588 -
589 - if(charts[cur].enabled) {
590 - //mylog('going to refresh chart ' + charts[cur].name);
591 - refreshed = refreshChart(charts[cur], chartsRefresh);
592 - if(refreshed) break;
593 - }
594 - }
595 -
596 - if(!refreshed) triggerRefresh();
597 - return cur;
598 -}
599 -
600 -// refresh the thumb charts
601 -// make sure we don't loose the refreshing thread
602 -var last_thumb_updated = 0;
603 -function thumbChartsRefresh() {
604 - //mylog('thumbChartsRefresh()');
605 -
606 - if(mycharts.length == 0 || mode != MODE_THUMBS) {
607 - triggerRefresh();
608 - return;
609 - }
610 -
611 - last_thumb_updated = roundRobinRefresh(mycharts, last_thumb_updated);
612 -}
613 -
614 -// refresh the group charts
615 -// make sure we don't loose the refreshing thread
616 -var last_group_updated = 0;
617 -function groupChartsRefresh() {
618 - //mylog('groupChartsRefresh()');
619 -
620 - if(!group_charts || group_charts.length == 0 || mode != MODE_GROUP_THUMBS) {
621 - //mylog('cannot refresh charts');
622 - triggerRefresh();
623 - return;
624 - }
625 -
626 - last_group_updated = roundRobinRefresh(group_charts, last_group_updated);
627 -}
628 -
629 -
630 -// ------------------------------------------------------------------------
631 -// switch the screen between views
632 -// these should be called only from initXXXX()
633 -
634 -function disableChart(i) {
635 - //mylog('disableChart(' + i + ')');
636 -
637 - var chart = null;
638 -
639 - var count = 0;
640 - if(mode == MODE_GROUP_THUMBS && group_charts) {
641 - $.each(group_charts, function(i, c) {
642 - if(c.enabled) count++;
643 - });
644 -
645 - if(i < group_charts.length) chart = group_charts[i];
646 - }
647 - else if(mode == MODE_THUMBS) {
648 - $.each(mycharts, function(i, c) {
649 - if(c.enabled) count++;
650 - });
651 -
652 - if(i < mycharts.length) chart = mycharts[i];
653 - }
654 -
655 - if(!chart) return;
656 -
657 - if(count <= 1) {
658 - alert('Cannot close the last chart shown.');
659 - return;
660 - }
661 -
662 - if(chart) {
663 - //mylog("disabling chart " + chart.name);
664 - chart.disablethisplease = true;
665 - }
666 -}
667 -
668 -function cleanThisChart(chart, emptydivs) {
669 - //mylog('cleanThisChart(' + chart.name + ', ' + emptydivs +')');
670 -
671 - if(chart.dashboard) {
672 - chart.dashboard.clear();
673 - chart.dashboard = null;
674 -
675 - if(chart.control_wrapper) {
676 - chart.control_wrapper.clear();
677 - chart.control_wrapper = null;
678 - }
679 -
680 - if(chart.hidden_wrapper) {
681 - chart.hidden_wrapper.clear();
682 - chart.hidden_wrapper = null;
683 - }
684 -
685 - chart.control_data = null;
686 - }
687 -
688 - if(chart.chart) chart.chart.clearChart();
689 - chart.chart = null;
690 -
691 - if(emptydivs) {
692 - var div = document.getElementById(chart.div);
693 - if(div) {
694 - div.style.display = 'none';
695 - div.innerHTML = "";
696 - }
697 -
698 - div = document.getElementById(chart.div + "_parent");
699 - if(div) {
700 - div.style.display = 'none';
701 - div.innerHTML = "";
702 - }
703 - }
704 -
705 - //mylog("chart " + chart.name + " cleaned with option " + emptydivs);
706 -}
707 -
708 -// cleanup the previously shown charts
709 -function cleanupCharts() {
710 - //mylog('cleanupCharts()');
711 -
712 - if(mode != MODE_MAIN && mainchart) {
713 - if(mainchart.chart) cleanThisChart(mainchart);
714 - mainchart = null;
715 - }
716 -
717 - if(mode != MODE_GROUP_THUMBS && group_charts) {
718 - clearGroupGraphs();
719 - }
720 -
721 - // cleanup the disabled charts
722 - $.each(mycharts, function(i, c) {
723 - if(c.disablethisplease && c.enabled) {
724 - cleanThisChart(c, 'emptydivs');
725 - c.disablethisplease = false;
726 - c.enabled = false;
727 - resize_request = true;
728 - //mylog("disabled chart " + c.name + " removed");
729 - }
730 - });
731 -
732 - if(group_charts) $.each(group_charts, function(i, c) {
733 - if(c.disablethisplease && c.enabled) {
734 - cleanThisChart(c, 'emptydivs');
735 - c.disablethisplease = false;
736 - c.enabled = false;
737 - resize_request = true;
738 - //mylog("disabled chart " + c.name + " removed");
739 - }
740 - });
741 -
742 - // we never cleanup the thumb charts
743 -}
744 -
745 -function updateUI() {
746 - $('[data-toggle="tooltip"]').tooltip({'placement': 'top', 'container': 'body', 'html': true});
747 -
748 - $('[data-spy="scroll"]').each(function () {
749 - var $spy = $(this).scrollspy('refresh')
750 - })
751 -}
752 -
753 -var thumbsScrollPosition = null;
754 -function switchToMainGraph() {
755 - //mylog('switchToMainGraph()');
756 -
757 - if(!mainchart) return;
758 -
759 - if(!group_charts) thumbsScrollPosition = window.pageYOffset;
760 -
761 - document.getElementById('maingraph_container').style.display = 'block';
762 - document.getElementById('thumbgraphs_container').style.display = 'none';
763 - document.getElementById('groupgraphs_container').style.display = 'none';
764 -
765 - document.getElementById("main_menu_div").innerHTML = "<ul class=\"nav navbar-nav\"><li><a href=\"javascript:switchToThumbGraphs();\"><span class=\"glyphicon glyphicon-circle-arrow-left\"></span> Back to Dashboard</a></li><li class=\"active\"><a href=\"#\">" + mainchart.name + "</a></li>" + familiesmainmenu + chartsmainmenu + "</ul>";
766 -
767 - window.scrollTo(0, 0);
768 -
769 - mode = MODE_MAIN;
770 - playGraphs();
771 - updateUI();
772 -}
773 -
774 -function switchToThumbGraphs() {
775 - //mylog('switchToThumbGraphs()');
776 -
777 - document.getElementById('maingraph_container').style.display = 'none';
778 - document.getElementById('thumbgraphs_container').style.display = 'block';
779 - document.getElementById('groupgraphs_container').style.display = 'none';
780 -
781 - document.getElementById("main_menu_div").innerHTML = mainmenu;
782 -
783 - if(thumbsScrollPosition) window.scrollTo(0, thumbsScrollPosition);
784 -
785 - // switch mode
786 - mode = MODE_THUMBS;
787 - playGraphs();
788 - updateUI();
789 -}
790 -
791 -function switchToGroupGraphs() {
792 - //mylog('switchToGroupGraphs()');
793 -
794 - if(!group_charts) return;
795 -
796 - if(!mainchart) thumbsScrollPosition = window.pageYOffset;
797 -
798 - document.getElementById('maingraph_container').style.display = 'none';
799 - document.getElementById('thumbgraphs_container').style.display = 'none';
800 - document.getElementById('groupgraphs_container').style.display = 'block';
801 -
802 - document.getElementById("main_menu_div").innerHTML = "<ul class=\"nav navbar-nav\"><li><a href=\"javascript:switchToThumbGraphs();\"><span class=\"glyphicon glyphicon-circle-arrow-left\"></span> Back to Dashboard</a></li><li class=\"active\"><a href=\"#\">" + group_charts[0].family + "</a></li>" + familiesmainmenu + chartsmainmenu + "</ul>";
803 -
804 - window.scrollTo(0, 0);
805 -
806 - mode = MODE_GROUP_THUMBS;
807 - playGraphs();
808 - updateUI();
809 -}
810 -
811 -
812 -// ------------------------------------------------------------------------
813 -// Group Charts
814 -
815 -var group_charts = null;
816 -function initGroupGraphs(group) {
817 - var count = 0;
818 -
819 - if(group_charts) clearGroupGraphs();
820 - group_charts = new Array();
821 -
822 - var groupbody = "";
823 - $.each(mycharts, function(i, c) {
824 - if(c.family == group) {
825 - group_charts[count] = [];
826 - group_charts[count] = $.extend(true, {}, c);
827 - group_charts[count].div += "_group";
828 - group_charts[count].enabled = true;
829 - group_charts[count].chart = null;
830 - group_charts[count].last_updated = 0;
831 - count++;
832 - }
833 - });
834 - group_charts.sort(chartssort);
835 -
836 - var sizes = groupChartSizes();
837 -
838 - var groupbody = "";
839 - $.each(group_charts, function(i, c) {
840 - c.chartOptions.width = sizes.width;
841 - c.chartOptions.height = sizes.height;
842 -
843 - calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
844 -
845 - groupbody += "<div class=\"thumbgraph\" id=\"" + c.div + "_parent\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.name, c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\">" + thumbChartActions(i, c, 'nogroup') + "</td></tr><tr><td height='15'></td></tr></table></div>";
846 - });
847 - groupbody += "";
848 -
849 - document.getElementById("groupgraphs").innerHTML = groupbody;
850 - switchToGroupGraphs();
851 -}
852 -
853 -function clearGroupGraphs() {
854 - if(group_charts && group_charts.length) {
855 - $.each(group_charts, function(i, c) {
856 - cleanThisChart(c, 'emptydivs');
857 - });
858 -
859 - group_charts = null;
860 - }
861 -
862 - document.getElementById("groupgraphs").innerHTML = "";
863 -}
864 -
865 -
866 -// ------------------------------------------------------------------------
867 -// Global entry point
868 -// initialize the thumb charts
869 -
870 -// load the charts from the server
871 -// generate html for the thumbgraphs to support them
872 -function initCharts() {
873 - var width = thumbWidth();
874 - var height = TARGET_THUMB_GRAPH_HEIGHT;
875 -
876 - loadCharts(null, function(all) {
877 - mycharts = all.charts;
878 -
879 - if(mycharts == null || mycharts.length == 0) {
880 - alert("Cannot load data from server.");
881 - return;
882 - }
883 -
884 - var thumbsContainer = document.getElementById("thumbgraphs");
885 - if(!thumbsContainer) {
886 - alert("Cannot find the thumbsContainer");
887 - return;
888 - }
889 -
890 - mycharts.sort(chartssort);
891 -
892 - document.getElementById('hostname_id').innerHTML = all.hostname;
893 - document.title = all.hostname;
894 -
895 - // create an array for grouping all same-type graphs together
896 - var dimensions = 0;
897 - var categories = new Array();
898 - var families = new Array();
899 - var chartslist = new Array();
900 - $.each(mycharts, function(i, c) {
901 - var j;
902 -
903 - chartslist.push({name: c.name, type: c.type, id: i});
904 -
905 - dimensions += c.dimensions.length;
906 - c.chartOptions.width = width;
907 - c.chartOptions.height = height;
908 -
909 - // calculate how many point to show for each chart
910 - //c.points_to_show = Math.round(c.entries / c.group) - 1;
911 - // show max 10 mins of data
912 - //if(c.points_to_show * c.group > THUMBS_MAX_TIME_TO_SHOW) c.points_to_show = THUMBS_MAX_TIME_TO_SHOW / c.group;
913 - calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
914 -
915 - if(c.enabled) {
916 - var h = "<div class=\"thumbgraph\" id=\"" + c.div + "_parent\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.name, c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\">"
917 - + thumbChartActions(i, c)
918 - + "</td></tr><tr><td height='15'></td></tr></table></div>";
919 -
920 - // find the categories object for this type
921 - for(j = 0; j < categories.length ;j++) {
922 - if(categories[j].name == c.type) {
923 - categories[j].html += h;
924 - categories[j].count++;
925 - break;
926 - }
927 - }
928 -
929 - if(j == categories.length)
930 - categories.push({name: c.type, title: c.category, description: '', priority: c.categoryPriority, count: 1, glyphicon: c.glyphicon, html: h});
931 - }
932 -
933 - // find the families object for this type
934 - for(j = 0; j < families.length ;j++) {
935 - if(families[j].name == c.family) {
936 - families[j].count++;
937 - break;
938 - }
939 - }
940 -
941 - if(j == families.length)
942 - families.push({name: c.family, count: 1});
943 - });
944 -
945 - document.getElementById('server_summary_id').innerHTML = "<small>NetData server at <b>" + all.hostname + "</b> is maintaining <b>" + mycharts.length + "</b> charts, having <b>" + dimensions + "</b> dimensions (by default with <b>" + all.history + "</b> entries each), which are updated every <b>" + all.update_every + "s</b>, using a total of <b>" + (Math.round(all.memory * 10 / 1024 / 1024) / 10) + " MB</b> for the round robin database.</small>";
946 -
947 - $.each(categories, function(i, a) {
948 - a.html = "<tr><td id=\"" + a.name + "\"><ol class=\"breadcrumb graphs\"><li class=\"active\"><span class=\"glyphicon " + a.glyphicon + "\"></span> &nbsp; <a id=\"" + a.name + "\" href=\"#" + a.name + "\"><b>" + a.title + "</b> " + a.description + " </a></li></ol></td></tr><tr><td><div class=\"thumbgraphs\">" + a.html + "</td></tr>";
949 - });
950 -
951 - function categoriessort(a, b) {
952 - if(a.priority < b.priority) return -1;
953 - return 1;
954 - }
955 - categories.sort(categoriessort);
956 -
957 - function familiessort(a, b) {
958 - if(a.name < b.name) return -1;
959 - return 1;
960 - }
961 - families.sort(familiessort);
962 -
963 - function chartslistsort(a, b) {
964 - if(a.name < b.name) return -1;
965 - return 1;
966 - }
967 - chartslist.sort(chartslistsort);
968 -
969 - // combine all the htmls into one
970 - var allcategories = "<table width=\"100%\">";
971 - mainmenu = '<ul class="nav navbar-nav">';
972 -
973 - categoriesmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-fire\"></span> Dashboard Sections <b class="caret"></b></a><ul class="dropdown-menu">';
974 - $.each(categories, function(i, a) {
975 - allcategories += a.html;
976 - categoriesmainmenu += "<li><a href=\"#" + a.name + "\">" + a.title + "</a></li>";
977 - });
978 - categoriesmainmenu += "</ul></li>";
979 - allcategories += "</table>";
980 -
981 - familiesmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-th-large\"></span> Chart Families <b class="caret"></b></a><ul class="dropdown-menu">';
982 - $.each(families, function(i, a) {
983 - familiesmainmenu += "<li><a href=\"javascript:initGroupGraphs('" + a.name + "');\">" + a.name + " <span class=\"badge pull-right\">" + a.count + "</span></a></li>";
984 - });
985 - familiesmainmenu += "</ul></li>";
986 -
987 - chartsmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-resize-full\"></span> All Charts <b class="caret"></b></a><ul class="dropdown-menu">';
988 - $.each(chartslist, function(i, a) {
989 - chartsmainmenu += "<li><a href=\"javascript:initMainChartIndexOfMyCharts('" + a.id + "');\">" + a.name + "</a></li>";
990 - });
991 - chartsmainmenu += "</ul></li>";
992 -
993 - mainmenu += categoriesmainmenu;
994 - mainmenu += familiesmainmenu;
995 - mainmenu += chartsmainmenu;
996 - mainmenu += "</ul>";
997 -
998 - thumbsContainer.innerHTML = allcategories;
999 - switchToThumbGraphs();
1000 - checkRefreshThread();
1001 - });
1002 -}
1003 -
1004 -$(window).blur(function() {
1005 - page_is_visible = 0;
1006 - mylog('blur');
1007 -});
1008 -
1009 -$(window).focus(function() {
1010 - page_is_visible = 1;
1011 - mylog('focus');
1012 -});
1013 -
1014 -// Set a callback to run when the Google Visualization API is loaded.
1015 -google.setOnLoadCallback(initCharts);
1 +var page_is_visible = 1;
2 +
3 +var TARGET_THUMB_GRAPH_WIDTH = 500; // thumb charts width will range from 0.5 to 1.5 of that
4 +var MINIMUM_THUMB_GRAPH_WIDTH = 400; // thumb chart will generally try to be wider than that
5 +var TARGET_THUMB_GRAPH_HEIGHT = 180; // the height of the thumb charts
6 +
7 +var THUMBS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
8 +var THUMBS_POINTS_DIVISOR = 4;
9 +var THUMBS_STACKED_POINTS_DIVISOR = 10;
10 +
11 +var GROUPS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
12 +var GROUPS_POINTS_DIVISOR = 4;
13 +var GROUPS_STACKED_POINTS_DIVISOR = 10;
14 +
15 +var MAINCHART_MAX_TIME_TO_SHOW = 600; // how much time the main chart will present by default?
16 +var MAINCHART_POINTS_DIVISOR = 10; // how much detailed will the main chart be by default? 1 = finest, higher is faster
17 +var MAINCHART_STACKED_POINTS_DIVISOR = 20; // how much detailed will the main chart be by default? 1 = finest, higher is faster
18 +
19 +var MAINCHART_CONTROL_HEIGHT = 75; // how tall the control chart will be
20 +var MAINCHART_CONTROL_DIVISOR = 2; // how much detailed will the control chart be? 1 = finest, higher is faster
21 +var MAINCHART_INITIAL_SELECTOR= 40; // 1/20th of the width, this overrides MAINCHART_MAX_TIME_TO_SHOW
22 +
23 +var CHARTS_REFRESH_IDLE = 100;
24 +var CHARTS_CHECK_NO_FOCUS = 500;
25 +
26 +var MODE_THUMBS = 1;
27 +var MODE_MAIN = 2;
28 +var MODE_GROUP_THUMBS = 3;
29 +var mode; // one of the MODE_* values
30 +
31 +var mycharts = new Array();
32 +var mainchart;
33 +
34 +// html for the main menu
35 +var mainmenu = "";
36 +var categoriesmainmenu = "";
37 +var familiesmainmenu = "";
38 +var chartsmainmenu = "";
39 +
40 +
41 +// ------------------------------------------------------------------------
42 +// common HTML generation
43 +
44 +function thumbChartActions(i, c, nogroup) {
45 + var name = c.name;
46 + if(!nogroup) name = c.family;
47 +
48 + var refinfo = "the chart is drawing ";
49 + if(c.group == 1) refinfo += "every single point collected (" + c.update_every + "s each).";
50 + else refinfo += ((c.group_method == "average")?"the average":"the max") + " value for every " + (c.group * c.update_every) + " seconds of data";
51 +
52 + var html = "<div class=\"btn-group btn-group\" data-toggle=\"tooltip\" title=\"" + refinfo + "\">"
53 + + "<button type=\"button\" class=\"btn btn-default\" onclick=\"javascript: return;\"><span class=\"glyphicon glyphicon-info-sign\"></span></button>"
54 + + "</div>"
55 + + "<div class=\"btn-group btn-group\"><button type=\"button\" class=\"btn btn-default disabled\"><small>&nbsp;&nbsp; " + name + "</small></button>";
56 +
57 + if(!nogroup) {
58 + var ingroup = 0;
59 + var ingroup_detail = 0;
60 +
61 + $.each(mycharts, function(i, d) {
62 + if(d.family == c.family) {
63 + ingroup++;
64 + if(d.isdetail) ingroup_detail++;
65 + }
66 + });
67 +
68 + var hidden = "";
69 + if(ingroup_detail) hidden = ", including " + ingroup_detail + " charts not shown now";
70 +
71 + html += "<button type=\"button\" data-toggle=\"tooltip\" title=\"Show all " + ingroup + " charts in group '" + c.family + "'" + hidden + "\" class=\"btn btn-default\" onclick=\"initGroupGraphs('" + c.family +"');\"><span class=\"glyphicon glyphicon-th-large\"></span></button>";
72 + }
73 +
74 + html += "<button type=\"button\" data-toggle=\"tooltip\" title=\"show chart '" + c.name + "' in fullscreen\" class=\"btn btn-default\" onclick=\"initMainChartIndex(" + i +");\"><span class=\"glyphicon glyphicon-resize-full\"></span></button>"
75 + + "<button type=\"button\" data-toggle=\"tooltip\" title=\"set options for chart '" + c.name + "'\" class=\"btn btn-default disabled\" onclick=\"alert('Not implemented yet!');\"><span class=\"glyphicon glyphicon-cog\"></span></button>"
76 + + "<button type=\"button\" data-toggle=\"tooltip\" title=\"ignore chart '" + c.name + "'\" class=\"btn btn-default\" onclick=\"disableChart(" + i + ");\"><span class=\"glyphicon glyphicon-trash\"></span></button>"
77 + + "</div>";
78 +
79 + return html;
80 +}
81 +
82 +function mylog(txt) {
83 + console.log(txt);
84 +}
85 +
86 +function chartssort(a, b) {
87 + if(a.priority == b.priority) {
88 + if(a.name < b.name) return -1;
89 + }
90 + else if(a.priority < b.priority) return -1;
91 +
92 + return 1;
93 +}
94 +
95 +
96 +// ------------------------------------------------------------------------
97 +// MAINGRAPH = fullscreen view of 1 graph
98 +
99 +// copy the chart c to mainchart
100 +// switch to main graphs screen
101 +function initMainChart(c) {
102 + if(mainchart) cleanThisChart(mainchart);
103 +
104 + mainchart = $.extend(true, {}, c);
105 + mainchart.enabled = true;
106 + mainchart.refreshCount = 0;
107 + mainchart.last_updated = 0;
108 + mainchart.chartOptions.explorer = null;
109 + mainchart.chart = null;
110 +
111 + mainchart.chartOptions.width = screenWidth();
112 + mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
113 + if(mainchart.chartOptions.height < 300) mainchart.chartOptions.height = 300;
114 +
115 + mainchart.div = 'maingraph';
116 + mainchart.time_to_show = (mainchart.last_entry_t - mainchart.first_entry_t) / MAINCHART_INITIAL_SELECTOR;
117 + if(mainchart.time_to_show < MAINCHART_INITIAL_SELECTOR) mainchart.time_to_show = MAINCHART_INITIAL_SELECTOR;
118 + calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, 0);
119 +
120 + // copy it to the hidden chart
121 + mainchart.hiddenchart = $.extend(true, {}, mainchart);
122 + mainchart.hiddenchart.chartOptions.height = MAINCHART_CONTROL_HEIGHT;
123 + mainchart.hiddenchart.div = 'maingraph_control';
124 + mainchart.hiddenchart.non_zero = 0;
125 +
126 + // initialize the div
127 + showChartIsLoading(mainchart.div, mainchart.name, mainchart.chartOptions.width, mainchart.chartOptions.height);
128 + document.getElementById(mainchart.hiddenchart.div).innerHTML = "<table><tr><td align=\"center\" width=\"" + mainchart.hiddenchart.chartOptions.width + "\" height=\"" + mainchart.hiddenchart.chartOptions.height + "\" style=\"vertical-align:middle\"><h4><span class=\"label label-default\">Please wait...</span></h4></td></tr></table>";
129 + //showChartIsLoading(mainchart.hiddenchart.div, mainchart.hiddenchart.name, mainchart.hiddenchart.chartOptions.width, mainchart.hiddenchart.chartOptions.height);
130 +
131 + // set the radio buttons
132 + setMainChartGroupMethod(mainchart.group_method, 'no-refresh');
133 + setMainChartMax('normal');
134 +
135 + $('#group' + mainchart.group).trigger('click');
136 + setMainChartGroup(mainchart.group, 'no-refresh');
137 +
138 + switchToMainGraph();
139 +}
140 +
141 +function refreshHiddenChart(doNext) {
142 + if(refresh_mode == REFRESH_PAUSED && mainchart.hiddenchart.last_updated != 0) {
143 + if(typeof doNext == "function") doNext();
144 + return;
145 + }
146 +
147 + // is it too soon for a refresh?
148 + var now = new Date().getTime();
149 + if((now - mainchart.hiddenchart.last_updated) < (mainchart.hiddenchart.group * mainchart.hiddenchart.update_every * 1000)) {
150 + if(typeof doNext == "function") doNext();
151 + return;
152 + }
153 +
154 + if(mainchart.dashboard && mainchart.hiddenchart.refreshCount > 50) {
155 + mainchart.dashboard.clear();
156 + mainchart.control_wrapper.clear();
157 + mainchart.hidden_wrapper.clear();
158 +
159 + mainchart.dashboard = null;
160 + mainchart.control_wrapper = null;
161 + mainchart.hidden_wrapper = null;
162 + mainchart.hiddenchart.last_updated = 0;
163 + }
164 +
165 + if(!mainchart.dashboard) {
166 + var controlopts = $.extend(true, {}, mainchart.chartOptions, {
167 + lineWidth: 1,
168 + height: mainchart.hiddenchart.chartOptions.height,
169 + chartArea: {'width': '98%'},
170 + hAxis: {'baselineColor': 'none', viewWindowMode: 'maximized'},
171 + vAxis: {'title': null},
172 + });
173 +
174 + mainchart.dashboard = new google.visualization.Dashboard(document.getElementById('maingraph_dashboard'));
175 + mainchart.control_wrapper = new google.visualization.ControlWrapper({
176 + controlType: 'ChartRangeFilter',
177 + containerId: 'maingraph_control',
178 + options: {
179 + filterColumnIndex: 0,
180 + ui: {
181 + chartType: mainchart.chartType,
182 + chartOptions: controlopts,
183 + minRangeSize: (MAINCHART_MAX_TIME_TO_SHOW * 1000) / MAINCHART_POINTS_DIVISOR,
184 + }
185 + },
186 + });
187 + mainchart.hidden_wrapper = new google.visualization.ChartWrapper({
188 + chartType: mainchart.chartType,
189 + containerId: 'maingraph_hidden',
190 + options: {
191 + isStacked: mainchart.chartOptions.isStacked,
192 + width: mainchart.hiddenchart.chartOptions.width,
193 + height: mainchart.hiddenchart.chartOptions.height,
194 + //chartArea: {'height': '80%', 'width': '100%'},
195 + //hAxis: {'slantedText': false},
196 + //legend: {'position': 'none'}
197 + },
198 + });
199 +
200 + mainchart.hiddenchart.refreshCount = 0;
201 + }
202 +
203 + // load the data for the control and the hidden wrappers
204 + // calculate the group and points to show for the control chart
205 + calculateChartPointsToShow(mainchart.hiddenchart, MAINCHART_CONTROL_DIVISOR, 0, -1);
206 +
207 + $.ajax({
208 + url: generateChartURL(mainchart.hiddenchart),
209 + dataType:"json",
210 + cache: false
211 + })
212 + .done(function(jsondata) {
213 + if(!jsondata || jsondata.length == 0) return;
214 +
215 + mainchart.control_data = new google.visualization.DataTable(jsondata);
216 +
217 + if(mainchart.hiddenchart.last_updated == 0) {
218 + google.visualization.events.addListener(mainchart.control_wrapper, 'ready', mainchartControlReadyEvent);
219 + mainchart.dashboard.bind(mainchart.control_wrapper, mainchart.hidden_wrapper);
220 + }
221 + if(refresh_mode != REFRESH_PAUSED) {
222 + mainchart.control_wrapper.setState({range: {
223 + start: new Date((Math.round(new Date().getTime() / 1000) - mainchart.hiddenchart.time_to_show) * 1000),
224 + end: new Date()
225 + }});
226 + }
227 +
228 + mainchart.dashboard.draw(mainchart.control_data);
229 + mainchart.hiddenchart.last_updated = new Date().getTime();
230 + mainchart.hiddenchart.refreshCount++;
231 + })
232 + .always(function() {
233 + if(typeof doNext == "function") doNext();
234 + });
235 +}
236 +
237 +function mainchartControlReadyEvent() {
238 + google.visualization.events.addListener(mainchart.control_wrapper, 'statechange', mainchartControlStateHandler);
239 + //mylog(mainchart);
240 +}
241 +
242 +function mainchartControlStateHandler() {
243 + // setMainChartPlay('pause');
244 +
245 + var state = mainchart.control_wrapper.getState();
246 + mainchart.after = Math.round(state.range.start.getTime() / 1000);
247 + mainchart.before = Math.round(state.range.end.getTime() / 1000);
248 +
249 + calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, 0);
250 + //mylog('group = ' + mainchart.group + ', points_to_show = ' + mainchart.points_to_show + ', dt = ' + (mainchart.before - mainchart.after));
251 +
252 + $('#group' + mainchart.group).trigger('click');
253 + mainchart.last_updated = 0;
254 +
255 + if(refresh_mode != REFRESH_PAUSED) pauseGraphs();
256 +}
257 +
258 +function initMainChartIndex(i) {
259 + if(mode == MODE_GROUP_THUMBS)
260 + initMainChart(group_charts[i]);
261 +
262 + else if(mode == MODE_THUMBS)
263 + initMainChart(mycharts[i]);
264 +
265 + else
266 + initMainChart(mycharts[i]);
267 +}
268 +
269 +function initMainChartIndexOfMyCharts(i) {
270 + initMainChart(mycharts[i]);
271 +}
272 +
273 +var last_main_chart_max='normal';
274 +function setMainChartMax(m) {
275 + if(!mainchart) return;
276 +
277 + if(m == 'toggle') {
278 + if(last_main_chart_max == 'maximized') m = 'normal';
279 + else m = 'maximized';
280 + }
281 +
282 + if(m == "maximized") {
283 + mainchart.chartOptions.theme = 'maximized';
284 + //mainchart.chartOptions.axisTitlesPosition = 'in';
285 + //mainchart.chartOptions.legend = {position: 'none'};
286 + mainchart.chartOptions.hAxis.title = null;
287 + mainchart.chartOptions.hAxis.viewWindowMode = 'maximized';
288 + mainchart.chartOptions.vAxis.viewWindowMode = 'maximized';
289 + mainchart.chartOptions.chartArea = {'width': '98%', 'height': '100%'};
290 + }
291 + else {
292 + mainchart.chartOptions.hAxis.title = null;
293 + mainchart.chartOptions.theme = null;
294 + mainchart.chartOptions.hAxis.viewWindowMode = null;
295 + mainchart.chartOptions.vAxis.viewWindowMode = null;
296 + mainchart.chartOptions.chartArea = {'width': '80%', 'height': '90%'};
297 + }
298 + $('.mainchart_max_button').button(m);
299 + last_main_chart_max = m;
300 + mainchart.last_updated = 0;
301 +}
302 +
303 +function setMainChartGroup(g, norefresh) {
304 + if(!mainchart) return;
305 +
306 + mainchart.group = g;
307 +
308 + if(!mainchart.before && !mainchart.after)
309 + calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, mainchart.group);
310 + else
311 + calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, mainchart.group);
312 +
313 + if(!norefresh) {
314 + mainchart.last_updated = 0;
315 + }
316 +}
317 +
318 +var last_main_chart_avg = null;
319 +function setMainChartGroupMethod(g, norefresh) {
320 + if(!mainchart) return;
321 +
322 + if(g == 'toggle') {
323 + if(last_main_chart_avg == 'max') g = 'average';
324 + else g = 'max';
325 + }
326 +
327 + mainchart.group_method = g;
328 +
329 + $('.mainchart_avg_button').button(g);
330 +
331 + if(!norefresh) {
332 + mainchart.last_updated = 0;
333 + }
334 +
335 + last_main_chart_avg = g;
336 +}
337 +
338 +function setMainChartPlay(p) {
339 + if(!mainchart) return;
340 +
341 + if(p == 'toggle') {
342 + if(refresh_mode != REFRESH_ALWAYS) p = 'play';
343 + else p = 'pause';
344 + }
345 +
346 + if(p == 'play') {
347 + //mainchart.chartOptions.explorer = null;
348 + mainchart.after = 0;
349 + mainchart.before = 0;
350 + calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.time_to_show, 0);
351 + $('#group' + mainchart.group).trigger('click');
352 + mainchart.last_updated = 0;
353 + mainchart.hiddenchart.last_updated = 0;
354 + playGraphs();
355 + }
356 + else {
357 + //mainchart.chartOptions.explorer = {
358 + // 'axis': 'horizontal',
359 + // 'maxZoomOut': 1,
360 + //};
361 + //mainchart.last_updated = 0;
362 +
363 + //if(!refreshChart(mainchart, pauseGraphs))
364 + pauseGraphs();
365 + }
366 +}
367 +
368 +
369 +// ------------------------------------------------------------------------
370 +// Chart resizing
371 +
372 +function screenWidth() {
373 + return (($(window).width() * 0.95) - 50);
374 +}
375 +
376 +// calculate the proper width for the thumb charts
377 +function thumbWidth() {
378 + var cwidth = screenWidth();
379 + var items = Math.round(cwidth / TARGET_THUMB_GRAPH_WIDTH);
380 + if(items < 1) items = 1;
381 +
382 + if(items > 1 && (cwidth / items) < MINIMUM_THUMB_GRAPH_WIDTH) items--;
383 +
384 + return Math.round(cwidth / items) - 1;
385 +}
386 +
387 +function groupChartSizes() {
388 + var s = { width: screenWidth() / 2, height: ($(window).height() - 130) / 3 - 10};
389 + if(s.width < MINIMUM_THUMB_GRAPH_WIDTH * 1.5) s.width = screenWidth();
390 +
391 + var count = 0;
392 + if(group_charts) $.each(group_charts, function(i, c) {
393 + if(c.enabled) count++;
394 + });
395 +
396 + if(count == 0) {
397 + s.width = TARGET_THUMB_GRAPH_WIDTH;
398 + s.height = TARGET_THUMB_GRAPH_HEIGHT;
399 + }
400 + if(count < 4) {
401 + s.width = screenWidth();
402 + s.height = ($(window).height() - 130) / count - 10;
403 + }
404 + else if(count == 4) {
405 + s.height = ($(window).height() - 130) / 2 - 10;
406 + }
407 +
408 + if(s.height < TARGET_THUMB_GRAPH_HEIGHT * 1.5)
409 + s.height = TARGET_THUMB_GRAPH_HEIGHT * 1.5;
410 +
411 + return s;
412 +}
413 +
414 +// resize all charts
415 +// if the thumb charts need resize in their width, reset them
416 +function resizeCharts() {
417 + var width = screenWidth();
418 +
419 + if(mainchart) {
420 + mainchart.chartOptions.width = width;
421 + mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
422 + mainchart.last_updated = 0;
423 +
424 + mainchart.hidden_wrapper.setOption('width', width);
425 + mainchart.control_wrapper.setOption('ui.chartOptions.width', width);
426 + mainchart.hiddenchart.chartOptions.width = width;
427 + mainchart.hiddenchart.last_updated = 0;
428 + }
429 +
430 + width = thumbWidth();
431 + $.each(mycharts, function(i, c) {
432 + if(c.enabled && c.chartOptions.width != width) {
433 + cleanThisChart(c);
434 + c.chartOptions.width = width;
435 + calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
436 + showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
437 + c.last_updated = 0;
438 + }
439 + });
440 +
441 + if(group_charts) $.each(group_charts, function(i, c) {
442 + var sizes = groupChartSizes();
443 +
444 + if(c.enabled && (c.chartOptions.width != sizes.width || c.chartOptions.height != sizes.height)) {
445 + cleanThisChart(c);
446 + c.chartOptions.width = sizes.width;
447 + c.chartOptions.height = sizes.height;
448 + calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
449 + showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
450 + c.last_updated = 0;
451 + }
452 + });
453 +}
454 +
455 +var resize_request = false;
456 +window.onresize = function(event) {
457 + resize_request = true;
458 +};
459 +
460 +
461 +// ------------------------------------------------------------------------
462 +// Core of the thread refreshing the charts
463 +
464 +var REFRESH_PAUSED = 0;
465 +var REFRESH_ALWAYS = 1;
466 +
467 +var refresh_mode = REFRESH_PAUSED;
468 +var last_refresh = 0;
469 +function playGraphs() {
470 + if(refresh_mode == REFRESH_ALWAYS) return;
471 +
472 + //mylog('PlayGraphs()');
473 + refresh_mode = REFRESH_ALWAYS;
474 + $('.mainchart_play_button').button('play');
475 +
476 + // check if the thread died due to a javascript error
477 + var now = new Date().getTime();
478 + if((now - last_refresh) > 5000) {
479 + // it died or never started
480 + //mylog('It seems the refresh thread died. Restarting it.');
481 + chartsRefresh();
482 + }
483 +}
484 +
485 +function pauseGraphs() {
486 + if(refresh_mode == REFRESH_PAUSED) return;
487 +
488 + //mylog('PauseGraphs()');
489 + refresh_mode = REFRESH_PAUSED;
490 + $('.mainchart_play_button').button('pause');
491 +}
492 +
493 +var interval = null;
494 +function checkRefreshThread() {
495 + if(interval == null) {
496 + interval = setInterval(checkRefreshThread, 2000);
497 + return;
498 + }
499 +
500 + var now = new Date().getTime();
501 + if(now - last_refresh > 10000) {
502 + mylog('Refresh thread died. Restarting it.');
503 + chartsRefresh();
504 + }
505 +}
506 +
507 +// refresh the proper chart
508 +// this is an internal function.
509 +// never call it directly, or new javascript threads will be spawn
510 +var timeout = null;
511 +function chartsRefresh() {
512 + last_refresh = new Date().getTime();
513 +
514 + if(!page_is_visible) {
515 + timeout = setTimeout(triggerRefresh, CHARTS_CHECK_NO_FOCUS);
516 + return;
517 + }
518 +
519 + if(resize_request) {
520 + resizeCharts();
521 + resize_request = false;
522 + // refresh_mode = REFRESH_ALWAYS;
523 + }
524 +
525 + if(refresh_mode == REFRESH_PAUSED) {
526 + if(mode == MODE_MAIN && mainchart.last_updated == 0) {
527 + mainChartRefresh();
528 + return;
529 + }
530 + }
531 +
532 + if(mode == MODE_THUMBS) thumbChartsRefresh();
533 + else if(mode == MODE_GROUP_THUMBS) groupChartsRefresh();
534 + else if(mode == MODE_MAIN) mainChartRefresh();
535 + else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
536 +}
537 +
538 +// callback for refreshing the charts later
539 +// this is an internal function.
540 +// never call it directly, or new javascript threads will be spawn
541 +function triggerRefresh() {
542 + //mylog('triggerRefresh()');
543 +
544 + // cleanup has to take place when the charts are not refreshed
545 + // since the refreshing thread is in this function, it means
546 + // nothing is being refreshed.
547 + cleanupCharts();
548 +
549 + if(mode == MODE_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
550 + else if(mode == MODE_GROUP_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
551 + else if(mode == MODE_MAIN) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
552 + else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
553 +}
554 +
555 +// refresh the main chart
556 +// make sure we don't loose the refreshing thread
557 +function mainChartRefresh() {
558 + //mylog('mainChartRefresh()');
559 +
560 + if(mode != MODE_MAIN || !mainchart) {
561 + triggerRefresh();
562 + return;
563 + }
564 +
565 + if(refresh_mode == REFRESH_PAUSED && mainchart.last_updated != 0) {
566 + hiddenChartRefresh();
567 + return;
568 + }
569 +
570 + if(!refreshChart(mainchart, hiddenChartRefresh))
571 + hiddenChartRefresh();
572 +}
573 +
574 +function hiddenChartRefresh() {
575 + refreshHiddenChart(triggerRefresh);
576 +}
577 +
578 +function roundRobinRefresh(charts, startat) {
579 + var refreshed = false;
580 +
581 + // find a chart to refresh
582 + var all = charts.length;
583 + var cur = startat;
584 + var count = 0;
585 +
586 + for(count = 0; count < all ; count++, cur++) {
587 + if(cur >= all) cur = 0;
588 +
589 + if(charts[cur].enabled) {
590 + //mylog('going to refresh chart ' + charts[cur].name);
591 + refreshed = refreshChart(charts[cur], chartsRefresh);
592 + if(refreshed) break;
593 + }
594 + }
595 +
596 + if(!refreshed) triggerRefresh();
597 + return cur;
598 +}
599 +
600 +// refresh the thumb charts
601 +// make sure we don't loose the refreshing thread
602 +var last_thumb_updated = 0;
603 +function thumbChartsRefresh() {
604 + //mylog('thumbChartsRefresh()');
605 +
606 + if(mycharts.length == 0 || mode != MODE_THUMBS) {
607 + triggerRefresh();
608 + return;
609 + }
610 +
611 + last_thumb_updated = roundRobinRefresh(mycharts, last_thumb_updated);
612 +}
613 +
614 +// refresh the group charts
615 +// make sure we don't loose the refreshing thread
616 +var last_group_updated = 0;
617 +function groupChartsRefresh() {
618 + //mylog('groupChartsRefresh()');
619 +
620 + if(!group_charts || group_charts.length == 0 || mode != MODE_GROUP_THUMBS) {
621 + //mylog('cannot refresh charts');
622 + triggerRefresh();
623 + return;
624 + }
625 +
626 + last_group_updated = roundRobinRefresh(group_charts, last_group_updated);
627 +}
628 +
629 +
630 +// ------------------------------------------------------------------------
631 +// switch the screen between views
632 +// these should be called only from initXXXX()
633 +
634 +function disableChart(i) {
635 + //mylog('disableChart(' + i + ')');
636 +
637 + var chart = null;
638 +
639 + var count = 0;
640 + if(mode == MODE_GROUP_THUMBS && group_charts) {
641 + $.each(group_charts, function(i, c) {
642 + if(c.enabled) count++;
643 + });
644 +
645 + if(i < group_charts.length) chart = group_charts[i];
646 + }
647 + else if(mode == MODE_THUMBS) {
648 + $.each(mycharts, function(i, c) {
649 + if(c.enabled) count++;
650 + });
651 +
652 + if(i < mycharts.length) chart = mycharts[i];
653 + }
654 +
655 + if(!chart) return;
656 +
657 + if(count <= 1) {
658 + alert('Cannot close the last chart shown.');
659 + return;
660 + }
661 +
662 + if(chart) {
663 + //mylog("disabling chart " + chart.name);
664 + chart.disablethisplease = true;
665 + }
666 +}
667 +
668 +function cleanThisChart(chart, emptydivs) {
669 + //mylog('cleanThisChart(' + chart.name + ', ' + emptydivs +')');
670 +
671 + if(chart.dashboard) {
672 + chart.dashboard.clear();
673 + chart.dashboard = null;
674 +
675 + if(chart.control_wrapper) {
676 + chart.control_wrapper.clear();
677 + chart.control_wrapper = null;
678 + }
679 +
680 + if(chart.hidden_wrapper) {
681 + chart.hidden_wrapper.clear();
682 + chart.hidden_wrapper = null;
683 + }
684 +
685 + chart.control_data = null;
686 + }
687 +
688 + if(chart.chart) chart.chart.clearChart();
689 + chart.chart = null;
690 +
691 + if(emptydivs) {
692 + var div = document.getElementById(chart.div);
693 + if(div) {
694 + div.style.display = 'none';
695 + div.innerHTML = "";
696 + }
697 +
698 + div = document.getElementById(chart.div + "_parent");
699 + if(div) {
700 + div.style.display = 'none';
701 + div.innerHTML = "";
702 + }
703 + }
704 +
705 + //mylog("chart " + chart.name + " cleaned with option " + emptydivs);
706 +}
707 +
708 +// cleanup the previously shown charts
709 +function cleanupCharts() {
710 + //mylog('cleanupCharts()');
711 +
712 + if(mode != MODE_MAIN && mainchart) {
713 + if(mainchart.chart) cleanThisChart(mainchart);
714 + mainchart = null;
715 + }
716 +
717 + if(mode != MODE_GROUP_THUMBS && group_charts) {
718 + clearGroupGraphs();
719 + }
720 +
721 + // cleanup the disabled charts
722 + $.each(mycharts, function(i, c) {
723 + if(c.disablethisplease && c.enabled) {
724 + cleanThisChart(c, 'emptydivs');
725 + c.disablethisplease = false;
726 + c.enabled = false;
727 + resize_request = true;
728 + //mylog("disabled chart " + c.name + " removed");
729 + }
730 + });
731 +
732 + if(group_charts) $.each(group_charts, function(i, c) {
733 + if(c.disablethisplease && c.enabled) {
734 + cleanThisChart(c, 'emptydivs');
735 + c.disablethisplease = false;
736 + c.enabled = false;
737 + resize_request = true;
738 + //mylog("disabled chart " + c.name + " removed");
739 + }
740 + });
741 +
742 + // we never cleanup the thumb charts
743 +}
744 +
745 +function updateUI() {
746 + $('[data-toggle="tooltip"]').tooltip({'placement': 'top', 'container': 'body', 'html': true});
747 +
748 + $('[data-spy="scroll"]').each(function () {
749 + var $spy = $(this).scrollspy('refresh')
750 + })
751 +}
752 +
753 +var thumbsScrollPosition = null;
754 +function switchToMainGraph() {
755 + //mylog('switchToMainGraph()');
756 +
757 + if(!mainchart) return;
758 +
759 + if(!group_charts) thumbsScrollPosition = window.pageYOffset;
760 +
761 + document.getElementById('maingraph_container').style.display = 'block';
762 + document.getElementById('thumbgraphs_container').style.display = 'none';
763 + document.getElementById('groupgraphs_container').style.display = 'none';
764 +
765 + document.getElementById("main_menu_div").innerHTML = "<ul class=\"nav navbar-nav\"><li><a href=\"javascript:switchToThumbGraphs();\"><span class=\"glyphicon glyphicon-circle-arrow-left\"></span> Back to Dashboard</a></li><li class=\"active\"><a href=\"#\">" + mainchart.name + "</a></li>" + familiesmainmenu + chartsmainmenu + "</ul>";
766 +
767 + window.scrollTo(0, 0);
768 +
769 + mode = MODE_MAIN;
770 + playGraphs();
771 + updateUI();
772 +}
773 +
774 +function switchToThumbGraphs() {
775 + //mylog('switchToThumbGraphs()');
776 +
777 + document.getElementById('maingraph_container').style.display = 'none';
778 + document.getElementById('thumbgraphs_container').style.display = 'block';
779 + document.getElementById('groupgraphs_container').style.display = 'none';
780 +
781 + document.getElementById("main_menu_div").innerHTML = mainmenu;
782 +
783 + if(thumbsScrollPosition) window.scrollTo(0, thumbsScrollPosition);
784 +
785 + // switch mode
786 + mode = MODE_THUMBS;
787 + playGraphs();
788 + updateUI();
789 +}
790 +
791 +function switchToGroupGraphs() {
792 + //mylog('switchToGroupGraphs()');
793 +
794 + if(!group_charts) return;
795 +
796 + if(!mainchart) thumbsScrollPosition = window.pageYOffset;
797 +
798 + document.getElementById('maingraph_container').style.display = 'none';
799 + document.getElementById('thumbgraphs_container').style.display = 'none';
800 + document.getElementById('groupgraphs_container').style.display = 'block';
801 +
802 + document.getElementById("main_menu_div").innerHTML = "<ul class=\"nav navbar-nav\"><li><a href=\"javascript:switchToThumbGraphs();\"><span class=\"glyphicon glyphicon-circle-arrow-left\"></span> Back to Dashboard</a></li><li class=\"active\"><a href=\"#\">" + group_charts[0].family + "</a></li>" + familiesmainmenu + chartsmainmenu + "</ul>";
803 +
804 + window.scrollTo(0, 0);
805 +
806 + mode = MODE_GROUP_THUMBS;
807 + playGraphs();
808 + updateUI();
809 +}
810 +
811 +
812 +// ------------------------------------------------------------------------
813 +// Group Charts
814 +
815 +var group_charts = null;
816 +function initGroupGraphs(group) {
817 + var count = 0;
818 +
819 + if(group_charts) clearGroupGraphs();
820 + group_charts = new Array();
821 +
822 + var groupbody = "";
823 + $.each(mycharts, function(i, c) {
824 + if(c.family == group) {
825 + group_charts[count] = [];
826 + group_charts[count] = $.extend(true, {}, c);
827 + group_charts[count].div += "_group";
828 + group_charts[count].enabled = true;
829 + group_charts[count].chart = null;
830 + group_charts[count].last_updated = 0;
831 + count++;
832 + }
833 + });
834 + group_charts.sort(chartssort);
835 +
836 + var sizes = groupChartSizes();
837 +
838 + var groupbody = "";
839 + $.each(group_charts, function(i, c) {
840 + c.chartOptions.width = sizes.width;
841 + c.chartOptions.height = sizes.height;
842 +
843 + calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
844 +
845 + groupbody += "<div class=\"thumbgraph\" id=\"" + c.div + "_parent\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.name, c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\">" + thumbChartActions(i, c, 'nogroup') + "</td></tr><tr><td height='15'></td></tr></table></div>";
846 + });
847 + groupbody += "";
848 +
849 + document.getElementById("groupgraphs").innerHTML = groupbody;
850 + switchToGroupGraphs();
851 +}
852 +
853 +function clearGroupGraphs() {
854 + if(group_charts && group_charts.length) {
855 + $.each(group_charts, function(i, c) {
856 + cleanThisChart(c, 'emptydivs');
857 + });
858 +
859 + group_charts = null;
860 + }
861 +
862 + document.getElementById("groupgraphs").innerHTML = "";
863 +}
864 +
865 +
866 +// ------------------------------------------------------------------------
867 +// Global entry point
868 +// initialize the thumb charts
869 +
870 +// load the charts from the server
871 +// generate html for the thumbgraphs to support them
872 +function initCharts() {
873 + var width = thumbWidth();
874 + var height = TARGET_THUMB_GRAPH_HEIGHT;
875 +
876 + loadCharts(null, function(all) {
877 + mycharts = all.charts;
878 +
879 + if(mycharts == null || mycharts.length == 0) {
880 + alert("Cannot load data from server.");
881 + return;
882 + }
883 +
884 + var thumbsContainer = document.getElementById("thumbgraphs");
885 + if(!thumbsContainer) {
886 + alert("Cannot find the thumbsContainer");
887 + return;
888 + }
889 +
890 + mycharts.sort(chartssort);
891 +
892 + document.getElementById('hostname_id').innerHTML = all.hostname;
893 + document.title = all.hostname;
894 +
895 + // create an array for grouping all same-type graphs together
896 + var dimensions = 0;
897 + var categories = new Array();
898 + var families = new Array();
899 + var chartslist = new Array();
900 + $.each(mycharts, function(i, c) {
901 + var j;
902 +
903 + chartslist.push({name: c.name, type: c.type, id: i});
904 +
905 + dimensions += c.dimensions.length;
906 + c.chartOptions.width = width;
907 + c.chartOptions.height = height;
908 +
909 + // calculate how many point to show for each chart
910 + //c.points_to_show = Math.round(c.entries / c.group) - 1;
911 + // show max 10 mins of data
912 + //if(c.points_to_show * c.group > THUMBS_MAX_TIME_TO_SHOW) c.points_to_show = THUMBS_MAX_TIME_TO_SHOW / c.group;
913 + calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
914 +
915 + if(c.enabled) {
916 + var h = "<div class=\"thumbgraph\" id=\"" + c.div + "_parent\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.name, c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\">"
917 + + thumbChartActions(i, c)
918 + + "</td></tr><tr><td height='15'></td></tr></table></div>";
919 +
920 + // find the categories object for this type
921 + for(j = 0; j < categories.length ;j++) {
922 + if(categories[j].name == c.type) {
923 + categories[j].html += h;
924 + categories[j].count++;
925 + break;
926 + }
927 + }
928 +
929 + if(j == categories.length)
930 + categories.push({name: c.type, title: c.category, description: '', priority: c.categoryPriority, count: 1, glyphicon: c.glyphicon, html: h});
931 + }
932 +
933 + // find the families object for this type
934 + for(j = 0; j < families.length ;j++) {
935 + if(families[j].name == c.family) {
936 + families[j].count++;
937 + break;
938 + }
939 + }
940 +
941 + if(j == families.length)
942 + families.push({name: c.family, count: 1});
943 + });
944 +
945 + document.getElementById('server_summary_id').innerHTML = "<small>NetData server at <b>" + all.hostname + "</b> is maintaining <b>" + mycharts.length + "</b> charts, having <b>" + dimensions + "</b> dimensions (by default with <b>" + all.history + "</b> entries each), which are updated every <b>" + all.update_every + "s</b>, using a total of <b>" + (Math.round(all.memory * 10 / 1024 / 1024) / 10) + " MB</b> for the round robin database.</small>";
946 +
947 + $.each(categories, function(i, a) {
948 + a.html = "<tr><td id=\"" + a.name + "\"><ol class=\"breadcrumb graphs\"><li class=\"active\"><span class=\"glyphicon " + a.glyphicon + "\"></span> &nbsp; <a id=\"" + a.name + "\" href=\"#" + a.name + "\"><b>" + a.title + "</b> " + a.description + " </a></li></ol></td></tr><tr><td><div class=\"thumbgraphs\">" + a.html + "</td></tr>";
949 + });
950 +
951 + function categoriessort(a, b) {
952 + if(a.priority < b.priority) return -1;
953 + return 1;
954 + }
955 + categories.sort(categoriessort);
956 +
957 + function familiessort(a, b) {
958 + if(a.name < b.name) return -1;
959 + return 1;
960 + }
961 + families.sort(familiessort);
962 +
963 + function chartslistsort(a, b) {
964 + if(a.name < b.name) return -1;
965 + return 1;
966 + }
967 + chartslist.sort(chartslistsort);
968 +
969 + // combine all the htmls into one
970 + var allcategories = "<table width=\"100%\">";
971 + mainmenu = '<ul class="nav navbar-nav">';
972 +
973 + categoriesmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-fire\"></span> Dashboard Sections <b class="caret"></b></a><ul class="dropdown-menu">';
974 + $.each(categories, function(i, a) {
975 + allcategories += a.html;
976 + categoriesmainmenu += "<li><a href=\"#" + a.name + "\">" + a.title + "</a></li>";
977 + });
978 + categoriesmainmenu += "</ul></li>";
979 + allcategories += "</table>";
980 +
981 + familiesmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-th-large\"></span> Chart Families <b class="caret"></b></a><ul class="dropdown-menu">';
982 + $.each(families, function(i, a) {
983 + familiesmainmenu += "<li><a href=\"javascript:initGroupGraphs('" + a.name + "');\">" + a.name + " <span class=\"badge pull-right\">" + a.count + "</span></a></li>";
984 + });
985 + familiesmainmenu += "</ul></li>";
986 +
987 + chartsmainmenu = '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class=\"glyphicon glyphicon-resize-full\"></span> All Charts <b class="caret"></b></a><ul class="dropdown-menu">';
988 + $.each(chartslist, function(i, a) {
989 + chartsmainmenu += "<li><a href=\"javascript:initMainChartIndexOfMyCharts('" + a.id + "');\">" + a.name + "</a></li>";
990 + });
991 + chartsmainmenu += "</ul></li>";
992 +
993 + mainmenu += categoriesmainmenu;
994 + mainmenu += familiesmainmenu;
995 + mainmenu += chartsmainmenu;
996 + mainmenu += "</ul>";
997 +
998 + thumbsContainer.innerHTML = allcategories;
999 + switchToThumbGraphs();
1000 + checkRefreshThread();
1001 + });
1002 +}
1003 +
1004 +$(window).blur(function() {
1005 + page_is_visible = 0;
1006 + mylog('blur');
1007 +});
1008 +
1009 +$(window).focus(function() {
1010 + page_is_visible = 1;
1011 + mylog('focus');
1012 +});
1013 +
1014 +// Set a callback to run when the Google Visualization API is loaded.
1015 +google.setOnLoadCallback(initCharts);