4 <meta http-equiv="Content-Type" content="text/html; 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">
13 <title>NetData</title>
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>
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">
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">
30 // Set a callback to run when the Google Visualization API is loaded.
31 google.setOnLoadCallback(initCharts);
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;
39 var mode; // one of the MODE_* values
41 var mycharts = new Array();
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>"; }
46 function showChartIsLoading(id, width, height) { document.getElementById(id).innerHTML = chartIsLoadingHTML(width, height); }
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();
53 mainchart = $.extend(true, {}, c);
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;
60 mainchart.thumbnail = false;
62 mainchart.div = 'maingraph';
63 mainchart.last_updated = 0;
64 mainchart.explorer = false;
66 if(mainchart.chartOptions.isStacked) mainchart.group = 15;
68 // calculate the time to refresh each chart
69 mainchart.chart_update_every = mainchart.group * 1000; // milliseconds
71 // calculate how many point to show for each chart
72 mainchart.points_to_show = Math.round(mainchart.entries / mainchart.group) - 1;
74 // show max 10 mins of data
75 if(mainchart.points_to_show * mainchart.group > 1200) mainchart.points_to_show = 1200 / mainchart.group;
78 showChartIsLoading(mainchart.div, mainchart.chartOptions.width, mainchart.chartOptions.height);
80 document.getElementById('maingraph_title').innerHTML = " <b> " + mainchart.title + " </b> (as " + mainchart.group_method + " of every " + (mainchart.group * mainchart.update_every) + " seconds)";
85 function setMainChart(i) {
86 mainChart(mycharts[i]);
89 // refresh the main chart
90 // make sure it gets updated frequently
91 function mainChartRefresh() {
92 if(!mainchart || mode != MODE_MAIN) {
93 if(mainchart) mainchart.clearChart();
98 var now = new Date().getTime();
100 if((now - mainchart.last_updated) >= mainchart.chart_update_every) {
101 refreshChart(mainchart, triggerRefresh);
102 mainchart.last_updated = now;
104 else triggerRefresh();
107 function screenWidth() {
108 return (($(window).width() * 0.95) - 40);
111 // calculate the proper width for the thumb charts
112 function thumbWidth() {
113 var cwidth = screenWidth();
114 var items = Math.round(cwidth / TARGET_THUMB_GRAPH_WIDTH);
115 if(items < 1) items = 1;
117 if(items > 1 && (cwidth / items) < MINIMUM_THUMB_GRAPH_WIDTH) items--;
119 return Math.round(cwidth / items) - 1;
123 // if the thumb charts need resize in their width, reset them
124 function resizeCharts() {
125 var width = screenWidth();
128 mainchart.chartOptions.width = width;
129 mainchart.chartOptions.height = $(window).height() - 200;
130 mainchart.last_updated = 0;
133 width = thumbWidth();
134 $.each(mycharts, function(i, c) {
135 if(c.enabled && c.chartOptions.width != width) {
136 if(c.chart) c.chart.clearChart();
138 c.chartOptions.width = width;
139 showChartIsLoading(c.div, c.chartOptions.width, c.chartOptions.height);
145 // load the charts from the server
146 // generate html for the thumbgraphs to support them
147 function initCharts() {
148 var width = thumbWidth();
149 var height = TARGET_THUMB_GRAPH_HEIGHT;
151 loadCharts(function(c) {
154 if(mycharts == null || mycharts.length == 0) {
155 alert("Cannot load data from server.");
159 var thumbsContainer = document.getElementById("thumbgraphs");
160 if(!thumbsContainer) {
161 alert("Cannot find the thumbsContainer");
165 function chartssort(a, b) {
166 if(a.userpriority < b.userpriority) return -1;
169 mycharts.sort(chartssort);
171 document.getElementById('hostname_id').innerHTML = mycharts[0].hostname;
172 document.title = mycharts[0].hostname;
174 // create an array for grouping all same-type graphs together
175 var categories = new Array();
176 $.each(mycharts, function(i, c) {
178 c.chartOptions.width = width;
179 c.chartOptions.height = height;
181 // calculate the time to refresh each chart
182 c.chart_update_every = c.group * 1000; // milliseconds
184 // calculate how many point to show for each chart
185 c.points_to_show = Math.round(c.entries / c.group) - 1;
187 // show max 10 mins of data
188 if(c.points_to_show * c.group > 600) c.points_to_show = 600 / c.group;
192 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 +");\"> select " + c.name + " for zoom </button></div></td></tr></table></div>";
194 // find the categories object for this type
195 for(j = 0; j < categories.length ;j++) {
196 if(categories[j].name == c.type) {
197 categories[j].html += h;
198 categories[j].count++;
203 if(j == categories.length) {
204 var t = "(as " + c.group_method + " every " + (c.group*c.update_every) + " seconds)";
205 categories.push({name: c.type, title: c.category, description: t, priority: 0, count: 1, glyphicon: c.glyphicon, html: h});
210 $.each(categories, function(i, a) {
211 if(a.name == "net") a.priority = 1;
212 else if(a.name == "tc") a.priority = 2;
213 else if(a.name == "conntrack") a.priority = 3;
214 else if(a.name == "ipvs") a.priority = 4;
215 else if(a.name == "ipv4") a.priority = 5;
216 else if(a.name == "cpu") a.priority = 6;
217 else if(a.name == "disk") a.priority = 7;
218 else a.priority = 99;
220 a.html = "<tr><td><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>";
223 function categoriessort(a, b) {
224 if(a.priority < b.priority) return -1;
227 categories.sort(categoriessort);
229 // combine all the htmls into one
230 var allcategories = "<table width=\"100%\">";
231 $.each(categories, function(i, a) {
232 allcategories += a.html;
234 allcategories += "</table>";
236 thumbsContainer.innerHTML = allcategories;
242 function thumbChartsRefreshInternal(howmany) {
243 if(mycharts.length == 0 || mode != MODE_THUMBS) return;
245 var now = new Date().getTime();
247 // refresh the mini charts
248 var wanted = howmany;
250 var count = mycharts.length - 1;
251 while(did < wanted && count >= 0) {
254 if(last_mini >= mycharts.length) last_mini = 0;
256 if(!mycharts[last_mini].enabled) continue;
257 if((now - mycharts[last_mini].last_updated) < mycharts[last_mini].chart_update_every) continue;
259 if(mycharts[last_mini].chart != null)
260 if(mycharts[last_mini].chart.getSelection()[0]) continue;
262 if($('#' + mycharts[last_mini].div).visible(true) == false) continue;
264 refreshChart(mycharts[last_mini], chartsRefresh);
265 mycharts[last_mini].last_updated = now;
270 if(did == 0) triggerRefresh();
273 // default thumbs charts refresh
274 function thumbChartsRefresh() {
275 thumbChartsRefreshInternal(1);
278 // refresh the proper chart
279 function chartsRefresh() {
280 if(mode == MODE_THUMBS)
281 thumbChartsRefresh();
283 else if(mode == MODE_MAIN)
287 setTimeout(triggerRefresh, 1000);
290 // callback for refreshing the charts later
291 function triggerRefresh() {
292 if(mode == MODE_THUMBS)
293 setTimeout(thumbChartsRefresh, 200);
295 else if(mode == MODE_MAIN)
296 setTimeout(mainChartRefresh, 500);
299 setTimeout(triggerRefresh, 1000);
302 window.onresize = function(event) {
306 var thumbsScrollPosition = null;
307 function showMainGraph() {
308 if(!mainchart) return;
310 thumbsScrollPosition = window.pageYOffset;
314 document.getElementById('maingraph_container').style.display = 'block';
315 document.getElementById('thumbgraphs_container').style.display = 'none';
320 function showThumbGraphs() {
323 document.getElementById('maingraph_container').style.display = 'none';
324 document.getElementById('thumbgraphs_container').style.display = 'block';
326 if(thumbsScrollPosition) window.scrollTo(0, thumbsScrollPosition);
329 if(mainchart.chart) mainchart.chart.clearChart();
339 <body role="document">
340 <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
341 <div class="container">
342 <div class="navbar-header">
343 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
344 <span class="sr-only">Toggle navigation</span>
345 <span class="icon-bar"></span>
346 <span class="icon-bar"></span>
347 <span class="icon-bar"></span>
349 <a class="navbar-brand" href="#" id="hostname_id">NetData</a>
351 <div class="collapse navbar-collapse">
352 <ul class="nav navbar-nav">
353 <li class="active"><a href="#">Home</a></li>
354 <li><a href="#net">Network</a></li>
355 <li><a href="#tc">QoS</a></li>
356 <li><a href="#conntrack">Netfilter</a></li>
357 <li><a href="#ipv4">IPv4</a></li>
358 <li><a href="#ipvs">IPVS</a></li>
359 <li><a href="#disk">Disk</a></li>
361 </div><!--/.nav-collapse -->
365 <div class="container graphs" id="maingraph_container" style="display: none">
367 <tr><td><ol class="breadcrumb graphs"><li class="active"><a id="maingraph_title" href="#maingraph"><b> Maingraph </b></a></li></ol></td></tr>
369 <div class="maingraph">
371 <tr><td><div class="maingraph" id="maingraph"></div></td></tr>
372 <tr><td align="center"><div class="btn-group"><button type="button" onclick="showThumbGraphs();" class="btn btn-default"> close main graph </button></div></td></tr>
374 </div><!-- /.maingraph -->
379 <div class="container graphs" id="thumbgraphs_container">
380 <div class="allgraphs" id="thumbgraphs">
382 <tr><td id="splash" align="center" style="vertical-align:middle">
384 Welcome to <b>NetData</b>!
386 <span class="glyphicon glyphicon-off"></span>
390 <span class="label label-default">Please wait...</span>
397 <script type="text/javascript">document.getElementById('splash').height = $(window).height();</script>