]> arthur.barton.de Git - netdata.git/blob - web/index.html
faster updates when multiple charts wait to be updated.
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5     <meta charset="utf-8">
6     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
7     <meta name="viewport" content="width=device-width, initial-scale=1">
8     <meta name="description" content="">
9     <meta name="author" content="costa@tsaousis.gr">
10  
11         <title>NetData</title>
12
13         <!-- Google AJAX API -->
14         <script type="text/javascript" src="https://www.google.com/jsapi"></script>
15         <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
16
17         <!-- Bootstrap -->
18         <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
19         <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
20         <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
21         <link href="/file/theme.css" rel="stylesheet">
22
23         <!-- NetData -->
24         <script type="text/javascript" src="/file/netdata.js"></script>
25         <script type="text/javascript" src="/file/jquery.visible.js"></script>
26         <script type="text/javascript">
27         
28         // Set a callback to run when the Google Visualization API is loaded.
29         google.setOnLoadCallback(initCharts);
30         
31         var MODE_THUMBS = 1;
32         var MODE_MAIN = 2;
33         var mode; // one of the MODE_* values
34
35         var mycharts = new Array();
36         var mainchart;
37
38         function chartIsLoadingHTML(width, height) { return "<table><tr><td align=\"center\" width=\"" + width + "\" height=\"" + height + "\"><h4><span class=\"glyphicon glyphicon-refresh\"></span><br/><br/>loading chart<br/><br/><span class=\"label label-default\">Please wait...</span></h4></td></tr></table>"; }
39
40         function showChartIsLoading(id, width, height) { document.getElementById(id).innerHTML = chartIsLoadingHTML(width, height); }
41
42         // copy the chart c to mainchart
43         // switch to main graphs screen
44         function mainChart(c) {
45                 if(mainchart && mainchart.chart) mainchart.chart.clearChart();
46
47                 mainchart = $.extend(true, {}, c);
48
49                 mainchart.chart = null;
50                 mainchart.chartOptions.width = Math.round((($(window).width() * 0.95) - 50) / 1);
51                 mainchart.chartOptions.height = $(window).height() - 200;
52                 if(mainchart.chartOptions.height < 300) mainchart.chartOptions.height = 300;
53                 
54                 mainchart.thumbnail = false;
55                 mainchart.group = 5;
56                 mainchart.group_method = "max";
57                 mainchart.div = 'maingraph';
58                 mainchart.last_updated = 0;
59                 mainchart.explorer = false;
60
61                 if(mainchart.type == "tc") {
62                         mainchart.group = 15;
63                         mainchart.group_method = "average";
64                 }
65                 else if(mainchart.type == "ipv4" || mainchart.type == "conntrack" || mainchart.type == "ipvs") {
66                         mainchart.group = 15;
67                         mainchart.group_method = "max";
68                 }
69
70                 // calculate the time to refresh each chart
71                 mainchart.chart_update_every = mainchart.group * 1000; // milliseconds
72
73                 // calculate how many point to show for each chart
74                 mainchart.points_to_show = Math.round(mainchart.entries / mainchart.group) - 1;
75
76                 // show max 10 mins of data
77                 if(mainchart.points_to_show * mainchart.group > 1200) mainchart.points_to_show = 1200 / mainchart.group;
78
79                 // initialize the div
80                 showChartIsLoading(mainchart.div, mainchart.chartOptions.width, mainchart.chartOptions.height);
81
82                 document.getElementById('maingraph_title').innerHTML = " <b> " + mainchart.title + " </b> (as " + mainchart.group_method + " of every " + (mainchart.group * mainchart.update_every) + " seconds)";
83
84                 showMainGraph();
85         }
86
87         function setMainChart(i) {
88                 mainChart(mycharts[i]);
89         }
90
91         // refresh the main chart
92         // make sure it gets updated frequently
93         function mainChartRefresh() {
94                 if(!mainchart || mode != MODE_MAIN) {
95                         if(mainchart) mainchart.clearChart();
96                         showThumbGraphs();
97                         return;
98                 }
99
100                 var now = new Date().getTime();
101
102                 if((now - mainchart.last_updated) >= mainchart.chart_update_every) {
103                         refreshChart(mainchart, triggerMainChartRefresh);
104                         mainchart.last_updated = now;
105                 }
106                 else triggerMainChartRefresh();
107         }
108
109         // callback for refreshing the main chart
110         function triggerMainChartRefresh() {
111                 if(mode == MODE_MAIN) setTimeout(mainChartRefresh, 500);
112         }
113
114         // calculate the proper width for the thumb charts
115         function thumbWidth() {
116                 var items = Math.round((($(window).width() * 0.95) - 50) / 500);
117                 if(items < 1) items = 1;
118
119                 var width = Math.round((($(window).width() * 0.95) - 50) / items) - 1;
120                 //console.log("window = " + (($(window).width() * 0.95) - 50) + ", items = " + items + ", width = " + width);
121
122                 return width;
123         }
124
125         // resize all charts
126         // if the thumb charts need resize in their width, reset them
127         function resizeCharts() {
128                 var width = Math.round((($(window).width() * 0.95) - 50) / 1);
129                 if(mainchart) {
130                         mainchart.chartOptions.width = Math.round((($(window).width() * 0.95) - 50) / 1);
131                         mainchart.chartOptions.height = $(window).height() - 200;
132                         mainchart.last_updated = 0;
133                 }
134
135                 width = thumbWidth();
136                 $.each(mycharts, function(i, c) {
137                         if(c.enabled && c.chartOptions.width != width) {
138                                 if(c.chart) c.chart.clearChart();
139                                 c.chart = null;
140                                 c.chartOptions.width = width;
141                                 showChartIsLoading(c.div, c.chartOptions.width, c.chartOptions.height);
142                                 c.last_updated = 0;
143                         }
144                 });
145         }
146
147         // load the charts from the server
148         // generate html for the thumbgraphs to support them
149         function initCharts() {
150                 var width = thumbWidth();
151                 var height = 200;
152
153                 loadCharts(function(c) {
154                         mycharts = c;
155
156                         if(mycharts == null || mycharts.length == 0) {
157                                 alert("Cannot load data from server.");
158                                 return;
159                         }
160
161                         var thumbsContainer = document.getElementById("graphs");
162                         if(!thumbsContainer) {
163                                 alert("Cannot find the thumbsContainer");
164                                 return;
165                         }
166
167                         function chartssort(a, b) {
168                                 if(a.userpriority < b.userpriority) return -1;
169                                 return 1;
170                         }
171                         mycharts.sort(chartssort);
172
173                         document.getElementById('hostname_id').innerHTML = mycharts[0].hostname;
174                         document.title = mycharts[0].hostname;
175
176                         // create an array for grouping all same-type graphs together
177                         var categories = new Array();
178                         $.each(mycharts, function(i, c) {
179                                 c.last_updated = 0;
180                                 c.chartOptions.width = width;
181                                 c.chartOptions.height = height;
182
183                                 switch(c.type) {
184                                         case "tc":
185                                                 c.glyphicon = "glyphicon-transfer";
186                                                 c.group = 30;
187                                                 c.group_method = "average";
188                                                 break;
189
190                                         case "net":
191                                                 c.glyphicon = "glyphicon-cloud";
192                                                 c.group = 10;
193                                                 c.group_method = "max";
194                                                 break;
195
196                                         case "ipv4":
197                                                 c.glyphicon = "glyphicon-resize-full";
198                                                 c.group = 30;
199                                                 c.group_method = "max";
200                                                 break;
201
202                                         case "conntrack":
203                                                 c.glyphicon = "glyphicon-eye-open";
204                                                 c.group = 30;
205                                                 c.group_method = "max";
206                                                 break;
207
208                                         case "ipvs":
209                                                 c.glyphicon = "glyphicon-sort";
210                                                 c.group = 30;
211                                                 c.group_method = "max";
212                                                 break;
213
214                                         case "disk":
215                                                 c.glyphicon = "glyphicon-floppy-disk";
216                                                 c.group = 20;
217                                                 c.group_method = "max";
218                                                 break;
219
220                                         default:
221                                                 c.glyphicon = "glyphicon-search";
222                                                 c.group = 60;
223                                                 c.group_method = "max";
224                                                 break;
225                                 }
226
227                                 // calculate the time to refresh each chart
228                                 c.chart_update_every = c.group * 1000; // milliseconds
229
230                                 // calculate how many point to show for each chart
231                                 c.points_to_show = Math.round(c.entries / c.group) - 1;
232
233                                 // show max 10 mins of data
234                                 if(c.points_to_show * c.group > 600) c.points_to_show = 600 / c.group;
235
236                                 if(c.enabled) {
237                                         var j;
238                                         var h = "<div class=\"thumbgraph\"><table><tr><td><div class=\"thumbgraph\" id=\"" + c.div + "\">" + chartIsLoadingHTML(c.chartOptions.width, c.chartOptions.height) + "</div></td></tr><tr><td align=\"center\"><div class=\"btn-group-xs\"><button type=\"button\" class=\"btn btn-default\" onclick=\"setMainChart(" + i +");\">&nbsp;&nbsp;select " + c.name + " for zoom&nbsp;&nbsp;</button></div></td></tr></table></div>";
239
240                                         // find the categories object for this type
241                                         for(j = 0; j < categories.length ;j++) {
242                                                 if(categories[j].name == c.type) {
243                                                         categories[j].html += h;
244                                                         categories[j].count++;
245                                                         break;
246                                                 }
247                                         }
248
249                                         if(j == categories.length) {
250                                                 var t = "(as " + c.group_method + " every " + (c.group*c.update_every) + " seconds)";
251                                                 categories.push({name: c.type, title: c.category, description: t, priority: 0, count: 1, glyphicon: c.glyphicon, html: h});
252                                         }
253                                 }
254                         });
255
256                         $.each(categories, function(i, a) {
257                                      if(a.name == "net") a.priority = 1;
258                                 else if(a.name == "tc") a.priority = 2;
259                                 else if(a.name == "conntrack") a.priority = 3;
260                                 else if(a.name == "ipvs") a.priority = 4;
261                                 else if(a.name == "ipv4") a.priority = 5;
262                                 else if(a.name == "disk") a.priority = 6;
263                                 else a.priority = 4;
264
265                                 a.html = "<tr><td><ol class=\"breadcrumb graphs\"><li class=\"active\"><span class=\"glyphicon " + a.glyphicon + "\"></span> &nbsp; <a id=\"" + a.name + "\" href=\"#" + a.name + "\"><b>" + a.title + "</b> " + a.description + " </a></li></ol></td></tr><tr><td><div class=\"thumbgraphs\">" + a.html + "</td></tr>";
266                         });
267
268                         function categoriessort(a, b) {
269                                 if(a.priority < b.priority) return -1;
270                                 return 1;
271                         }
272                         categories.sort(categoriessort);
273
274                         // combine all the htmls into one
275                         var allcategories = "<table width=\"100%\">";
276                         $.each(categories, function(i, a) {
277                                 allcategories += a.html;
278                         });
279                         allcategories += "</table>";
280
281                         thumbsContainer.innerHTML = allcategories;
282                         showThumbGraphs();
283                 });
284         }
285
286         var last_mini = 0;
287         function thumbChartsRefreshInternal(howmany) {
288                 if(mycharts.length == 0 || mode != MODE_THUMBS) return;
289
290                 var now = new Date().getTime();
291
292                 // refresh the mini charts
293                 var wanted = howmany;
294                 var did    = 0;
295                 var count  = mycharts.length - 1;
296                 while(did < wanted && count >= 0) {
297                         count--;
298                         last_mini++;
299                         if(last_mini >= mycharts.length) last_mini = 0;
300
301                         if(!mycharts[last_mini].enabled) continue;
302                         if((now - mycharts[last_mini].last_updated) < mycharts[last_mini].chart_update_every) continue;
303
304                         if(mycharts[last_mini].chart != null)
305                                 if(mycharts[last_mini].chart.getSelection()[0]) continue;
306
307                         if($('#' + mycharts[last_mini].div).visible(true) == false) continue;
308
309                         refreshChart(mycharts[last_mini], triggerThumbChartsRefreshFast);
310                         mycharts[last_mini].last_updated = now;
311
312                         did++;
313                 }
314
315                 if(did == 0) triggerThumbChartsRefresh();
316         }
317
318         function triggerThumbChartsRefresh() {
319                 setTimeout(thumbChartsRefresh, 200);
320         }
321
322         function triggerThumbChartsRefreshFast() {
323                 thumbChartsRefresh();
324         }
325
326         function thumbChartsRefresh() {
327                 if(mode == MODE_THUMBS) thumbChartsRefreshInternal(1);
328         }
329
330         // setInterval(myChartsRefresh, 500);
331
332         window.onresize = function(event) {
333                 resizeCharts();
334         };
335
336         function showMainGraph() {
337                 if(!mainchart) return;
338                 mode = MODE_MAIN;
339
340                 document.getElementById('maingraph_container').style.display = 'block';
341                 document.getElementById('thumbgraphs_container').style.display = 'none';
342
343                 mainChartRefresh();
344         }
345
346         function showThumbGraphs() {
347                 mode = MODE_THUMBS;
348
349                 document.getElementById('maingraph_container').style.display = 'none';
350                 document.getElementById('thumbgraphs_container').style.display = 'block';
351
352                 if(mainchart) {
353                         if(mainchart.chart) mainchart.chart.clearChart();
354                         mainchart = null;
355                 }
356
357                 thumbChartsRefresh(1);
358         }
359
360         </script>
361 </head>
362
363 <body role="document">
364     <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
365       <div class="container">
366         <div class="navbar-header">
367           <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
368             <span class="sr-only">Toggle navigation</span>
369             <span class="icon-bar"></span>
370             <span class="icon-bar"></span>
371             <span class="icon-bar"></span>
372           </button>
373           <a class="navbar-brand" href="#" id="hostname_id">NetData</a>
374         </div>
375         <div class="collapse navbar-collapse">
376           <ul class="nav navbar-nav">
377             <li class="active"><a href="#">Home</a></li>
378             <li><a href="#net">Network</a></li>
379             <li><a href="#tc">QoS</a></li>
380             <li><a href="#conntrack">Netfilter</a></li>
381             <li><a href="#ipv4">IPv4</a></li>
382             <li><a href="#ipvs">IPVS</a></li>
383             <li><a href="#disk">Disk</a></li>
384           </ul>
385         </div><!--/.nav-collapse -->
386       </div>
387     </div>
388
389     <div class="container graphs" id="maingraph_container" style="display: none">
390                 <table>
391                         <tr><td><ol class="breadcrumb graphs"><li class="active"><a id="maingraph_title" href="#maingraph"><b> Maingraph </b></a></li></ol></td></tr>
392                         <tr><td>
393                         <div class="maingraph">
394                                         <table>
395                                                 <tr><td><div class="maingraph" id="maingraph"></div></td></tr>
396                                                 <tr><td align="center"><div class="btn-group"><button type="button" onclick="showThumbGraphs();" class="btn btn-default"> close main graph </button></div></td></tr>
397                                         </table>
398                            </div><!-- /.maingraph -->
399                         </td></tr>
400                 </table>
401         </div>
402
403     <div class="container graphs" id="thumbgraphs_container">
404         <div class="allgraphs" id="graphs">
405         <table width="100%"><tr><td align="center"><p/>&nbsp;<p/>&nbsp;<p/>&nbsp;<h1><span class="glyphicon glyphicon-refresh"></span><br/><br/>loading charts<br/><br/><span class="label label-default">Please wait...</span></h1></td></tr></table>
406         </div>
407         </div>
408 </html>