]> arthur.barton.de Git - netdata.git/blob - web/index.html
32fe5a52826e5e1fa32e17413d4d0084ee12bfb8
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4         <title>netdata dashboard</title>
5
6         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7         <meta charset="utf-8">
8         <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
9         <meta name="viewport" content="width=device-width, initial-scale=1">
10         <meta name="apple-mobile-web-app-capable" content="yes">
11         <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
12         <meta name="author" content="costa@tsaousis.gr">
13
14         <link rel="shortcut icon" href="images/seo-performance-multi-size.ico">
15
16         <link rel="apple-touch-icon" href="images/seo-performance-72.png">
17         <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png">
18         <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png">
19
20         <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png">
21         <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png">
22         <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png">
23         <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png">
24         <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png">
25         <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png">
26         <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png">
27         <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png">
28
29         <style>
30
31         /* prevent body from hiding under the navbar */
32         body {
33                 padding-top: 50px;
34         }
35
36         .modal-wide .modal-dialog {
37                 width: 80%;
38         }
39
40         /* fix # anchors scrolling under the navbar
41            https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
42          */
43         h1 {
44                 position: relative;
45                 z-index: -1;
46         }
47         h2 {
48                 position: relative;
49                 z-index: -2;
50         }
51         h1:before, h2:before {
52                 display: block;
53                 content: " ";
54                 margin-top: -70px;
55                 height: 70px;
56                 visibility: hidden;
57         }
58
59         .p {
60                 display: block;
61                 margin-top: 15px;
62         }
63
64         .option-row,
65         .option-control {
66                 vertical-align: top;
67                 padding: 10px;
68                 padding-top: 30px;
69                 padding-left: 30px;
70         }
71
72         .option-info {
73                 padding: 10px;
74         }
75
76         .chart-message {
77                 display: block;
78                 margin-top: 10px;
79         }
80
81         .container {
82                 width: 90% !important;
83         }
84
85         #masthead h1 {
86                 /*font-size: 30px;*/
87                 line-height: 1;
88                 padding-top: 30px;
89         }
90
91         #masthead .well {
92                 margin-top:4%;
93         }
94
95         /* fix the navbar shifting when a modal is open */
96         /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
97         body.modal-open{
98                 width: 100% !important;
99                 padding-right: 0 !important;
100 /*              overflow-y: scroll !important; */
101 /*              position: fixed !important;*/
102                 overflow: visible;
103         }
104
105         /*
106          * Side navigation
107          *
108          * Scrollspy and affixed enhanced navigation to highlight sections and secondary
109          * sections of docs content.
110          */
111
112         .affix {
113                 position: static;
114                 top: 70px !important;
115                 /*width: 220px;*/
116         }
117
118         .affix-top {
119                 /*width: 220px;*/
120         }
121
122         .dashboard-sidebar {
123                 max-height: calc(100% - 70px) !important;
124                 overflow-y: auto;
125                 /*width: 220px !important;*/
126         }
127
128         /* By default it's not affixed in mobile views, so undo that */
129         .dashboard-sidebar.affix {
130                 position: static;
131         }
132
133         @media (min-width: 768px) {
134                 .dashboard-sidebar {
135                         padding-left: 20px;
136                 }
137         }
138
139         /* First level of nav */
140         .dashboard-sidenav {
141                 margin-top: 20px;
142                 margin-bottom: 20px;
143         }
144
145         /* All levels of nav */
146         .dashboard-sidebar .nav > li > a {
147                 display: block;
148                 padding: 4px 20px;
149                 font-size: 13px;
150                 font-weight: 500;
151                 color: #767676;
152         }
153         .dashboard-sidebar .nav > li > a:hover,
154         .dashboard-sidebar .nav > li > a:focus {
155                 padding-left: 19px;
156                 color: #563d7c;
157                 text-decoration: none;
158                 background-color: transparent;
159                 border-left: 1px solid #563d7c;
160         }
161         .dashboard-sidebar .nav > .active > a,
162         .dashboard-sidebar .nav > .active:hover > a,
163         .dashboard-sidebar .nav > .active:focus > a {
164                 padding-left: 18px;
165                 font-weight: bold;
166                 color: #563d7c;
167                 background-color: transparent;
168                 border-left: 2px solid #563d7c;
169         }
170
171         /* Nav: second level (shown on .active) */
172         .dashboard-sidebar .nav .nav {
173                 display: none; /* Hide by default, but at >768px, show it */
174                 padding-bottom: 10px;
175         }
176         .dashboard-sidebar .nav .nav > li > a {
177                 padding-top: 1px;
178                 padding-bottom: 1px;
179                 padding-left: 30px;
180                 font-size: 12px;
181                 font-weight: normal;
182         }
183         .dashboard-sidebar .nav .nav > li > a:hover,
184         .dashboard-sidebar .nav .nav > li > a:focus {
185                 padding-left: 29px;
186         }
187         .dashboard-sidebar .nav .nav > .active > a,
188         .dashboard-sidebar .nav .nav > .active:hover > a,
189         .dashboard-sidebar .nav .nav > .active:focus > a {
190                 padding-left: 28px;
191                 font-weight: 500;
192         }
193
194         .dropdown-menu {
195                 min-width: 200px;
196         }
197         .dropdown-menu.columns-2 {
198                 margin: 0;
199                 padding: 0;
200                 width: 400px;
201         }
202         .dropdown-menu li a {
203                 padding: 5px 15px;
204                 font-weight: 300;
205         }
206         .dropdown-menu.multi-column {
207                 overflow-x: hidden;
208         }
209         .multi-column-dropdown {
210                 list-style: none;
211                 padding: 0;
212         }
213         .multi-column-dropdown li a {
214                 display: block;
215                 clear: both;
216                 line-height: 1.428571429;
217                 white-space: normal;
218         }
219         .multi-column-dropdown li a:hover {
220                 text-decoration: none;
221                 color: #f5f5f5;
222                 background-color: #262626;
223         }
224         .scrollable-menu {
225                 height: auto;
226                 max-height: 80vh;
227                 overflow-x: hidden;
228         }
229
230         /* Back to top (hidden on mobile) */
231         .back-to-top,
232         .dashboard-theme-toggle {
233                 display: none;
234                 padding: 4px 10px;
235                 margin-top: 10px;
236                 margin-left: 10px;
237                 font-size: 12px;
238                 font-weight: 500;
239                 color: #999;
240         }
241         .back-to-top:hover,
242         .dashboard-theme-toggle:hover {
243                 color: #563d7c;
244                 text-decoration: none;
245         }
246         .dashboard-theme-toggle {
247                 margin-top: 0;
248         }
249
250         @media (min-width: 768px) {
251                 .back-to-top,
252                 .dashboard-theme-toggle {
253                         display: block;
254                 }
255
256                 /* Widen the fixed sidebar */
257                 .dashboard-sidebar.affix,
258                 .dashboard-sidebar.affix-top,
259                 .dashboard-sidebar.affix-bottom {
260                         width: 200px !important;
261                 }
262
263                 .dashboard-sidebar.affix {
264                         position: fixed; /* Undo the static from mobile first approach */
265                         top: 20px;
266                 }
267
268                 .dashboard-sidebar.affix-bottom {
269                         position: absolute; /* Undo the static from mobile first approach */
270                 }
271
272                 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
273                 .dashboard-sidebar.affix .dashboard-sidenav {
274                         margin-top: 0;
275                         margin-bottom: 0;
276                 }
277         }
278
279         /* Show and affix the side nav when space allows it */
280         @media (min-width: 992px) {
281                 .dashboard-sidebar .nav > .active > ul {
282                         display: block;
283                 }
284
285                 /* Widen the fixed sidebar */
286                 .dashboard-sidebar.affix,
287                 .dashboard-sidebar.affix-top,
288                 .dashboard-sidebar.affix-bottom {
289                         width: 200px !important;
290                 }
291                 .dashboard-sidebar.affix {
292                         position: fixed; /* Undo the static from mobile first approach */
293                         top: 20px;
294                 }
295                 .dashboard-sidebar.affix-bottom {
296                         position: absolute; /* Undo the static from mobile first approach */
297                 }
298                 .dashboard-sidebar.affix-bottom .dashboard-sidenav,
299                 .dashboard-sidebar.affix .dashboard-sidenav {
300                         margin-top: 0;
301                         margin-bottom: 0;
302                 }
303         }
304
305         @media (min-width: 1200px) {
306                 /* Widen the fixed sidebar again */
307                 .dashboard-sidebar.affix-bottom,
308                 .dashboard-sidebar.affix-top,
309                 .dashboard-sidebar.affix {
310                         width: 263px;
311                 }
312         }
313         </style>
314
315         <!-- you can set your netdata server globally, by ucommenting this -->
316         <!-- you can also give a different server per chart, with the attribute: data-host="http://netdata.server:19999" -->
317         <!-- <script> netdataServer = "http://box:19999"; </script> -->
318
319         <!-- check which theme to use -->
320         <script>
321                 function loadLocalStorage(name) {
322                         var ret = null;
323
324                         try {
325                                 if(typeof Storage !== "undefined" && typeof localStorage === 'object')
326                                         ret = localStorage.getItem(name);
327                         }
328                         catch(error) {
329                                 ;
330                         }
331
332                         if(typeof ret === 'undefined' || ret === null)
333                                 return null;
334
335                         return ret;
336                 }
337
338                 function saveLocalStorage(name, value) {
339                         try {
340                                 if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
341                                         localStorage.setItem(name, value.toString());
342                                         return true;
343                                 }
344                         }
345                         catch(error) {
346                                 ;
347                         }
348
349                         return false;
350                 }
351
352                 function getTheme(def) {
353                         var ret = loadLocalStorage('netdataTheme');
354                         if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
355                                 return def;
356                         else
357                                 return ret;
358                 }
359
360                 var netdataTheme = getTheme('slate');
361
362                 function setTheme(theme) {
363                         if(theme === netdataTheme) return false;
364
365                         return saveLocalStorage('netdataTheme', theme);
366                 }
367
368                 var netdataRegistryCallback = function(urls) {
369                         var el = '';
370                         var a1 = '';
371                         var found = 0;
372
373                         if(urls) {
374                                 $.each(urls, function(i, u) {
375                                         if(u.guid !== NETDATA.registry.machine_guid) {
376                                                 found++;
377                                                 el += '<li id="registry_server_' + u.guid + '"><a href="' + u.url + '">' + u.name + '</a></li>';
378                                                 a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
379                                         }
380                                 });
381                         }
382
383                         if(!found) {
384                                 if(urls)
385                                         el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">your netdata server list is empty...</a></li>';
386                                 else
387                                         el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">failed to contact the registry...</a></li>';
388
389                                 a1 += '<li><a href="#">&nbsp;</a></li>';
390
391                                 el += '<li role="separator" class="divider"></li>' +
392                                                 '<li><a href="//london.netdata.rocks/default.html">EU - London (DigitalOcean.com)</a></li>' +
393                                                 '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
394                                                 '<li><a href="//athens.netdata.rocks/default.html">EU - Athens</a></li>';
395                                 a1 += '<li role="separator" class="divider"></li>' +
396                                                 '<li><a href="#">&nbsp;</a></li>' +
397                                                 '<li><a href="#">&nbsp;</a></li>'+
398                                                 '<li><a href="#">&nbsp;</a></li>';
399                         }
400
401                         el += '<li role="separator" class="divider"></li>';
402                         a1 += '<li role="separator" class="divider"></li>';
403
404                         el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
405                         a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-cog" aria-hidden="true" style="color: #999;"></i></a></li>'
406
407                         document.getElementById('mynetdata_servers').innerHTML = el;
408                         document.getElementById('mynetdata_actions1').innerHTML = a1;
409
410                         document.getElementById('mynetdata_servers2').innerHTML = el;
411                 };
412
413         </script>
414
415         <!-- load the dashboard manager - it will do the rest -->
416         <script type="text/javascript" src="dashboard.js?v35"></script>
417 </head>
418
419 <body data-spy="scroll" data-target="#sidebar">
420         <nav class="navbar navbar-default navbar-fixed-top" role="banner">
421                 <div class="container">
422                         <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
423                                 <ul class="nav navbar-nav">
424                                         <li class="dropdown">
425                                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
426                                                 <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
427                                                         <div class="row">
428                                                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
429                                                                         <ul id="mynetdata_servers" class="multi-column-dropdown">
430                                                                         </ul>
431                                                                 </div>
432                                                                 <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
433                                                                         <ul id="mynetdata_actions1" class="multi-column-dropdown">
434                                                                         </ul>
435                                                                 </div>
436                                                         </div>
437                                                 </ul>
438                                         </li>
439                                 </ul>
440                         </nav>
441                         <div class="navbar-header">
442                                 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
443                                         <span class="sr-only">Toggle navigation</span>
444                                         <span class="icon-bar"></span>
445                                         <span class="icon-bar"></span>
446                                         <span class="icon-bar"></span>
447                                 </button>
448                                 <a href="/" class="navbar-brand" id="hostname">netdata</a>
449                         </div>
450                         <nav class="collapse navbar-collapse navbar-right" role="navigation">
451                                 <ul class="nav navbar-nav">
452                                         <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
453                                         <li class="hidden-sm"><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
454                                         <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fa fa-cloud-download"></i> update</a></li>
455                                         <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
456                                         <li class="dropdown hidden-md hidden-lg hidden-xs">
457                                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
458                                                 <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
459                                                         <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
460                                                         <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
461                                                         <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
462                                                 </ul>
463                                         </li>
464                                         <li class="dropdown hidden-sm hidden-md hidden-lg">
465                                                 <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
466                                                 <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
467                                                 </ul>
468                                         </li>
469                                 </ul>
470                         </nav>
471         </nav>
472                 </div>
473         </nav>
474
475         <div id="masthead" style="display: none;">
476                 <div class="container">
477                         <div class="row">
478                                 <div class="col-md-7">
479                                         <h1>Netdata
480                                                 <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
481                                         </h1>
482                                 </div>
483                                 <div class="col-md-5">
484                                         <div class="well well-lg">
485                                                 <div class="row">
486                                                 <div class="col-md-6">
487                                                         <b>Drag</b> charts to pan.
488                                                         <b>Shift + wheel</b> on them, to zoom in and out.
489                                                         <b>Double-click</b> on them, to reset.
490                                                         <b>Hover</b> on them too!
491                                                         </div>
492                                                 <div class="col-md-6">
493                                                         <div data-netdata="system.intr" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dygraph-type="line" data-dygraph-strokewidth="3" data-dygraph-smooth="true" data-dygraph-highlightcirclesize="6" data-after="-90" data-height="60px" data-colors="#C66"></div>
494                                                         </div>
495                                                 </div>
496                                         </div>
497                                 </div>
498                         </div>
499                 </div>
500         </div>
501
502         <div class="container">
503                 <div class="row">
504                         <div class="col-md-10" role="main">
505                                 <div id="charts_div"></div>
506                         </div>
507                         <div class="col-md-2" role="complementary">
508                                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
509                         </div>
510                 </div>
511         </div>
512
513         <div id="footer" class="container" style="display: none;">
514                 <div class="row">
515                         <div class="col-md-10" role="main">
516                                 <div class="p">
517                                         <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
518                                         <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
519                                         Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
520                                 </div>
521                                 <div class="p">
522                                         <small>
523                                                 <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
524
525                                                 <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
526                                                 <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
527
528                                                 <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
529                                                 <i class="fa fa-copyright"></i> Copyright 2009-2012, Splunk Inc., <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">New BSD License</a>
530
531                                                 <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
532                                                 <i class="fa fa-copyright"></i> Copyright 2009-2015, Ben Pickles, <a href="https://github.com/benpickles/peity/blob/master/MIT-LICENCE" target="_blank">MIT License</a>
533
534                                                 <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
535                                                 <i class="fa fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a>
536
537                                                 <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
538                                                 <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
539
540                                                 <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
541                                                 <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
542
543                                                 <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
544                                                 <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
545
546                                                 <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
547                                                 <i class="fa fa-copyright"></i> Copyright (c) 2011-2014 Min Hur, The New York Times Company, <a href="https://github.com/minhur/bootstrap-toggle/blob/master/LICENSE" target="_blank">MIT License</a>
548
549                                                 <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
550                                                 <i class="fa fa-copyright"></i> Copyright 2012, James Florentino, <a href="https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE" target="_blank">MIT License</a>
551
552                                                 <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
553                                                 <i class="fa fa-copyright"></i> Copyright Marc J. Schmidt, <a href="https://github.com/marcj/css-element-queries/blob/master/LICENSE" target="_blank">MIT License</a>
554
555                                                 <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
556                                                 <i class="fa fa-copyright"></i> Created by Dave Gandy, Font: <a href="http://scripts.sil.org/OFL" target="_blank">SIL OFL 1.1 License</a>, CSS: <a href="http://opensource.org/licenses/mit-license.html" target="_blank">MIT License</a>
557
558                                                 <i class="fa fa-circle"></i> <a href="http://www.iconsdb.com/soylent-red-icons/seo-performance-icon.html" target="_blank">IconsDB.com Icons</a>, Icons provided as CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.
559
560                                                 <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
561                                                 <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
562
563                                                 <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
564                                                 <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
565
566                                                 <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
567                                                 <i class="fa fa-copyright"></i> Copyright 2013, Masayuki Tanaka, <a href="https://github.com/masayuki0812/c3/blob/master/LICENSE" target="_blank">MIT License</a>
568
569                                                 <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
570                                                 <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
571
572                                         </small>
573                                 </div>
574                         </div>
575                 </div>
576         </div>
577
578         <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
579                 <div class="modal-dialog modal-lg" role="document">
580                         <div class="modal-content">
581                                 <div class="modal-header">
582                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
583                                         <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
584                                 </div>
585                                 <div class="modal-body">
586                                                 <div class="p">
587                                                 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> is the fastest way to visualize metrics. It is a resource efficient, highly optimized system for collecting and visualizing any type of real-time time series data, from CPU usage, disk activity, SQL queries, API calls, web site visitors, etc.
588                                                 </div>
589                                                 <div class="p">
590                                                 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> tries to visualize the truth of <b>now</b>, in its <b>greatest detail</b>, so that you can get insights of what is happening now and what just happened, on your systems and applications.
591                                                 </div>
592                                                 <div class="p">
593                                                 To make a chart in <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>, you just need a <b>number</b>. Just a number you can read somehow. <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> will turn this number to a real time, interactive, web chart. For collecting these numbers, it supports <a href="https://github.com/firehol/netdata/wiki/External-Plugins" target="_blank">external plugins</a>, even <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">shell</a> or <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">node.js</a> plugins. Any computer program, in any language, that can print a few lines of text on its standard output, can be a netdata data collector.
594                                                 </div>
595                                                 <div class="p">
596                                                 <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> can embed charts everywhere, like this one <div data-netdata="system.cpu" data-dimensions="system" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-system-at="system.cpu.system.modal.1"></div> (my CPU system usage which is <span id="system.cpu.system.modal.1" style="display: inline-block; width: 40px; text-align: right;"></span>%),
597                                                 or this one <div data-netdata="ipv4.tcppackets" data-dimensions="received" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-received-at="ipv4.tcppackets.received.modal.1"></div> (my IPv4 received TCP packets, which are <span id="ipv4.tcppackets.received.modal.1" style="display: inline-block; width: 60px; text-align: right;"></span>/second).
598                                                 </div>
599                                                 <div class="p">
600                                                 You can have <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> charts on your site too. Just give it a <code>div</code> and a real time chart, zoomable and draggable will appear (try it even on these tiny ones - <b>drag</b> them to pan horizontally, <b>shift + drag</b> to zoom in, on <b>chrome shift + mouse wheel</b> to zoom in/out, <b>double click</b> on them to reset them - don't be afraid of <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> performance - <a href="https://github.com/firehol/netdata/wiki/Performance" target="_blank">a raspberry pi 2 can sustain 300 charts updates per second</a>!).
601                                                 </div>
602                                                 <div class="p">
603                                                 For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
604                                                 </div>
605                                 </div>
606                                 <div class="modal-footer">
607                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
608                                 </div>
609                         </div>
610                 </div>
611         </div>
612
613         <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
614                 <div class="modal-dialog modal-lg" role="document">
615                         <div class="modal-content">
616                                 <div class="modal-header">
617                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
618                                         <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
619                                 </div>
620                                 <div class="modal-body">
621
622                                         <h4>Dygraphs (line, area and stacked area charts)</h4>
623
624                                         <!-- Nav tabs -->
625                                         <ul class="nav nav-tabs" role="tablist">
626                                                 <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
627                                                 <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
628                                         </ul>
629
630                                         <!-- Tab panes -->
631                                         <div class="tab-content">
632                                                 <div role="tabpanel" class="tab-pane active" id="help_mouse">
633                                                         <div class="p">
634                                                                 <h4>Mouse Over / Hover</h4>
635                                                                 Mouse over on a chart to show, at its legend, the values for the timestamp under the mouse (the chart will also highlight the point at the chart).
636                                                                 <br/>
637                                                                 All the other visible charts will also show and highlight their values for the same timestamp.
638                                                         </div>
639                                                         <hr/>
640                                                         <div class="p">
641                                                                 <h4>Drag Chart Contents</h4>
642                                                                 Drag the contents of a chart to pan it horizontally.
643                                                                 <br/>
644                                                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
645                                                                 <br/>
646                                                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
647                                                         </div>
648                                                         <hr/>
649                                                         <div class="p">
650                                                                 <h4>Double Click</h4>
651                                                                 Double Click a chart to reset all the charts to their default auto-refreshing state.
652                                                         </div>
653                                                         <hr/>
654                                                         <div class="p">
655                                                                 <h4>SHIFT + Drag</h4>
656                                                                 While pressing the shift key, click on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
657                                                                 <ul>
658                                                                         <li>The already loaded chart contents are zoomed (low resolution)</li>
659                                                                         <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
660                                                                 </ul>
661                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
662                                                         </div>
663                                                         <hr/>
664                                                         <div class="p">
665                                                                 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
666                                                                 While pressing the shift key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
667                                                                 <br/>
668                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
669                                                         </div>
670                                                         <hr/>
671                                                         <div class="p">
672                                                                 <h4>Legend Operations</h4>
673                                                                 Click on the label or value of a dimension, will select / un-select this dimension.
674                                                                 <br/>
675                                                                 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
676                                                         </div>
677                                                 </div>
678                                                 <div role="tabpanel" class="tab-pane" id="help_touch">
679                                                         <div class="p">
680                                                                 <h4>Single Tap</h4>
681                                                                 Single Tap on the contents of a chart to show, at its legend, the values for the timestamp tapped (the chart will also highlight the point at the chart).
682                                                                 <br/>
683                                                                 All the other visible charts will also show and highlight their values for the same timestamp.
684                                                         </div>
685                                                         <hr/>
686                                                         <div class="p">
687                                                                 <h4>Drag Chart Contents</h4>
688                                                                 Touch and Drag the contents of a chart to pan it horizontally.
689                                                                 <br/>
690                                                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
691                                                                 <br/>
692                                                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
693                                                         </div>
694                                                         <hr/>
695                                                         <div class="p">
696                                                                 <h4>Double Tap</h4>
697                                                                 Double tap a chart to reset all the charts to their default auto-refreshing state.
698                                                         </div>
699                                                         <hr/>
700                                                         <div class="p">
701                                                                 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
702                                                                 With two fingers, zoom in or out.
703                                                                 <br/>
704                                                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
705                                                         </div>
706                                                         <hr/>
707                                                         <div class="p">
708                                                                 <h4>Legend Operations</h4>
709                                                                 Tap on the label or value of a dimension, will select / un-select this dimension.
710                                                         </div>
711                                                 </div>
712                                         </div>
713                                 </div>
714                                 <div class="modal-footer">
715                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
716                                 </div>
717                         </div>
718                 </div>
719         </div>
720
721         <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
722                 <div class="modal-dialog modal-lg" role="document">
723                         <div class="modal-content">
724                                 <div class="modal-header">
725                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
726                                         <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
727                                 </div>
728                                 <div class="modal-body">
729                                         <center>
730                                                 <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
731                                                 <br/>
732                                                 Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
733                                                 <br/>
734                                                 To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
735                                         </center>
736                                         <div style="padding: 10px;"></div>
737
738                                         <!-- Nav tabs -->
739                                         <ul class="nav nav-tabs" role="tablist">
740                                                 <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
741                                                 <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
742                                                 <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
743                                         </ul>
744
745                                         <!-- Tab panes -->
746                                         <div class="tab-content">
747                                                 <div role="tabpanel" class="tab-pane active" id="settings_performance">
748                                                         <form id="optionsForm1" method="get" class="form-horizontal">
749                                                                 <div class="form-group">
750                                                                         <table>
751                                                                         <tr class="option-row">
752                                                                                 <td class="option-control"><input id="stop_updates_when_focus_is_lost" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="On Focus" data-off="Always" data-width="110px"></td>
753                                                                                 <td class="option-info"><strong>When to refresh the charts?</strong><br/>
754                                                                                         <small>When set to <b>On Focus</b>, the charts will stop being updated if the page / tab does not have the focus of the user. When set to <b>Always</b>, the charts will always be refreshed. Set it to <b>On Focus</b> it to lower the CPU requirements of the browser (and extend the battery of laptops and tablets) when this page does not have your focus. Set to <b>Always</b> to work on another window (i.e. change the settings of something) and have the charts auto-refresh in this window.</small>
755                                                                                 </td>
756                                                                                 </tr>
757                                                                         <tr class="option-row">
758                                                                                 <td class="option-control">
759                                                                                 <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
760                                                                                 </td>
761                                                                                 <td class="option-info"><strong>Which dimensions to show?</strong><br/>
762                                                                                         <small>When set to <b>Non Zero</b>, dimensions that have all their values (within the current view) set to zero will not be transferred from the netdata server (except if all dimensions of the chart are zero, in which case this setting does nothing - all dimensions are transferred and shown). When set to <b>All</b>, all dimensions will always be shown. Set it to <b>Non Zero</b> to lower the data transferred between netdata and your browser, lower the CPU requirements of your browser (fewer lines to draw) and increase the focus on the legends (fewer entries at the legends).</small>
763                                                                                 </td>
764                                                                                 </tr>
765                                                                         <tr class="option-row">
766                                                                                 <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
767                                                                                 <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
768                                                                                         <small>When set to <b>Destroy</b>, charts that are not in the current viewport of the browser (are above, or below the visible area of the page), will be destroyed and re-created if and when they become visible again. When set to <b>Hide</b>, the not-visible charts will be just hidden, to simplify the DOM and speed up your browser. Set it to <b>Destroy</b>, to lower the memory requirements of your browser. Set it to <b>Hide</b> for smoother page scrolling.</small>
769                                                                                 </td>
770                                                                                 </tr>
771                                                                         </table>
772                                                                 </div>
773                                                         </form>
774                                                 </div>
775                                                 <div role="tabpanel" class="tab-pane" id="settings_sync">
776                                                         <form id="optionsForm2" method="get" class="form-horizontal">
777                                                                 <div class="form-group">
778                                                                         <table>
779                                                                         <tr class="option-row">
780                                                                                 <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
781                                                                                 <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
782                                                                                         <small>When set to <b>parallel</b>, visible charts are refreshed in parallel (all queries are sent to netdata server in parallel) and are rendered asynchronously. When set to <b>sequential</b> charts are refreshed one after another. Set it to parallel if your browser can cope with it (most modern browsers do), set it to sequential if you work on an older/slower computer.</small>
783                                                                                 </td>
784                                                                                 </tr>
785                                                                         <tr class="option-row" id="concurrent_refreshes_row">
786                                                                                 <td class="option-control"></td>
787                                                                                 <td class="option-info">
788                                                                                         <table>
789                                                                                         <tr class="option-row">
790                                                                                         <td class="option-control">
791                                                                                         <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
792                                                                                         </td>
793                                                                                         <td class="option-info">
794                                                                                         <strong>Shall we re-sync chart refreshes?</strong><br/>
795                                                                                         <small>When set to <b>Resync</b>, the dashboard will attempt to re-synchronize all the charts so that they are refreshed concurrently. When set to <b>Best Effort</b>, each chart may be refreshed with a little time difference to the others. Normally, the dashboard starts refreshing them in parallel, but depending on the speed of your computer and the network latencies, charts start having a slight time difference. Setting this to <b>Resync</b> will attempt to re-synchronize the charts on every update. Setting it to <b>Best Effort</b> may lower the pressure on your browser and the network.</small>
796                                                                                         </td>
797                                                                                         </tr>
798                                                                                         </table>
799                                                                                 </td>
800                                                                                 </tr>
801                                                                         <tr class="option-row">
802                                                                                 <td class="option-control"><input id="sync_selection" type="checkbox" checked data-toggle="toggle" data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
803                                                                                 <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
804                                                                                         <small>When enabled, a selection on one chart will automatically select the same time on all other visible charts and the legends of all visible charts will be updated to show the selected values. When disabled, only the chart getting the user's attention will be selected. Enable it to get better insights of the data. Disable it if you are on a very slow computer that cannot actually do it.</small>
805                                                                                 </td>
806                                                                                 </tr>
807                                                                         <tr class="option-row">
808                                                                                 <td class="option-control"><input id="sync_pan_and_zoom" type="checkbox" checked data-toggle="toggle"  data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
809                                                                                 <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
810                                                                                         <small>When enabled, pan and zoom operations on a chart will be replicated to all charts (even the ones that are not currently visible - of course only when they will become visible). When disabled, pan and zoom operations will not be propagated to other charts.</small>
811                                                                                 </td>
812                                                                                 </tr>
813                                                                         </table>
814                                                                 </div>
815                                                         </form>
816                                                 </div>
817                                                 <div role="tabpanel" class="tab-pane" id="settings_visual">
818                                                         <form id="optionsForm3" method="get" class="form-horizontal">
819                                                                 <div class="form-group">
820                                                                         <table>
821                                                                         <tr class="option-row">
822                                                                                 <td class="option-control"><input id="netdata_theme_control" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="Dark" data-off="White" data-width="110px"></td>
823                                                                                 <td class="option-info"><strong>Which theme to use?</strong><br/>
824                                                                                         <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
825                                                                                         <br/>
826                                                                                         <b>Switching this will reload the dashboard</b>.
827                                                                                         </small>
828                                                                                 </td>
829                                                                                 </tr>
830                                                                         <tr class="option-row">
831                                                                                 <td class="option-control"><input id="show_help" type="checkbox" checked data-toggle="toggle" data-on="Help Me" data-off="No Help" data-width="110px"></td>
832                                                                                 <td class="option-info"><strong>Do you need help?</strong><br/>
833                                                                                         <small>Netdata can show some help in some areas to help you use the dashboard. If all these balloons bother you, disable them using this switch.
834                                                                                         <br/>
835                                                                                         <b>Switching this will reload the dashboard</b>.
836                                                                                         </small>
837                                                                                 </td>
838                                                                                 </tr>
839                                                                         <tr class="option-row">
840                                                                                 <td class="option-control"><input id="pan_and_zoom_data_padding" type="checkbox" checked data-toggle="toggle"  data-on="Pad" data-off="Don't Pad" data-width="110px"></td>
841                                                                                 <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
842                                                                                         <small>When set to <b>Pad</b> the charts will be padded with more data, both before and after the visible area, thus giving the impression the whole database is loaded. This padding will happen only after the first pan or zoom operation on the chart (initially all charts have only the visible data). When set to <b>Don't Pad</b> only the visible data will be transfered from the netdata server, even after the first pan and zoom operation.</small>
843                                                                                 </td>
844                                                                                 </tr>
845                                                                         <tr class="option-row">
846                                                                                 <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle"  data-on="Smooth" data-off="Rough" data-width="110px"></td>
847                                                                                 <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
848                                                                                         <small>When set to <b>Smooth</b> the charts libraries that support it, will plot smooth curves instead of simple straight lines to connect the points.
849                                                                                         <br/>
850                                                                                         Keep in mind <a href="http://dygraphs.com" target="_blank">dygraphs</a>, the main charting library in netdata dashboards, can only smooth line charts. It cannot smooth area or stacked charts. When set to <b>Rough</b>, this setting can lower the CPU resources consumed by your browser.</small>
851                                                                                 </td>
852                                                                                 </tr>
853                                                                         </table>
854                                                                 </div>
855                                                         </form>
856                                                 </div>
857                                         </div>
858                                 </div>
859                                 <div class="modal-footer">
860                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
861                                 </div>
862                         </div>
863                 </div>
864         </div>
865
866
867         <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
868                 <div class="modal-dialog" role="document">
869                         <div class="modal-content">
870                                 <div class="modal-header">
871                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
872                                         <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
873                                 </div>
874                                 <div class="modal-body">
875                                         Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
876                                         <br/>
877                                         <div style="padding: 10px;"></div>
878                                         <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
879                                 </div>
880                                 <div class="modal-footer">
881                                         <a href="#" onclick="notifyForUpdate(true);" type="button" class="btn btn-default">Check Now</a>
882                                         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
883                                 </div>
884                         </div>
885                 </div>
886         </div>
887
888         <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
889                 <div class="modal-dialog" role="document">
890                         <div class="modal-content">
891                                 <div class="modal-header">
892                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
893                                         <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
894                                 </div>
895                                 <div class="modal-body">
896                                         You are about to delete, from your personal list of netdata servers, the following server:
897                                         <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
898                                         <b><span id="deleteRegistryServerName2"></span></b>
899                                         <br/>
900                                         <b><span id="deleteRegistryServerURL"></span></b>
901                                         </p>
902                                         Are you sure you want to do this?
903                                         <br/>
904                                         <div style="padding: 10px;"></div>
905                                         <small>Keep in mind, this server will be added back if and when you visit it again.</small>
906                                         <br/>
907                                         <div id="deleteRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px; color: #fff;"></div>
908                                 </div>
909                                 <div class="modal-footer">
910                                         <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
911                                         <a href="#" onclick="notifyForDeleteRegistry(true); return false;" type="button" class="btn btn-danger">delete it</a>
912                                 </div>
913                         </div>
914                 </div>
915         </div>
916
917         <div class="modal fade" id="switchRegistryModal" tabindex="-1" role="dialog" aria-labelledby="switchRegistryModalLabel">
918                 <div class="modal-dialog" role="document">
919                         <div class="modal-content">
920                                 <div class="modal-header">
921                                         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
922                                         <h4 class="modal-title" id="switchRegistryModalLabel">Switch Netdata Registry Identity</h4>
923                                 </div>
924                                 <div class="modal-body">
925                                         You can copy and paste the following ID to all your browsers (e.g. work and home).
926                                         <br/>
927                                         All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
928                                         <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
929                                         <form action="#">
930                                         <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
931                                         </form>
932                                         </p>
933                                         Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
934                                         <p style="padding-top: 10px;"><small>
935                                                 Keep in mind that:
936                                                 <ul>
937                                                         <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li>
938                                                         <li>both IDs (your old and the new) must list this netdata at their personal lists.</li>
939                                                         <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li>
940                                                         <li>to get a new ID, just clear your browser cookies.</li>
941                                                 </ul>
942                                         </small></p>
943                                         <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px; color: #fff;"></div>
944                                 </div>
945                                 <div class="modal-footer">
946                                         <button type="button" class="btn btn-success" data-dismiss="modal">cancel</button>
947                                         <a href="#" onclick="notifyForSwitchRegistry(true); return false;" type="button" class="btn btn-danger">impersonate</a>
948                                 </div>
949                         </div>
950                 </div>
951         </div>
952
953 <script>
954 var this_is_demo = null;
955 function isdemo() {
956         if(this_is_demo !== null) return this_is_demo;
957         this_is_demo = false;
958
959         try {
960                 if(typeof document.location.hostname === 'string') {
961                         if(document.location.hostname.endsWith('.my-netdata.io') ||
962                                         document.location.hostname.endsWith('.mynetdata.io') ||
963                                         document.location.hostname.endsWith('.netdata.rocks') ||
964                                         document.location.hostname.endsWith('.firehol.org') ||
965                                         document.location.hostname.endsWith('.netdata.online'))
966                                         this_is_demo = true;
967                 }
968         }
969         catch(error) {
970                 ;
971         }
972
973         return this_is_demo;
974 }
975
976 if(isdemo()) {
977         document.getElementById('masthead').style.display = 'block';
978 }
979
980 function switchRegistryModalHandler() {
981         document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
982         document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
983         $('#switchRegistryModal').modal('show');
984 }
985
986 function notifyForSwitchRegistry() {
987         var n = document.getElementById('switchRegistryPersonGUID').value;
988
989         if(n !== '' && n.length === 36) {
990                 NETDATA.registry.switch(n, function(result) {
991                         if(result !== null) {
992                                 $('#switchRegistryModal').modal('hide');
993                                 NETDATA.registry.init();
994                         }
995                         else {
996                                 document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
997                         }
998                 });
999         }
1000         else
1001                 document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
1002 }
1003
1004 var deleteRegistryUrl = null;
1005 function deleteRegistryModalHandler(guid, name, url) {
1006         deleteRegistryUrl = url;
1007         document.getElementById('deleteRegistryServerName').innerHTML = name;
1008         document.getElementById('deleteRegistryServerName2').innerHTML = name;
1009         document.getElementById('deleteRegistryServerURL').innerHTML = url;
1010         $('#deleteRegistryModal').modal('show');
1011 }
1012
1013 function notifyForDeleteRegistry() {
1014         if(deleteRegistryUrl) {
1015                 NETDATA.registry.delete(deleteRegistryUrl, function(result) {
1016                         if(result !== null) {
1017                                 deleteRegistryUrl = null;
1018                                 $('#deleteRegistryModal').modal('hide');
1019                                 NETDATA.registry.init();
1020                         }
1021                         else {
1022                                 document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
1023                         }
1024                 });
1025         }
1026 }
1027
1028 var options = {
1029         sparklines_registry: {},
1030         submenu_names: {},
1031         data: null,
1032         hostname: 'netdata_server', // will be overwritten by the netdata server
1033         categories: new Array(),
1034         categories_idx: {},
1035         families: new Array(),
1036         families_idx: {},
1037
1038         chartsPerRow: 0,
1039         chartsMinWidth: 1450,
1040         chartsHeight: 180,
1041         sparklinesHeight: 60
1042 };
1043
1044 // generate a sparkline
1045 // used in the documentation
1046 function sparkline(chart, dimension, units) {
1047         var key = chart + '.' + dimension;
1048
1049         if(typeof units === 'undefined')
1050                 units = '';
1051
1052         if(typeof options.sparklines_registry[key] === 'undefined')
1053                 options.sparklines_registry[key] = { count: 1 };
1054         else
1055                 options.sparklines_registry[key].count++;
1056
1057         key = key + '.' + options.sparklines_registry[key].count;
1058
1059         var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
1060
1061         return h;
1062 }
1063
1064 function chartsPerRow(total) {
1065         if(options.chartsPerRow === 0) {
1066                 width = Math.floor(total / options.chartsMinWidth);
1067                 if(width === 0) width = 1;
1068                 return width;
1069         }
1070         else return options.chartsPerRow;
1071 }
1072
1073 function prioritySort(a, b) {
1074         if(a.priority < b.priority) return -1;
1075         if(a.priority > b.priority) return 1;
1076         if(a.name < b.name) return -1;
1077         return 1;
1078 }
1079
1080 function sortObjectByPriority(object) {
1081         var idx = {};
1082         var sorted = new Array();
1083
1084         for(var i in object) {
1085                 if(typeof idx[i] === 'undefined') {
1086                         idx[i] = object[i];
1087                         sorted.push(i);
1088                 }
1089         }
1090
1091         sorted.sort(function(a, b) {
1092                 if(idx[a].priority < idx[b].priority) return -1;
1093                 if(idx[a].priority > idx[b].priority) return 1;
1094                 if(a < b) return -1;
1095                 return 1;
1096         });
1097
1098         return sorted;
1099 }
1100
1101 // ----------------------------------------------------------------------------
1102
1103 function gaugeChart(title, width, dimensions, colors) {
1104         if(typeof colors === 'undefined')
1105                 colors = '';
1106
1107         if(typeof dimensions === 'undefined')
1108                 dimensions = '';
1109
1110         return '<div data-netdata="CHART_UNIQUE_ID"'
1111                                                         + ' data-dimensions="' + dimensions + '"'
1112                                                         + ' data-chart-library="gauge"'
1113                                                         + ' data-gauge-adjust="width"'
1114                                                         + ' data-title="' + title + '"'
1115                                                         + ' data-width="' + width + '"'
1116                                                         + ' data-before="0"'
1117                                                         + ' data-after="-CHART_DURATION"'
1118                                                         + ' data-points="CHART_DURATION"'
1119                                                         + ' data-colors="' + colors + '"'
1120                                                         + ' role="application"></div>';
1121 }
1122
1123 // ----------------------------------------------------------------------------
1124
1125 var menuData = {
1126         'system': {
1127                 title: 'System Overview',
1128                 info: 'Overview of the key system metrics.'
1129         },
1130
1131         'ap': {
1132                 title: 'Access Points',
1133                 info: undefined
1134         },
1135
1136         'tc': {
1137                 title: 'Quality of Service',
1138                 info: 'Netdata collects and visualizes tc class utilization using its <a href="https://github.com/firehol/netdata/blob/master/plugins.d/tc-qos-helper.sh" target="_blank">tc-helper plugin</a>. If you also use <a href="http://firehol.org/#fireqos" target="_blank">FireQOS</a> for setting up QoS, netdata automatically collects interface and class names. If your QoS configuration includes overheads calculation, the values shown here will include these overheads (the total bandwidth for the same interface as reported in the Network Interfaces section, will be lower than the total bandwidth reported here). Also, data collection may have a slight time difference compared to the interface (QoS data collection is implemented with a BASH script, so a shift in data collection of a few milliseconds should be justified).'
1139         },
1140
1141         'net': {
1142                 title: 'Network Interfaces',
1143                 info: 'Per network interface statistics collected from <code>/proc/net/dev</code>.'
1144         },
1145
1146         'ipv4': {
1147                 title: 'IPv4 Networking',
1148                 info: undefined
1149         },
1150
1151         'ipv6': {
1152                 title: 'IPv6 Networking',
1153                 info: undefined
1154         },
1155
1156         'ipvs': {
1157                 title: 'IP Virtual Server',
1158                 info: undefined
1159         },
1160
1161         'netfilter': {
1162                 title: 'Firewall (netfilter)',
1163                 info: undefined
1164         },
1165
1166         'cpu': {
1167                 title: 'CPUs',
1168                 info: undefined
1169         },
1170
1171         'mem': {
1172                 title: 'Memory',
1173                 info: undefined
1174         },
1175
1176         'disk': {
1177                 title: 'Disks',
1178                 info: undefined
1179         },
1180
1181         'sensors': {
1182                 title: 'Sensors',
1183                 info: undefined
1184         },
1185
1186         'nfsd': {
1187                 title: 'File Server (nfsd)',
1188                 info: undefined
1189         },
1190
1191         'apps': {
1192                 title: 'Applications',
1193                 info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported).<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1194                 height: 1.5
1195         },
1196
1197         'users': {
1198                 title: 'Users',
1199                 info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1200                 height: 1.5
1201         },
1202
1203         'groups': {
1204                 title: 'User Groups',
1205                 info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group.<br/><b>IMPORTANT</b>: The values shown here are not 100% accurate. They only include values for the processes running. If an application is spawning children continuously, which are terminated in just a few milliseconds (like shell scripts do), the values reported will be inaccurate. Linux does report the values for the exited children of a process. However, these values are reported to the parent process <b>only when the child exits</b>. If these values, of the exited child processes, were also aggregated in the charts below, the charts would have been full of spikes, presenting unrealistic utilization for each process group. So, we decided to ignore these values and present only the utilization of <b>the currently running processes</b>.',
1206                 height: 1.5
1207         },
1208
1209         'netdata': {
1210                 title: 'Netdata Monitoring',
1211                 info: undefined
1212         },
1213
1214         'example': {
1215                 title: 'Example Charts',
1216                 info: undefined
1217         },
1218
1219         'cgroup': {
1220                 title: 'Container',
1221                 info: undefined
1222         },
1223
1224         'mysql': {
1225                 title: 'MySQL',
1226                 info: undefined
1227         },
1228
1229         'named': {
1230                 title: 'named',
1231                 info: undefined
1232         },
1233 };
1234
1235 var submenuData = {
1236         'mem.ksm': {
1237                 title: 'Memory Deduper',
1238                 info: 'Kernel Same-page Merging (KSM) performance monitoring, read from several files in <code>/sys/kernel/mm/ksm/</code>. KSM is a memory-saving de-duplication feature in the Linux kernel (since version 2.6.32). The KSM daemon ksmd periodically scans those areas of user memory which have been registered with it, looking for pages of identical content which can be replaced by a single write-protected page (which is automatically copied if a process later wants to update its content). KSM was originally developed for use with KVM (where it was known as Kernel Shared Memory), to fit more virtual machines into physical memory, by sharing the data common between them.  But it can be useful to any application which generates many instances of the same data.'
1239         },
1240
1241         'netfilter.conntrack': {
1242                 title: 'Connection Tracker',
1243                 info: 'Netfilter Connection Tracker performance monitoring, read from <code>/proc/net/stat/nf_conntrack</code>. The connection tracker keeps track of all connections of the machine, inbound and outbound. It works by keeping a database with all open connections, tracking network and address translation and connection expectations.'
1244         },
1245
1246         'netfilter.nfacct': {
1247                 title: 'Bandwidth Accounting',
1248                 info: 'The following information is read using the <code>nfacct.plugin</code>.'
1249         },
1250
1251         'netfilter.synproxy': {
1252                 title: 'DDoS Protection',
1253                 info: 'DDoS Protection performance monitoring read from <code>/proc/net/stat/synproxy</code>. <a href="https://github.com/firehol/firehol/wiki/Working-with-SYNPROXY" target="_blank">SYNPROXY</a> is a TCP SYN packets proxy. It is used to protect any TCP server (like a web server) from SYN floods and similar DDoS attacks. It is a netfilter module, in the Linux kernel (since version 3.12). It is optimized to handle millions of packets per second utilizing all CPUs available without any concurrency locking between the connections. It can be used for any kind of TCP traffic (even encrypted), since it does not interfere with the content itself.'
1254         }
1255 };
1256
1257 var chartData = {
1258         'system.cpu': {
1259                 info: 'Total CPU utilization (all cores). 100% here means there is no CPU idle time at all. You can get per core usage at the <a href="#cpu">CPUs</a> section and per application usage at the <a href="#apps">Applications Monitoring</a> section.<br/>Keep an eye on <b>iowait</b> ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.<br/>Another important metric worth monitoring, is <b>softirq</b> ' + sparkline('system.cpu', 'softirq', '%') + '. A constantly high percentage of softirq may indicate network drivers issues.'
1260         },
1261
1262         'system.load': {
1263                 info: 'Current system load read from <code>/proc/loadavg</code>.',
1264                 height: 0.7
1265         },
1266
1267         'system.io': {
1268                 info: 'Total Disk I/O, for all disks, read from <code>/proc/vmstat</code>. You can get detailed information about each disk at the <a href="#disk">Disks</a> section and per application Disk usage at the <a href="#apps">Applications Monitoring</a> section.'
1269         },
1270
1271         'system.swapio': {
1272                 info: 'Total Swap I/O, read from <code>/proc/vmstat</code>. (netdata measures both <code>in</code> and <code>out</code>. If either of them is not shown in the chart, it is because it is zero - you can change the page settings to always render all the available dimensions on all charts).'
1273         },
1274
1275         'system.pgfaults': {
1276                 info: 'Total page faults, read from <code>/proc/vmstat</code>. <b>Major page faults</b> indicates that the system is using its swap. You can find which applications use the swap at the <a href="#apps">Applications Monitoring</a> section.'
1277         },
1278
1279         'system.entropy': {
1280                 colors: '#CC22AA',
1281                 info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, read from <code>/proc/sys/kernel/random/entropy_avail</code>, is like a pool of random numbers that are mainly used in cryptography. It is advised that the pool remains always <a href="https://blog.cloudflare.com/ensuring-randomness-with-linuxs-random-number-generator/" target="_blank">above 200</a>. If the pool of entropy gets empty, you risk your security to be predictable and you should install a user-space random numbers generating daemon, like <a href="http://www.issihosts.com/haveged/" target="_blank">haveged</a>, to keep the pool in healthy levels.'
1282         },
1283
1284         'system.forks': {
1285                 colors: '#5555DD',
1286                 info: 'The number of new processes created per second, read from <code>/proc/stat</code>.'
1287         },
1288
1289         'system.intr': {
1290                 colors: '#DD5555',
1291                 info: 'Total number of CPU interrupts, read from <code>/proc/stat</code>. Check <code>system.interrupts</code> that gives more detail about each interrupt and also the <a href="#cpu">CPUs</a> section where interrupts are analyzed per CPU core.'
1292         },
1293
1294         'system.interrupts': {
1295                 info: 'CPU interrupts in detail, read from <code>/proc/interrupts</code>. At the <a href="#cpu">CPUs</a> section, interrupts are analyzed per CPU core.'
1296         },
1297
1298         'system.softirqs': {
1299                 info: 'CPU softirqs in detail, read from <code>/proc/softirqs</code>. At the <a href="#cpu">CPUs</a> section, softirqs are analyzed per CPU core.'
1300         },
1301
1302         'system.processes': {
1303                 info: 'System processes, read from <code>/proc/stat</code>. <b>Blocked</b> are processes that are willing to execute but they cannot, e.g. because they wait for disk activity.'
1304         },
1305
1306         'system.active_processes': {
1307                 info: 'All system active processes, read from <code>/proc/loadavg</code>.'
1308         },
1309
1310         'system.ctxt': {
1311                 info: '<a href="https://en.wikipedia.org/wiki/Context_switch" target="_blank">Context Switches</a>, read from <code>/proc/stat</code>, is the switching of the CPU from one process, task or thread to another. If there are many processes or threads willing to execute and very few CPU cores available to handle them, the system is making more context switching to balance the CPU resources among them. The whole process is computationally intensive. The more the context switches, the slower the system gets.'
1312         },
1313
1314         'system.idlejitter': {
1315                 colors: '#5555AA',
1316                 info: 'Idle jitter is calculated by netdata. A thread is spawned that requests to sleep for a few microseconds. When the system wakes it up, it measures how many microseconds have passed. The difference between the requested and the actual duration of the sleep, is the <b>idle jitter</b>. This number is useful in real-time environments, where CPU jitter can affect the quality of the service (like VoIP media gateways).'
1317         },
1318
1319         'system.ipv4': {
1320                 info: 'Total IPv4 Traffic, read from <code>/proc/net/netstat</code>.'
1321         },
1322
1323         'system.ipv6': {
1324                 info: 'Total IPv6 Traffic, read from <code>/proc/net/snmp6</code>.'
1325         },
1326
1327         'system.ram': {
1328                 info: 'System memory, read from <code>/proc/meminfo</code>.'
1329         },
1330
1331         'system.swap': {
1332                 info: 'System swap memory, read from <code>/proc/meminfo</code>.'
1333         },
1334
1335         'mem.ksm_savings': {
1336                 heads: [
1337                         gaugeChart('Saved', '12%', 'savings', '#0099CC')
1338                 ]
1339         },
1340
1341         'mem.ksm_ratios': {
1342                 heads: [
1343                         function(id) {
1344                                 return  '<div data-netdata="' + id + '"'
1345                                         + ' data-gauge-max-value="100"'
1346                                         + ' data-chart-library="gauge"'
1347                                         + ' data-title="Savings"'
1348                                         + ' data-units="percentage %"'
1349                                         + ' data-gauge-adjust="width"'
1350                                         + ' data-width="12%"'
1351                                         + ' data-before="0"'
1352                                         + ' data-after="-CHART_DURATION"'
1353                                         + ' data-points="CHART_DURATION"'
1354                                         + ' role="application"></div>';
1355                         }
1356                 ]
1357         },
1358
1359         'mem.committed': {
1360                 colors: NETDATA.colors[3]
1361         },
1362
1363         'apps.cpu': {
1364                 height: 2.0
1365         },
1366
1367         'apps.preads': {
1368                 height: 2.0
1369         },
1370
1371         'apps.pwrites': {
1372                 height: 2.0
1373         },
1374
1375         'users.cpu': {
1376                 height: 2.0
1377         },
1378
1379         'users.preads': {
1380                 height: 2.0
1381         },
1382
1383         'users.pwrites': {
1384                 height: 2.0
1385         },
1386
1387         'groups.cpu': {
1388                 height: 2.0
1389         },
1390
1391         'groups.preads': {
1392                 height: 2.0
1393         },
1394
1395         'groups.pwrites': {
1396                 height: 2.0
1397         },
1398
1399         'tc.qos': {
1400                 heads: [
1401                         function(id) {
1402                                 if(id.match(/.*-ifb$/))
1403                                         return gaugeChart('Inbound', '12%', '', '#5555AA');
1404                                 else
1405                                         return gaugeChart('Outbound', '12%', '', '#AA9900');
1406                         }
1407                 ]
1408         },
1409
1410         'net.net': {
1411                 heads: [
1412                         gaugeChart('Received', '12%', 'received'),
1413                         gaugeChart('Sent', '12%', 'sent')
1414                 ]
1415         },
1416
1417         'disk.util': {
1418                 colors: '#FF5588',
1419                 heads: [
1420                         gaugeChart('Utilization', '12%', '', '#FF5588')
1421                 ]
1422         },
1423
1424         'disk.backlog': {
1425                 colors: '#0099CC'
1426         },
1427
1428         'disk.io': {
1429                 heads: [
1430                         gaugeChart('Read', '12%', 'reads'),
1431                         gaugeChart('Write', '12%', 'writes')
1432                 ]
1433         },
1434
1435         'netfilter.sockets': {
1436                 colors: '#88AA00',
1437                 heads: [
1438                         gaugeChart('Active Connections', '12%', '', '#88AA00')
1439                 ]
1440         },
1441
1442         'netfilter.new': {
1443                 heads: [
1444                         gaugeChart('New Connections', '12%', 'new', '#5555AA')
1445                 ]
1446         },
1447
1448         'disk.iotime': {
1449                 height: 0.5
1450         },
1451         'disk.mops': {
1452                 height: 0.5
1453         },
1454         'disk.svctm': {
1455                 height: 0.5
1456         },
1457         'disk.avgsz': {
1458                 height: 0.5
1459         },
1460         'disk.await': {
1461                 height: 0.5
1462         },
1463
1464         'apache.connections': {
1465                 colors: NETDATA.colors[4],
1466                 mainheads: [
1467                         gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1468                 ]
1469         },
1470
1471         'apache.requests': {
1472                 colors: NETDATA.colors[0],
1473                 mainheads: [
1474                         gaugeChart('Connections', '12%', '', NETDATA.colors[0])
1475                 ]
1476         },
1477
1478         'apache.net': {
1479                 colors: NETDATA.colors[3],
1480                 mainheads: [
1481                         gaugeChart('Bandwidth', '12%', '', NETDATA.colors[3])
1482                 ]
1483         },
1484
1485         'apache.workers': {
1486                 mainheads: [
1487                         function(id) {
1488                                 return  '<div data-netdata="' + id + '"'
1489                                         + ' data-dimensions="busy"'
1490                                         + ' data-append-options="percentage"'
1491                                         + ' data-gauge-max-value="100"'
1492                                         + ' data-chart-library="gauge"'
1493                                         + ' data-title="Workers Utilization"'
1494                                         + ' data-units="percentage %"'
1495                                         + ' data-gauge-adjust="width"'
1496                                         + ' data-width="12%"'
1497                                         + ' data-before="0"'
1498                                         + ' data-after="-CHART_DURATION"'
1499                                         + ' data-points="CHART_DURATION"'
1500                                         + ' role="application"></div>';
1501                         }
1502                 ]
1503         },
1504
1505         'apache.bytesperreq': {
1506                 colors: NETDATA.colors[3],
1507                 height: 0.5
1508         },
1509
1510         'apache.reqpersec': {
1511                 colors: NETDATA.colors[4],
1512                 height: 0.5
1513         },
1514
1515         'apache.bytespersec': {
1516                 colors: NETDATA.colors[6],
1517                 height: 0.5
1518         },
1519
1520         'nginx.connections': {
1521                 colors: NETDATA.colors[4],
1522                 mainheads: [
1523                         gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1524                 ]
1525         },
1526
1527         'nginx.requests': {
1528                 colors: NETDATA.colors[0],
1529                 mainheads: [
1530                         gaugeChart('Requests', '12%', '', NETDATA.colors[0])
1531                 ]
1532         }
1533 };
1534
1535 function anyAttribute(obj, attr, key, def) {
1536         if(typeof obj[key] !== 'undefined') {
1537                 if(typeof obj[key][attr] !== 'undefined')
1538                         return obj[key][attr];
1539         }
1540         return def;
1541 }
1542
1543 function menuTitle(chart) {
1544         if(typeof chart.menu_pattern !== 'undefined') {
1545                 return anyAttribute(menuData, 'title', chart.menu_pattern, chart.menu_pattern).toString()
1546                                 + ': ' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString();
1547         }
1548
1549         return anyAttribute(menuData, 'title', chart.menu, chart.menu);
1550 }
1551
1552 function menuInfo(menu) {
1553         return anyAttribute(menuData, 'info', menu, null);
1554 }
1555
1556 function menuHeight(menu, relative) {
1557         return anyAttribute(menuData, 'height', menu, 1.0) * relative;
1558 }
1559
1560 function submenuTitle(menu, submenu) {
1561         var key = menu + '.' + submenu;
1562         return anyAttribute(submenuData, 'title', key, submenu);
1563 }
1564
1565 function submenuInfo(menu, submenu) {
1566         var key = menu + '.' + submenu;
1567         return anyAttribute(submenuData, 'info', key, null);
1568 }
1569
1570 function submenuHeight(menu, submenu, relative) {
1571         var key = menu + '.' + submenu;
1572         return anyAttribute(submenuData, 'height', key, 1.0) * relative;
1573 }
1574
1575
1576 function chartInfo(id) {
1577         if(typeof chartData[id] !== 'undefined' && typeof chartData[id].info !== 'undefined')
1578                 return '<div class="chart-message netdata-chart-alignment" role="document">' + chartData[id].info + '</div>';
1579         else
1580                 return '';
1581 }
1582
1583 function chartHeight(id, def) {
1584         if(typeof chartData[id] !== 'undefined' && typeof chartData[id].height !== 'undefined')
1585                 return def * chartData[id].height;
1586         else
1587                 return def;
1588 }
1589
1590
1591 // ----------------------------------------------------------------------------
1592
1593 // enrich the data structure returned by netdata
1594 // to reflect our menu system and content
1595 function enrichChartData(chart) {
1596         var tmp = chart.type.split('_')[0];
1597
1598         switch(tmp) {
1599                 case 'ap':
1600                 case 'net':
1601                 case 'disk':
1602                         chart.menu = tmp;
1603                         break;
1604
1605                 case 'mysql':
1606                 case 'named':
1607                 case 'cgroup':
1608                         chart.menu = chart.type;
1609                         chart.menu_pattern = tmp;
1610                         break;
1611
1612                 case 'tc':
1613                         chart.menu = tmp;
1614
1615                         // find a name for this device from fireqos info
1616                         // we strip '_(in|out)' or '(in|out)_'
1617                         if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
1618                                 var n = chart.name.split('.')[1];
1619                                 if(n.endsWith('_in'))
1620                                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
1621                                 else if(n.endsWith('_out'))
1622                                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
1623                                 else if(n.startsWith('in_'))
1624                                         options.submenu_names[chart.family] = n.slice(3, n.length);
1625                                 else if(n.startsWith('out_'))
1626                                         options.submenu_names[chart.family] = n.slice(4, n.length);
1627                         }
1628
1629                         // increase the priority of IFB devices
1630                         // to have inbound appear before outbound
1631                         if(chart.id.match(/.*-ifb$/))
1632                                 chart.priority--;
1633
1634                         break;
1635
1636                 default:
1637                         chart.menu = chart.type;
1638                         break;
1639         }
1640
1641         chart.submenu = chart.family;
1642 }
1643
1644 // ----------------------------------------------------------------------------
1645
1646 function name2id(s) {
1647         return s
1648                 .replace(/ /g, '_')
1649                 .replace(/\(/g, '_')
1650                 .replace(/\)/g, '_')
1651                 .replace(/\./g, '_')
1652                 .replace(/\//g, '_');
1653 }
1654
1655 function headMain(charts, duration) {
1656         var head = '';
1657
1658         if(typeof charts['system.swap'] !== 'undefined')
1659                 head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
1660                 + ' data-dimensions="free"'
1661                 + ' data-append-options="percentage"'
1662                 + ' data-chart-library="easypiechart"'
1663                 + ' data-title="Free Swap"'
1664                 + ' data-units="%"'
1665                 + ' data-easypiechart-max-value="100"'
1666                 + ' data-width="8%"'
1667                 + ' data-before="0"'
1668                 + ' data-after="-' + duration.toString() + '"'
1669                 + ' data-points="' + duration.toString() + '"'
1670                 + ' data-colors="#DD4400"'
1671                 + ' role="application"></div>';
1672
1673         if(typeof charts['system.io'] !== 'undefined') {
1674                 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1675                 + ' data-dimensions="in"'
1676                 + ' data-chart-library="easypiechart"'
1677                 + ' data-title="Disk Read"'
1678                 + ' data-units="KB / s"'
1679                 + ' data-width="10%"'
1680                 + ' data-before="0"'
1681                 + ' data-after="-' + duration.toString() + '"'
1682                 + ' data-points="' + duration.toString() + '"'
1683                 + ' role="application"></div>';
1684
1685                 head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1686                 + ' data-dimensions="out"'
1687                 + ' data-chart-library="easypiechart"'
1688                 + ' data-title="Disk Write"'
1689                 + ' data-units="KB / s"'
1690                 + ' data-width="10%"'
1691                 + ' data-before="0"'
1692                 + ' data-after="-' + duration.toString() + '"'
1693                 + ' data-points="' + duration.toString() + '"'
1694                 + ' role="application"></div>';
1695         }
1696
1697         if(typeof charts['system.cpu'] !== 'undefined')
1698                 head += '<div data-netdata="system.cpu"'
1699                 + ' data-chart-library="gauge"'
1700                 + ' data-title="CPU"'
1701                 + ' data-units="%"'
1702                 + ' data-gauge-max-value="100"'
1703                 + ' data-width="18%"'
1704                 + ' data-after="-' + duration.toString() + '"'
1705                 + ' data-points="' + duration.toString() + '"'
1706                 + ' data-colors="' + NETDATA.colors[12] + '"'
1707                 + ' role="application"></div>';
1708
1709         if(typeof charts['system.ipv4'] !== 'undefined') {
1710                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1711                 + ' data-dimensions="received"'
1712                 + ' data-chart-library="easypiechart"'
1713                 + ' data-title="IPv4 Inbound"'
1714                 + ' data-units="kbps"'
1715                 + ' data-width="10%"'
1716                 + ' data-before="0"'
1717                 + ' data-after="-' + duration.toString() + '"'
1718                 + ' data-points="' + duration.toString() + '"'
1719                 + ' role="application"></div>';
1720
1721                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1722                 + ' data-dimensions="sent"'
1723                 + ' data-chart-library="easypiechart"'
1724                 + ' data-title="IPv4 Outbound"'
1725                 + ' data-units="kbps"'
1726                 + ' data-width="10%"'
1727                 + ' data-before="0"'
1728                 + ' data-after="-' + duration.toString() + '"'
1729                 + ' data-points="' + duration.toString() + '"'
1730                 + ' role="application"></div>';
1731         }
1732         else if(typeof charts['system.ipv6'] !== 'undefined') {
1733                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1734                 + ' data-dimensions="received"'
1735                 + ' data-chart-library="easypiechart"'
1736                 + ' data-title="IPv6 Inbound"'
1737                 + ' data-units="kbps"'
1738                 + ' data-width="10%"'
1739                 + ' data-before="0"'
1740                 + ' data-after="-' + duration.toString() + '"'
1741                 + ' data-points="' + duration.toString() + '"'
1742                 + ' role="application"></div>';
1743
1744                 head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1745                 + ' data-dimensions="sent"'
1746                 + ' data-chart-library="easypiechart"'
1747                 + ' data-title="IPv6 Outbound"'
1748                 + ' data-units="kbps"'
1749                 + ' data-width="10%"'
1750                 + ' data-before="0"'
1751                 + ' data-after="-' + duration.toString() + '"'
1752                 + ' data-points="' + duration.toString() + '"'
1753                 + ' role="application"></div>';
1754         }
1755
1756         if(typeof charts['system.ram'] !== 'undefined')
1757                 head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
1758                 + ' data-dimensions="cached|free"'
1759                 + ' data-append-options="percentage"'
1760                 + ' data-chart-library="easypiechart"'
1761                 + ' data-title="Available RAM"'
1762                 + ' data-units="%"'
1763                 + ' data-easypiechart-max-value="100"'
1764                 + ' data-width="8%"'
1765                 + ' data-after="-' + duration.toString() + '"'
1766                 + ' data-points="' + duration.toString() + '"'
1767                 + ' data-colors="' + NETDATA.colors[7] + '"'
1768                 + ' role="application"></div>';
1769
1770         return head;
1771 }
1772
1773 function generateHeadCharts(type, chart, duration) {
1774         var head = '';
1775         var hcharts = anyAttribute(chartData, type, chart.context, []);
1776         if(hcharts.length > 0) {
1777                 var hi = 0, hlen = hcharts.length;
1778                 while(hi < hlen) {
1779                         if(typeof hcharts[hi] === 'function')
1780                                 head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1781                         else
1782                                 head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1783                         hi++;
1784                 }
1785         }
1786         return head;
1787 }
1788
1789 function renderPage(menus, data) {
1790         var div = document.getElementById('charts_div');
1791         var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
1792
1793         // find the proper duration for per-second updates
1794         var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
1795         var html = '';
1796         var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
1797         var mainhead = headMain(data.charts, duration);
1798
1799         // sort the menus
1800         var main = sortObjectByPriority(menus);
1801         var i = 0, len = main.length;
1802         while(i < len) {
1803                 var menu = main[i++];
1804
1805                 // generate an entry at the main menu
1806
1807                 var menuid = name2id(menu);
1808                 sidebar += '<li class=""><a href="#' + menuid + '">' + menus[menu].title + '</a><ul class="nav">';
1809                 html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div id="menu_' + menuid + '" role="document">';
1810
1811                 if(menus[menu].info !== null)
1812                         html += menus[menu].info;
1813
1814                 // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
1815
1816                 var shtml = '';
1817                 var mhead = '<div class="netdata-chart-row">' + mainhead;
1818                 mainhead = '';
1819
1820                 // sort the submenus of this menu
1821                 var sub = sortObjectByPriority(menus[menu].submenus);
1822                 var si = 0, slen = sub.length;
1823                 while(si < slen) {
1824                         var submenu = sub[si++];
1825
1826                         // generate an entry at the submenu
1827                         var submenuid = name2id(menu + '_' + submenu);
1828                         sidebar += '<li class><a href="#' + submenuid + '">' + menus[menu].submenus[submenu].title + '</a></li>';
1829                         shtml += '<div class="netdata-group-container" id="submenu_' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
1830
1831                         if(menus[menu].submenus[submenu].info !== null)
1832                                 shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
1833
1834                         var head = '<div class="netdata-chart-row">';
1835                         var chtml = '';
1836
1837                         // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
1838
1839                         // sort the charts in this submenu of this menu
1840                         menus[menu].submenus[submenu].charts.sort(prioritySort);
1841                         var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
1842                         while(ci < clen) {
1843                                 var chart = menus[menu].submenus[submenu].charts[ci++];
1844
1845                                 // generate the submenu heading charts
1846                                 mhead += generateHeadCharts('mainheads', chart, duration);
1847                                 head += generateHeadCharts('heads', chart, duration);
1848
1849                                 // generate the chart
1850                                 chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
1851                                         + ' data-width="' + pcent_width.toString() + '%"'
1852                                         + ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
1853                                         + ' data-before="0"'
1854                                         + ' data-after="-' + duration.toString() + '"'
1855                                         + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
1856                                         + ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
1857                                         + ' role="application"></div>';
1858
1859                                 // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
1860                         }
1861
1862                         head += '</div>';
1863                         shtml += head + chtml + '</div>';
1864                 }
1865
1866                 mhead += '</div>';
1867                 sidebar += '</ul></li>';
1868                 html += mhead + shtml + '</div></div><hr role="separator"/>';
1869         }
1870
1871         sidebar += '</ul>';
1872         div.innerHTML = html;
1873         document.getElementById('sidebar').innerHTML = sidebar;
1874         finalizePage();
1875 }
1876
1877 function renderChartsAndMenu(data) {
1878         var menus = {};
1879         var charts = data.charts;
1880
1881         for(var c in charts) {
1882                 enrichChartData(charts[c]);
1883
1884                 // create the menu
1885                 if(typeof menus[charts[c].menu] === 'undefined') {
1886                         menus[charts[c].menu] = {
1887                                 priority: charts[c].priority,
1888                                 submenus: {},
1889                                 title: menuTitle(charts[c]),
1890                                 info: menuInfo(charts[c].menu),
1891                                 height: menuHeight(charts[c].menu, options.chartsHeight)
1892                         };
1893                 }
1894
1895                 if(charts[c].priority < menus[charts[c].menu].priority)
1896                         menus[charts[c].menu].priority = charts[c].priority;
1897
1898                 // create the submenu
1899                 if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
1900                         menus[charts[c].menu].submenus[charts[c].submenu] = {
1901                                 priority: charts[c].priority,
1902                                 charts: new Array(),
1903                                 title: null,
1904                                 info: submenuInfo(charts[c].menu, charts[c].submenu),
1905                                 height: submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
1906                         };
1907                 }
1908
1909                 if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
1910                         menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
1911
1912                 // index the chart in the menu/submenu
1913                 menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
1914         }
1915
1916         // propagate the descriptive subname given to QoS
1917         // to all the other submenus with the same name
1918         for(var m in menus) {
1919                 for(var s in menus[m].submenus) {
1920                         // set the family using a name
1921                         if(typeof options.submenu_names[s] !== 'undefined') {
1922                                 menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
1923                         }
1924                         else {
1925                                 menus[m].submenus[s].title = submenuTitle(m, s);
1926                         }
1927                 }
1928         }
1929
1930         renderPage(menus, data);
1931 }
1932
1933 function downloadAllCharts(netdata_url) {
1934         if(typeof netdata_url === 'undefined' || netdata_url === null)
1935                 netdata_url = NETDATA.serverDefault;
1936
1937         NETDATA.pause(function() {
1938
1939                 // download all the charts the server knows
1940                 NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
1941
1942                         options.data = data;
1943                         options.hostname = data.hostname;
1944                         document.getElementById('hostname').innerHTML = options.hostname;
1945                         document.getElementById('hostname').href = NETDATA.serverDefault;
1946                         document.title = options.hostname + ' dashboard';
1947
1948                         renderChartsAndMenu(data);
1949
1950                         // prepare our DOM
1951 //                      prepareScreen(data);
1952
1953                         // due to affix issues, prepareScreen() will unpause
1954                         // netdata as needed
1955                 });
1956         });
1957 }
1958
1959 // ----------------------------------------------------------------------------
1960
1961 function versionLog(msg) {
1962         document.getElementById('versionCheckLog').innerHTML = msg;
1963 }
1964
1965 function getNetdataVersion(callback) {
1966         versionLog('Downloading installed version info from netdata...');
1967
1968         $.ajax({
1969                 url: 'version.txt',
1970                 async: true,
1971                 cache: false
1972         })
1973         .done(function(data) {
1974                 data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
1975                 if(data.length !== 40) {
1976                         versionLog('Received version string is invalid.');
1977                         callback(null);
1978                 }
1979                 else {
1980                         versionLog('Installed version of netdata is ' + data);
1981                         document.getElementById('netdataVersion').innerHTML = data;
1982                         callback(data);
1983                 }
1984         })
1985         .fail(function() {
1986                 versionLog('Failed to download installed version info from netdata!');
1987                 callback(null);
1988         });
1989 }
1990
1991 function getGithubLatestCommit(callback) {
1992         versionLog('Downloading latest version info from github...');
1993
1994         $.ajax({
1995                 url: 'https://api.github.com/repos/firehol/netdata/commits',
1996                 async: true,
1997                 cache: false
1998         })
1999         .done(function(data) {
2000                 versionLog('Latest version info from github is ' + data[0].sha);
2001                 callback(data[0].sha);
2002         })
2003         .fail(function() {
2004                 versionLog('Failed to download installed version info from github!');
2005                 callback(null);
2006         });
2007 }
2008
2009 function checkForUpdate(callback) {
2010         getNetdataVersion(function(sha1) {
2011                 if(sha1 === null) callback(null, null);
2012
2013                 getGithubLatestCommit(function(sha2) {
2014                         callback(sha1, sha2);
2015                 });
2016         });
2017
2018         return null;
2019 }
2020
2021 var updateBlinkCounter = 0;
2022 function notifyForUpdate(force) {
2023         versionLog('<p>checking for updates...</p>');
2024
2025         var now = new Date().getTime();
2026
2027         if(typeof force === 'undefined' || force !== true) {
2028                 var last = loadLocalStorage('last_update_check');
2029
2030                 if(typeof last === 'string')
2031                         last = parseInt(last);
2032                 else
2033                         last = 0;
2034
2035                 if(now - last < 3600000 * 8) {
2036                         // no need to check it - too soon
2037                         return;
2038                 }
2039         }
2040
2041         checkForUpdate(function(sha1, sha2) {
2042                 var save = false;
2043
2044                 if(sha1 === null) {
2045                         save = false;
2046                         versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
2047                 }
2048                 else if(sha2 === null) {
2049                         save = false;
2050                         versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
2051                 }
2052                 else if(sha1 === sha2) {
2053                         save = true;
2054                         versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
2055                 }
2056                 else {
2057                         save = true;
2058                         var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
2059
2060                         versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
2061
2062                         function updateButtonBlink() {
2063                                 updateBlinkCounter--;
2064                                 if(updateBlinkCounter > 0)
2065                                         $('#updateButton').fadeOut(500).fadeIn(500, updateButtonBlink);
2066                         }
2067
2068                         if(updateBlinkCounter === 0) {
2069                                 updateBlinkCounter = 300;
2070                                 updateButtonBlink();
2071                         }
2072                 }
2073
2074                 if(save)
2075                         saveLocalStorage('last_update_check', now.toString());
2076         });
2077 }
2078
2079 // ----------------------------------------------------------------------------
2080
2081 function getUrlParameter(sParam) {
2082     var sPageURL = decodeURIComponent(window.location.search.substring(1)),
2083         sURLVariables = sPageURL.split('&'),
2084         sParameterName,
2085         i;
2086
2087     for (i = 0; i < sURLVariables.length; i++) {
2088         sParameterName = sURLVariables[i].split('=');
2089
2090         if (sParameterName[0] === sParam) {
2091             return sParameterName[1] === undefined ? true : sParameterName[1];
2092         }
2093     }
2094 }
2095
2096 function finalizePage() {
2097         // resize all charts - without starting the background thread
2098         // this has to be done while NETDATA is paused
2099         // if we ommit this, the affix menu will be wrong, since all
2100         // the Dom elements are initially zero-sized
2101         NETDATA.parseDom();
2102
2103         var before = 0, after = 0, nowelcome = 0;
2104         after = getUrlParameter('force_after_ms');
2105         before = getUrlParameter('force_before_ms');
2106         nowelcome = (getUrlParameter('nowelcome') === true)?true:false;
2107
2108         if(before > 0 && after > 0) {
2109                 nowelcome = true;
2110                 NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], after, before);
2111         }
2112
2113         // let it run (update the charts)
2114         NETDATA.unpause();
2115
2116         // check if we have to jump to a specific section
2117         var hash = location.hash.replace('#','');
2118         if(hash != '') {
2119                 // Clear the hash in the URL
2120                 // location.hash = '';   // delete front "//" if you want to change the address bar
2121                 var offset = $(location.hash).offset();
2122                 if(typeof offset !== 'undefined')
2123                         $('html, body').animate({ scrollTop: offset.top }, 0);
2124         }
2125
2126         /* activate bootstrap sidebar (affix) */
2127         $('#sidebar').affix({
2128                 offset: {
2129                         top: (isdemo())?150:0,
2130                         bottom: 0
2131                 }
2132         });
2133
2134         /* fix scrolling of very long affix lists
2135            http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
2136          */
2137         $('#sidebar').on('affixed.bs.affix', function() {
2138                 $(this).removeAttr('style');
2139         });
2140
2141         /* activate bootstrap scrollspy (needed for sidebar) */
2142         $(document.body).scrollspy({
2143                 target: '#sidebar',
2144                 offset: $(window).height() / 3 // controls the diff of the <hX> element to the top, to select it
2145         });
2146
2147         document.getElementById('footer').style.display = 'block';
2148
2149
2150         var update_options_modal = function() {
2151                 // console.log('update_options_modal');
2152
2153                 var sync_option = function(option) {
2154                         var self = $('#' + option);
2155
2156                         if(self.prop('checked') !== NETDATA.getOption(option)) {
2157                                 // console.log('switching ' + option.toString());
2158                                 self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
2159                         }
2160                 }
2161
2162                 var theme_sync_option = function(option) {
2163                         var self = $('#' + option);
2164
2165                         self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
2166                 }
2167
2168                 sync_option('eliminate_zero_dimensions');
2169                 sync_option('destroy_on_hide');
2170                 sync_option('parallel_refresher');
2171                 sync_option('concurrent_refreshes');
2172                 sync_option('sync_selection');
2173                 sync_option('sync_pan_and_zoom');
2174                 sync_option('stop_updates_when_focus_is_lost');
2175                 sync_option('smooth_plot');
2176                 sync_option('pan_and_zoom_data_padding');
2177                 sync_option('show_help');
2178                 theme_sync_option('netdata_theme_control');
2179
2180                 if(NETDATA.getOption('parallel_refresher') === false) {
2181                         $('#concurrent_refreshes_row').hide();
2182                 }
2183                 else {
2184                         $('#concurrent_refreshes_row').show();
2185                 }
2186         };
2187         NETDATA.setOption('setOptionCallback', update_options_modal);
2188
2189         // handle options changes
2190         $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
2191         $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
2192         $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
2193         $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
2194         $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
2195         $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
2196         $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
2197         $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
2198         $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
2199         $('#show_help').change(function()                       { NETDATA.setOption('show_help', $(this).prop('checked')); location.reload(); });
2200
2201         // this has to be the last
2202         // it reloads the page
2203         $('#netdata_theme_control').change(function() {
2204                 if(setTheme($(this).prop('checked')?'slate':'white'))
2205                         location.reload();
2206         });
2207
2208         $('#updateModal').on('shown.bs.modal', function() {
2209                 notifyForUpdate(true);
2210         });
2211
2212         $('#deleteRegistryModal').on('hidden.bs.modal', function() {
2213                 deleteRegistryGuid = null;
2214         });
2215
2216         if(isdemo()) {
2217                 if(!nowelcome) {
2218                         setTimeout(function() {
2219                                 $('#welcomeModal').modal();
2220                         }, 1000);
2221                 }
2222
2223                 // google analytics when this is used for the home page of the demo sites
2224                 // this does not run on user's installations
2225                 setTimeout(function() {
2226                         (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
2227                         (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
2228                         m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
2229                         })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
2230
2231                         ga('create', 'UA-64295674-3', 'auto');
2232                         ga('send', 'pageview');
2233                 }, 2000);
2234         }
2235         else notifyForUpdate();
2236 }
2237
2238 function resetDashboardOptions() {
2239         var help = NETDATA.options.current.show_help;
2240
2241         NETDATA.resetOptions();
2242         if(setTheme('slate'))
2243                 location.reload();
2244
2245         if(help !== NETDATA.options.current.show_help)
2246                 location.reload();
2247 }
2248
2249 downloadAllCharts();
2250
2251 </script>
2252
2253 </body>
2254 </html>