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> " + 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> <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> " + 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> <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);