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