1 var page_is_visible = 1;
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
7 var THUMBS_MAX_TIME_TO_SHOW = 240; // how much time the thumb charts will present?
8 var THUMBS_POINTS_DIVISOR = 3;
9 var THUMBS_STACKED_POINTS_DIVISOR = 3;
11 var GROUPS_MAX_TIME_TO_SHOW = 120; // how much time the group charts will present?
12 var GROUPS_POINTS_DIVISOR = 2;
13 var GROUPS_STACKED_POINTS_DIVISOR = 2;
15 var MAINCHART_MIN_TIME_TO_SHOW = 600; // how much time the main chart will present by default?
16 var MAINCHART_POINTS_DIVISOR = 5; // how much detailed will the main chart be by default? 1 = finest, higher is faster
17 var MAINCHART_STACKED_POINTS_DIVISOR = 10; // how much detailed will the main chart be by default? 1 = finest, higher is faster
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= 20; // 1/20th of the width, this overrides MAINCHART_MIN_TIME_TO_SHOW
23 var CHARTS_REFRESH_LOOP = 50; // delay between chart refreshes
24 var CHARTS_REFRESH_IDLE = 500; // delay between chart refreshes when no chart was ready for refresh the last time
25 var CHARTS_CHECK_NO_FOCUS = 500; // delay to check for visibility when the page has no focus
26 var CHARTS_SCROLL_IDLE = 100; // delay to wait after a page scroll
30 userAgent = navigator.userAgent;
31 return userAgent.indexOf("MSIE ") > -1 || userAgent.indexOf("Trident/") > -1;
35 // do stuff with ie-users
36 CHARTS_REFRESH_LOOP=250;
37 CHARTS_SCROLL_IDLE=500;
42 var MODE_GROUP_THUMBS = 3;
43 var mode; // one of the MODE_* values
45 var mycharts = new Array();
48 // html for the main menu
50 var categoriesmainmenu = "";
51 var familiesmainmenu = "";
52 var chartsmainmenu = "";
55 // ------------------------------------------------------------------------
56 // common HTML generation
58 function thumbChartActions(i, c, nogroup) {
60 if(!nogroup) name = c.family;
62 var refinfo = "the chart is drawing ";
63 if(c.group == 1) refinfo += "every single point collected (" + c.update_every + "s each).";
64 else refinfo += ((c.group_method == "average")?"the average":"the max") + " value for every " + (c.group * c.update_every) + " seconds of data";
66 var html = "<div class=\"btn-group btn-group\" data-toggle=\"tooltip\" title=\"" + refinfo + "\">"
67 + "<button type=\"button\" class=\"btn btn-default\" onclick=\"javascript: return;\"><span class=\"glyphicon glyphicon-info-sign\"></span></button>"
69 + "<div class=\"btn-group btn-group\"><button type=\"button\" class=\"btn btn-default disabled\"><small> " + name + "</small></button>";
73 var ingroup_detail = 0;
75 $.each(mycharts, function(i, d) {
76 if(d.family == c.family) {
78 if(d.isdetail) ingroup_detail++;
83 if(ingroup_detail) hidden = ", including " + ingroup_detail + " charts not shown now";
85 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>";
88 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>"
89 + "<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>"
90 + "<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>"
98 $('#logline').html(txt);
101 function chartssort(a, b) {
102 if(a.priority == b.priority) {
103 if(a.name < b.name) return -1;
105 else if(a.priority < b.priority) return -1;
111 // ------------------------------------------------------------------------
112 // MAINGRAPH = fullscreen view of 1 graph
114 // copy the chart c to mainchart
115 // switch to main graphs screen
116 function initMainChart(c) {
117 if(mainchart) cleanThisChart(mainchart);
119 mainchart = $.extend(true, {}, c);
120 mainchart.enabled = true;
121 mainchart.refreshCount = 0;
122 mainchart.last_updated = 0;
123 mainchart.chartOptions.explorer = null;
124 mainchart.chart = null;
126 mainchart.before = 0;
129 mainchart.chartOptions.width = screenWidth();
130 mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
131 if(mainchart.chartOptions.height < 300) mainchart.chartOptions.height = 300;
133 mainchart.div = 'maingraph';
134 mainchart.max_time_to_show = (mainchart.last_entry_t - mainchart.first_entry_t) / MAINCHART_INITIAL_SELECTOR;
135 if(mainchart.max_time_to_show < MAINCHART_MIN_TIME_TO_SHOW) mainchart.max_time_to_show = MAINCHART_MIN_TIME_TO_SHOW;
136 calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.max_time_to_show, 0);
138 // copy it to the hidden chart
139 mainchart.hiddenchart = $.extend(true, {}, mainchart);
140 mainchart.hiddenchart.chartOptions.height = MAINCHART_CONTROL_HEIGHT;
141 mainchart.hiddenchart.div = 'maingraph_control';
142 mainchart.hiddenchart.non_zero = 0;
144 // initialize the div
145 showChartIsLoading(mainchart.div, mainchart.name, mainchart.chartOptions.width, mainchart.chartOptions.height);
146 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>";
147 //showChartIsLoading(mainchart.hiddenchart.div, mainchart.hiddenchart.name, mainchart.hiddenchart.chartOptions.width, mainchart.hiddenchart.chartOptions.height);
149 // set the radio buttons
150 setMainChartGroupMethod(mainchart.group_method, 'no-refresh');
151 setMainChartMax('normal');
153 $('#group' + mainchart.group).trigger('click');
154 setMainChartGroup(mainchart.group, 'no-refresh');
159 function refreshHiddenChart(doNext) {
160 if(refresh_mode == REFRESH_PAUSED && mainchart.hiddenchart.last_updated != 0) {
161 if(typeof doNext == "function") doNext();
165 // is it too soon for a refresh?
166 var now = new Date().getTime();
167 if((now - mainchart.hiddenchart.last_updated) < (mainchart.update_every * 10 * 1000) || (now - mainchart.hiddenchart.last_updated) < (mainchart.hiddenchart.group * mainchart.hiddenchart.update_every * 1000)) {
168 if(typeof doNext == "function") doNext();
172 if(mainchart.dashboard && mainchart.hiddenchart.refreshCount > 50) {
173 mainchart.dashboard.clear();
174 mainchart.control_wrapper.clear();
175 mainchart.hidden_wrapper.clear();
177 mainchart.dashboard = null;
178 mainchart.control_wrapper = null;
179 mainchart.hidden_wrapper = null;
180 mainchart.hiddenchart.last_updated = 0;
183 if(!mainchart.dashboard) {
184 var controlopts = $.extend(true, {}, mainchart.chartOptions, {
186 height: mainchart.hiddenchart.chartOptions.height,
187 chartArea: {'width': '98%'},
188 hAxis: {'baselineColor': 'none', viewWindowMode: 'maximized'},
189 vAxis: {'title': null},
192 mainchart.dashboard = new google.visualization.Dashboard(document.getElementById('maingraph_dashboard'));
193 mainchart.control_wrapper = new google.visualization.ControlWrapper({
194 controlType: 'ChartRangeFilter',
195 containerId: 'maingraph_control',
197 filterColumnIndex: 0,
199 chartType: mainchart.chartType,
200 chartOptions: controlopts,
201 minRangeSize: (mainchart.max_time_to_show * 1000) / MAINCHART_POINTS_DIVISOR,
205 mainchart.hidden_wrapper = new google.visualization.ChartWrapper({
206 chartType: mainchart.chartType,
207 containerId: 'maingraph_hidden',
209 isStacked: mainchart.chartOptions.isStacked,
210 width: mainchart.hiddenchart.chartOptions.width,
211 height: mainchart.hiddenchart.chartOptions.height,
212 //chartArea: {'height': '80%', 'width': '100%'},
213 //hAxis: {'slantedText': false},
214 //legend: {'position': 'none'}
218 mainchart.hiddenchart.refreshCount = 0;
221 // load the data for the control and the hidden wrappers
222 // calculate the group and points to show for the control chart
223 calculateChartPointsToShow(mainchart.hiddenchart, MAINCHART_CONTROL_DIVISOR, 0, -1);
226 url: generateChartURL(mainchart.hiddenchart),
230 .done(function(jsondata) {
231 if(!jsondata || jsondata.length == 0) return;
233 mainchart.control_data = new google.visualization.DataTable(jsondata);
235 if(mainchart.hiddenchart.last_updated == 0) {
236 google.visualization.events.addListener(mainchart.control_wrapper, 'ready', mainchartControlReadyEvent);
237 mainchart.dashboard.bind(mainchart.control_wrapper, mainchart.hidden_wrapper);
239 if(refresh_mode != REFRESH_PAUSED) {
240 // console.log('mainchart.points_to_show: ' + mainchart.points_to_show + ', mainchart.group: ' + mainchart.group + ', mainchart.update_every: ' + mainchart.update_every);
242 var start = now - (mainchart.points_to_show * mainchart.group * mainchart.update_every * 1000);
244 var min = MAINCHART_MIN_TIME_TO_SHOW * 1000;
245 if(end - start < min) start = end - min;
247 mainchart.control_wrapper.setState({range: {
248 start: new Date(start),
256 mainchart.dashboard.draw(mainchart.control_data);
257 mainchart.hiddenchart.last_updated = new Date().getTime();
258 mainchart.hiddenchart.refreshCount++;
261 if(typeof doNext == "function") doNext();
265 function mainchartControlReadyEvent() {
266 google.visualization.events.addListener(mainchart.control_wrapper, 'statechange', mainchartControlStateHandler);
270 function mainchartControlStateHandler() {
271 // setMainChartPlay('pause');
273 var state = mainchart.control_wrapper.getState();
274 mainchart.after = Math.round(state.range.start.getTime() / 1000);
275 mainchart.before = Math.round(state.range.end.getTime() / 1000);
277 calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, 0);
278 //mylog('group = ' + mainchart.group + ', points_to_show = ' + mainchart.points_to_show + ', dt = ' + (mainchart.before - mainchart.after));
280 $('#group' + mainchart.group).trigger('click');
281 mainchart.last_updated = 0;
283 if(refresh_mode != REFRESH_PAUSED) pauseGraphs();
286 function initMainChartIndex(i) {
287 if(mode == MODE_GROUP_THUMBS)
288 initMainChart(group_charts[i]);
290 else if(mode == MODE_THUMBS)
291 initMainChart(mycharts[i]);
294 initMainChart(mycharts[i]);
297 function initMainChartIndexOfMyCharts(i) {
298 initMainChart(mycharts[i]);
301 var last_main_chart_max='normal';
302 function setMainChartMax(m) {
303 if(!mainchart) return;
306 if(last_main_chart_max == 'maximized') m = 'normal';
307 else m = 'maximized';
310 if(m == "maximized") {
311 mainchart.chartOptions.theme = 'maximized';
312 //mainchart.chartOptions.axisTitlesPosition = 'in';
313 //mainchart.chartOptions.legend = {position: 'none'};
314 mainchart.chartOptions.hAxis.title = null;
315 mainchart.chartOptions.hAxis.viewWindowMode = 'maximized';
316 mainchart.chartOptions.vAxis.viewWindowMode = 'maximized';
317 mainchart.chartOptions.chartArea = {'width': '98%', 'height': '100%'};
320 mainchart.chartOptions.hAxis.title = null;
321 mainchart.chartOptions.theme = null;
322 mainchart.chartOptions.hAxis.viewWindowMode = null;
323 mainchart.chartOptions.vAxis.viewWindowMode = null;
324 mainchart.chartOptions.chartArea = {'width': '80%', 'height': '90%'};
326 $('.mainchart_max_button').button(m);
327 last_main_chart_max = m;
328 mainchart.last_updated = 0;
331 function setMainChartGroup(g, norefresh) {
332 if(!mainchart) return;
336 if(!mainchart.before && !mainchart.after)
337 calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.max_time_to_show, mainchart.group);
339 calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, 0, mainchart.group);
342 mainchart.last_updated = 0;
346 var last_main_chart_avg = null;
347 function setMainChartGroupMethod(g, norefresh) {
348 if(!mainchart) return;
351 if(last_main_chart_avg == 'max') g = 'average';
355 mainchart.group_method = g;
357 $('.mainchart_avg_button').button(g);
360 mainchart.last_updated = 0;
363 last_main_chart_avg = g;
366 function setMainChartPlay(p) {
367 if(!mainchart) return;
370 if(refresh_mode != REFRESH_ALWAYS) p = 'play';
375 //mainchart.chartOptions.explorer = null;
377 mainchart.before = 0;
378 calculateChartPointsToShow(mainchart, mainchart.chartOptions.isStacked?MAINCHART_STACKED_POINTS_DIVISOR:MAINCHART_POINTS_DIVISOR, mainchart.max_time_to_show, 0);
379 $('#group' + mainchart.group).trigger('click');
380 mainchart.last_updated = 0;
381 mainchart.hiddenchart.last_updated = 0;
385 //mainchart.chartOptions.explorer = {
386 // 'axis': 'horizontal',
389 //mainchart.last_updated = 0;
391 //if(!renderChart(mainchart, pauseGraphs))
397 // ------------------------------------------------------------------------
400 function screenWidth() {
401 return (($(window).width() * 0.95) - 50);
404 // calculate the proper width for the thumb charts
405 function thumbWidth() {
406 var cwidth = screenWidth();
407 var items = Math.round(cwidth / TARGET_THUMB_GRAPH_WIDTH);
408 if(items < 1) items = 1;
410 if(items > 1 && (cwidth / items) < MINIMUM_THUMB_GRAPH_WIDTH) items--;
412 return Math.round(cwidth / items) - 1;
415 function groupChartSizes() {
416 var s = { width: screenWidth() / 2, height: ($(window).height() - 130) / 3 - 10};
417 if(s.width < MINIMUM_THUMB_GRAPH_WIDTH * 1.5) s.width = screenWidth();
420 if(group_charts) $.each(group_charts, function(i, c) {
421 if(c.enabled) count++;
425 s.width = TARGET_THUMB_GRAPH_WIDTH;
426 s.height = TARGET_THUMB_GRAPH_HEIGHT;
429 s.width = screenWidth();
430 s.height = ($(window).height() - 130) / count - 10;
432 else if(count == 4) {
433 s.height = ($(window).height() - 130) / 2 - 10;
436 if(s.height < TARGET_THUMB_GRAPH_HEIGHT * 1.5)
437 s.height = TARGET_THUMB_GRAPH_HEIGHT * 1.5;
443 // if the thumb charts need resize in their width, reset them
444 function resizeCharts() {
445 var width = screenWidth();
448 mainchart.chartOptions.width = width;
449 mainchart.chartOptions.height = $(window).height() - 150 - MAINCHART_CONTROL_HEIGHT;
450 mainchart.last_updated = 0;
452 mainchart.hidden_wrapper.setOption('width', width);
453 mainchart.control_wrapper.setOption('ui.chartOptions.width', width);
454 mainchart.hiddenchart.chartOptions.width = width;
455 mainchart.hiddenchart.last_updated = 0;
458 width = thumbWidth();
459 $.each(mycharts, function(i, c) {
460 if(c.enabled && c.chartOptions.width != width) {
462 c.chartOptions.width = width;
463 calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
464 showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
469 if(group_charts) $.each(group_charts, function(i, c) {
470 var sizes = groupChartSizes();
472 if(c.enabled && (c.chartOptions.width != sizes.width || c.chartOptions.height != sizes.height)) {
474 c.chartOptions.width = sizes.width;
475 c.chartOptions.height = sizes.height;
476 calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
477 showChartIsLoading(c.div, c.name, c.chartOptions.width, c.chartOptions.height);
483 var resize_request = false;
484 window.onresize = function(event) {
485 resize_request = true;
489 // ------------------------------------------------------------------------
490 // Core of the thread refreshing the charts
492 var REFRESH_PAUSED = 0;
493 var REFRESH_ALWAYS = 1;
495 var refresh_mode = REFRESH_PAUSED;
496 var last_refresh = 0;
497 function playGraphs() {
498 if(refresh_mode == REFRESH_ALWAYS) return;
500 //mylog('PlayGraphs()');
501 refresh_mode = REFRESH_ALWAYS;
502 $('.mainchart_play_button').button('play');
504 // check if the thread died due to a javascript error
505 var now = new Date().getTime();
506 if((now - last_refresh) > 60000) {
507 // it died or never started
508 //mylog('It seems the refresh thread died. Restarting it.');
513 function pauseGraphs() {
514 if(refresh_mode == REFRESH_PAUSED) return;
516 //mylog('PauseGraphs()');
517 refresh_mode = REFRESH_PAUSED;
518 $('.mainchart_play_button').button('pause');
522 function checkRefreshThread() {
523 if(interval == null) {
524 interval = setInterval(checkRefreshThread, 2000);
528 var now = new Date().getTime();
529 if(now - last_refresh > 60000) {
530 mylog('Refresh thread died. Restarting it.');
535 // refresh the proper chart
536 // this is an internal function.
537 // never call it directly, or new javascript threads will be spawn
539 function chartsRefresh() {
540 last_refresh = new Date().getTime();
542 if(!page_is_visible) {
543 timeout = setTimeout(triggerRefresh, CHARTS_CHECK_NO_FOCUS);
549 resize_request = false;
550 // refresh_mode = REFRESH_ALWAYS;
553 if(last_user_scroll) {
554 var now = new Date().getTime();
555 if((now - last_user_scroll) >= CHARTS_SCROLL_IDLE) {
556 last_user_scroll = 0;
557 mylog('Scrolling: resuming refresh...');
560 mylog('Scrolling: pausing refresh for ' + (CHARTS_SCROLL_IDLE - (now - last_user_scroll)) + ' ms...');
561 timeout = setTimeout(triggerRefresh, CHARTS_SCROLL_IDLE - (now - last_user_scroll));
566 if(refresh_mode == REFRESH_PAUSED) {
567 if(mode == MODE_MAIN && mainchart.last_updated == 0) {
573 if(mode == MODE_THUMBS) timeout = setTimeout(thumbChartsRefresh, CHARTS_REFRESH_LOOP);
574 else if(mode == MODE_GROUP_THUMBS) timeout = setTimeout(groupChartsRefresh, CHARTS_REFRESH_LOOP);
575 else if(mode == MODE_MAIN) timeout = setTimeout(mainChartRefresh, CHARTS_REFRESH_LOOP);
576 else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
579 // callback for refreshing the charts later
580 // this is an internal function.
581 // never call it directly, or new javascript threads will be spawn
582 function triggerRefresh() {
583 //mylog('triggerRefresh()');
585 // cleanup has to take place when the charts are not refreshed
586 // since the refreshing thread is in this function, it means
587 // nothing is being refreshed.
590 if(mode == MODE_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
591 else if(mode == MODE_GROUP_THUMBS) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
592 else if(mode == MODE_MAIN) timeout = setTimeout(chartsRefresh, CHARTS_REFRESH_IDLE);
593 else timeout = setTimeout(triggerRefresh, CHARTS_REFRESH_IDLE);
596 // refresh the main chart
597 // make sure we don't loose the refreshing thread
598 function mainChartRefresh() {
599 //mylog('mainChartRefresh()');
601 if(mode != MODE_MAIN || !mainchart) {
606 if(refresh_mode == REFRESH_PAUSED && mainchart.last_updated != 0) {
607 hiddenChartRefresh();
611 if(!renderChart(mainchart, hiddenChartRefresh))
612 hiddenChartRefresh();
615 function hiddenChartRefresh() {
616 refreshHiddenChart(triggerRefresh);
619 function roundRobinRefresh(charts, startat) {
620 var refreshed = false;
622 // find a chart to refresh
623 var all = charts.length;
624 var cur = startat + 1;
627 for(count = 0; count < all ; count++, cur++) {
628 if(cur >= all) cur = 0;
630 if(charts[cur].enabled) {
631 refreshed = renderChart(charts[cur], chartsRefresh);
633 mylog('Refreshed: ' + charts[cur].name);
639 if(!refreshed) triggerRefresh();
643 // refresh the thumb charts
644 // make sure we don't loose the refreshing thread
645 var last_thumb_updated = 0;
646 function thumbChartsRefresh() {
647 //mylog('thumbChartsRefresh()');
649 if(mycharts.length == 0 || mode != MODE_THUMBS) {
654 last_thumb_updated = roundRobinRefresh(mycharts, last_thumb_updated);
657 // refresh the group charts
658 // make sure we don't loose the refreshing thread
659 var last_group_updated = 0;
660 function groupChartsRefresh() {
661 //mylog('groupChartsRefresh()');
663 if(!group_charts || group_charts.length == 0 || mode != MODE_GROUP_THUMBS) {
664 //mylog('cannot refresh charts');
669 last_group_updated = roundRobinRefresh(group_charts, last_group_updated);
673 // ------------------------------------------------------------------------
674 // switch the screen between views
675 // these should be called only from initXXXX()
677 function disableChart(i) {
678 //mylog('disableChart(' + i + ')');
683 if(mode == MODE_GROUP_THUMBS && group_charts) {
684 $.each(group_charts, function(i, c) {
685 if(c.enabled) count++;
688 if(i < group_charts.length) chart = group_charts[i];
690 else if(mode == MODE_THUMBS) {
691 $.each(mycharts, function(i, c) {
692 if(c.enabled) count++;
695 if(i < mycharts.length) chart = mycharts[i];
701 alert('Cannot close the last chart shown.');
706 //mylog("disabling chart " + chart.name);
707 chart.disablethisplease = true;
711 function cleanThisChart(chart, emptydivs) {
712 //mylog('cleanThisChart(' + chart.name + ', ' + emptydivs +')');
714 if(chart.dashboard) {
715 chart.dashboard.clear();
716 chart.dashboard = null;
718 if(chart.control_wrapper) {
719 chart.control_wrapper.clear();
720 chart.control_wrapper = null;
723 if(chart.hidden_wrapper) {
724 chart.hidden_wrapper.clear();
725 chart.hidden_wrapper = null;
728 chart.control_data = null;
731 if(chart.chart) chart.chart.clearChart();
735 var div = document.getElementById(chart.div);
737 div.style.display = 'none';
741 div = document.getElementById(chart.div + "_parent");
743 div.style.display = 'none';
748 //mylog("chart " + chart.name + " cleaned with option " + emptydivs);
751 // cleanup the previously shown charts
752 function cleanupCharts() {
753 //mylog('cleanupCharts()');
755 if(mode != MODE_MAIN && mainchart) {
756 if(mainchart.chart) cleanThisChart(mainchart);
760 if(mode != MODE_GROUP_THUMBS && group_charts) {
764 // cleanup the disabled charts
765 $.each(mycharts, function(i, c) {
766 if(c.disablethisplease && c.enabled) {
767 cleanThisChart(c, 'emptydivs');
768 c.disablethisplease = false;
770 resize_request = true;
771 //mylog("disabled chart " + c.name + " removed");
775 if(group_charts) $.each(group_charts, function(i, c) {
776 if(c.disablethisplease && c.enabled) {
777 cleanThisChart(c, 'emptydivs');
778 c.disablethisplease = false;
780 resize_request = true;
781 //mylog("disabled chart " + c.name + " removed");
785 // we never cleanup the thumb charts
788 function updateUI() {
789 $('[data-toggle="tooltip"]').tooltip({'placement': 'top', 'container': 'body', 'html': true});
791 $('[data-spy="scroll"]').each(function () {
792 var $spy = $(this).scrollspy('refresh')
796 var thumbsScrollPosition = null;
797 function switchToMainGraph() {
798 //mylog('switchToMainGraph()');
800 if(!mainchart) return;
802 if(!group_charts) thumbsScrollPosition = window.pageYOffset;
804 document.getElementById('maingraph_container').style.display = 'block';
805 document.getElementById('thumbgraphs_container').style.display = 'none';
806 document.getElementById('groupgraphs_container').style.display = 'none';
807 document.getElementById('splash_container').style.display = 'none';
809 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>";
811 window.scrollTo(0, 0);
818 function switchToThumbGraphs() {
819 //mylog('switchToThumbGraphs()');
821 document.getElementById('maingraph_container').style.display = 'none';
822 document.getElementById('thumbgraphs_container').style.display = 'block';
823 document.getElementById('groupgraphs_container').style.display = 'none';
824 document.getElementById('splash_container').style.display = 'none';
826 document.getElementById("main_menu_div").innerHTML = mainmenu;
828 if(thumbsScrollPosition) window.scrollTo(0, thumbsScrollPosition);
836 function switchToGroupGraphs() {
837 //mylog('switchToGroupGraphs()');
839 if(!group_charts) return;
841 if(!mainchart) thumbsScrollPosition = window.pageYOffset;
843 document.getElementById('maingraph_container').style.display = 'none';
844 document.getElementById('thumbgraphs_container').style.display = 'none';
845 document.getElementById('groupgraphs_container').style.display = 'block';
846 document.getElementById('splash_container').style.display = 'none';
848 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>";
850 window.scrollTo(0, 0);
852 mode = MODE_GROUP_THUMBS;
858 // ------------------------------------------------------------------------
861 var group_charts = null;
862 function initGroupGraphs(group) {
865 if(group_charts) clearGroupGraphs();
866 group_charts = new Array();
869 $.each(mycharts, function(i, c) {
870 if(c.family == group) {
871 group_charts[count] = [];
872 group_charts[count] = $.extend(true, {}, c);
873 group_charts[count].div += "_group";
874 group_charts[count].enabled = true;
875 group_charts[count].chart = null;
876 group_charts[count].last_updated = 0;
880 group_charts.sort(chartssort);
882 var sizes = groupChartSizes();
885 $.each(group_charts, function(i, c) {
886 c.chartOptions.width = sizes.width;
887 c.chartOptions.height = sizes.height;
889 calculateChartPointsToShow(c, c.chartOptions.isStacked?GROUPS_STACKED_POINTS_DIVISOR:GROUPS_POINTS_DIVISOR, GROUPS_MAX_TIME_TO_SHOW, -1);
891 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>";
895 document.getElementById("groupgraphs").innerHTML = groupbody;
896 switchToGroupGraphs();
899 function clearGroupGraphs() {
900 if(group_charts && group_charts.length) {
901 $.each(group_charts, function(i, c) {
902 cleanThisChart(c, 'emptydivs');
908 document.getElementById("groupgraphs").innerHTML = "";
912 // ------------------------------------------------------------------------
913 // Global entry point
914 // initialize the thumb charts
916 var last_user_scroll = 0;
918 // load the charts from the server
919 // generate html for the thumbgraphs to support them
920 function initCharts() {
921 var width = thumbWidth();
922 var height = TARGET_THUMB_GRAPH_HEIGHT;
924 window.onscroll = function (e) {
925 last_user_scroll = new Date().getTime();
926 mylog('Scrolling: detected');
929 loadCharts(null, function(all) {
930 mycharts = all.charts;
932 if(mycharts == null || mycharts.length == 0) {
933 alert("Cannot load data from server.");
937 var thumbsContainer = document.getElementById("thumbgraphs");
938 if(!thumbsContainer) {
939 alert("Cannot find the thumbsContainer");
943 mycharts.sort(chartssort);
945 document.getElementById('hostname_id').innerHTML = all.hostname;
946 document.title = all.hostname;
948 // create an array for grouping all same-type graphs together
950 var categories = new Array();
951 var families = new Array();
952 var chartslist = new Array();
953 $.each(mycharts, function(i, c) {
956 chartslist.push({name: c.name, type: c.type, id: i});
958 dimensions += c.dimensions.length;
959 c.chartOptions.width = width;
960 c.chartOptions.height = height;
962 // calculate how many point to show for each chart
963 //c.points_to_show = Math.round(c.entries / c.group) - 1;
964 // show max 10 mins of data
965 //if(c.points_to_show * c.group > THUMBS_MAX_TIME_TO_SHOW) c.points_to_show = THUMBS_MAX_TIME_TO_SHOW / c.group;
966 calculateChartPointsToShow(c, c.chartOptions.isStacked?THUMBS_STACKED_POINTS_DIVISOR:THUMBS_POINTS_DIVISOR, THUMBS_MAX_TIME_TO_SHOW, -1);
969 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\">"
970 + thumbChartActions(i, c)
971 + "</td></tr><tr><td height='15'></td></tr></table></div>";
973 // find the categories object for this type
974 for(j = 0; j < categories.length ;j++) {
975 if(categories[j].name == c.type) {
976 categories[j].html += h;
977 categories[j].count++;
982 if(j == categories.length)
983 categories.push({name: c.type, title: c.category, description: '', priority: c.categoryPriority, count: 1, glyphicon: c.glyphicon, html: h});
986 // find the families object for this type
987 for(j = 0; j < families.length ;j++) {
988 if(families[j].name == c.family) {
994 if(j == families.length)
995 families.push({name: c.family, count: 1});
998 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>";
1000 $.each(categories, function(i, a) {
1001 a.html = "<tr><td id=\"" + a.name + "\"><ol class=\"breadcrumb graphs\"><li class=\"active\"><span class=\"glyphicon " + a.glyphicon + "\"></span> <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>";
1004 function categoriessort(a, b) {
1005 if(a.priority < b.priority) return -1;
1008 categories.sort(categoriessort);
1010 function familiessort(a, b) {
1011 if(a.name < b.name) return -1;
1014 families.sort(familiessort);
1016 function chartslistsort(a, b) {
1017 if(a.name < b.name) return -1;
1020 chartslist.sort(chartslistsort);
1022 // combine all the htmls into one
1023 var allcategories = "<table width=\"100%\">";
1024 mainmenu = '<ul class="nav navbar-nav">';
1026 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">';
1027 $.each(categories, function(i, a) {
1028 allcategories += a.html;
1029 categoriesmainmenu += "<li><a href=\"#" + a.name + "\">" + a.title + "</a></li>";
1031 categoriesmainmenu += "</ul></li>";
1032 allcategories += "</table>";
1034 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">';
1035 $.each(families, function(i, a) {
1036 familiesmainmenu += "<li><a href=\"javascript:initGroupGraphs('" + a.name + "');\">" + a.name + " <span class=\"badge pull-right\">" + a.count + "</span></a></li>";
1038 familiesmainmenu += "</ul></li>";
1040 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">';
1041 $.each(chartslist, function(i, a) {
1042 chartsmainmenu += "<li><a href=\"javascript:initMainChartIndexOfMyCharts('" + a.id + "');\">" + a.name + "</a></li>";
1044 chartsmainmenu += "</ul></li>";
1046 mainmenu += categoriesmainmenu;
1047 mainmenu += familiesmainmenu;
1048 mainmenu += chartsmainmenu;
1049 mainmenu += '<li role="presentation" class="disabled" style="display: none;"><a href="#" id="logline"></a></li></ul>';
1051 thumbsContainer.innerHTML = allcategories;
1052 switchToThumbGraphs();
1053 checkRefreshThread();
1057 $(window).blur(function() {
1058 page_is_visible = 0;
1059 mylog('Lost Focus!');
1062 $(window).focus(function() {
1063 page_is_visible = 1;
1064 mylog('Focus restored!');
1067 // Set a callback to run when the Google Visualization API is loaded.
1068 google.setOnLoadCallback(initCharts);