diff options
Diffstat (limited to '')
-rw-r--r-- | web/index.html | 2887 |
1 files changed, 2422 insertions, 465 deletions
diff --git a/web/index.html b/web/index.html index cd8239d2..e3c03909 100644 --- a/web/index.html +++ b/web/index.html @@ -46,6 +46,12 @@ <meta name="twitter:image" content="https://cloud.githubusercontent.com/assets/2662304/14092712/93b039ea-f551-11e5-822c-beadbf2b2a2e.gif" /> <style> + + /* force the vertical window scrollbar */ + html { + overflow-y: scroll; + } + /* prevent body from hiding under the navbar */ body { padding-top: 50px; @@ -65,6 +71,42 @@ text-align: center; } + .navbar-highlight { + display: none; + position: fixed; + margin-top: 5px; + height: 26px; + width: 100%; + text-align: center; + overflow: hidden; + z-index: 30; + pointer-events: none !important; + } + + .navbar-highlight-content { + position: relative; + display: inline-block; + margin: 0 auto; + height: 26px; + min-width: 500px; + background-color:rgba(0, 0, 0, 0.7); + padding-top: 2px; + padding-bottom: 2px; + padding-left: 15px; + padding-right: 15px; + border-radius:10px; + color: lightgrey; + pointer-events: auto !important; + } + + .navbar-highlight-bar { + cursor: pointer; + } + .navbar-highlight-button-right { + cursor: pointer; + padding-left: 10px; + } + .modal-wide .modal-dialog { width: 80%; } @@ -105,7 +147,12 @@ padding: 10px; } - .chart-message { + .dashboard-submenu-info { + display: block; + margin-top: 10px; + } + + .dashboard-context-info { display: block; margin-top: 10px; } @@ -265,6 +312,11 @@ max-height: 80vh; overflow-x: hidden; } + .scrollable-menu-50 { + height: auto; + max-height: 50vh; + overflow-x: hidden; + } /* Back to top (hidden on mobile) */ .back-to-top, @@ -300,6 +352,70 @@ display: none; } + .dashboard-section-container { + display: block; + width: 100%; + page-break-before: auto; + page-break-after: auto; + page-break-inside: auto; + } + + .dashboard-print-row { + display: block; + width: 100%; + page-break-before: auto; + page-break-after: auto; + page-break-inside: avoid; + } + + .netdata-chartblock-container { + display: inline-block; + } + + /* https://github.com/seiyria/bootstrap-slider/issues/746 */ + .tooltip { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + @media print { + body { + overflow: visible !important; + -webkit-print-color-adjust: exact; + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .dashboard-section { + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .dashboard-subsection { + page-break-before: avoid; + page-break-after: auto; + page-break-inside: auto; + } + + .charts-body { + padding-left: 0%; + padding-right: 0%; + display: block; + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .back-to-top, + .dashboard-theme-toggle { + display: block; + } + } + @media (min-width: 768px) { .charts-body { padding-left: 0%; @@ -405,12 +521,18 @@ <!-- check which theme to use --> <script type="text/javascript"> + // netdata snapshot data + var netdataSnapshotData = null; + // enable alarms checking and notifications var netdataShowAlarms = true; // enable registry updates var netdataRegistry = true; + // control the welcome modal and analytics + var this_is_demo = null; + // -------------------------------------------------------------------- // urlOptions @@ -418,10 +540,15 @@ hash: '#', theme: null, help: null, + mode: 'live', // 'live', 'print' update_always: false, pan_and_zoom: false, + server: null, after: 0, before: 0, + highlight: false, + highlight_after: 0, + highlight_before: 0, nowelcome: false, show_alarms: false, chart: null, @@ -436,12 +563,17 @@ return typeof this[property] !== 'undefined'; }, - genHash: function() { + genHash: function(forReload) { var hash = urlOptions.hash; if(urlOptions.pan_and_zoom === true) { hash += ';after=' + urlOptions.after.toString() + - ';before=' + urlOptions.before.toString(); + ';before=' + urlOptions.before.toString(); + } + + if(urlOptions.highlight === true) { + hash += ';highlight_after=' + urlOptions.highlight_after.toString() + + ';highlight_before=' + urlOptions.highlight_before.toString(); } if(urlOptions.theme !== null) @@ -453,6 +585,12 @@ if(urlOptions.update_always === true) hash += ';update_always=true'; + if(forReload === true && urlOptions.server !== null) + hash += ';server=' + urlOptions.server.toString(); + + if(urlOptions.mode !== 'live') + hash += ';mode=' + urlOptions.mode; + return hash; }, @@ -471,7 +609,7 @@ } } - var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom', 'update_always' ]; + var booleans = [ 'nowelcome', 'show_alarms', 'update_always' ]; len = booleans.length; while(len--) { if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1) @@ -480,6 +618,27 @@ urlOptions[booleans[len]] = false; } + var numeric = [ 'after', 'before', 'highlight_after', 'highlight_before' ]; + len = numeric.length; + while(len--) { + if(typeof urlOptions[numeric[len]] === 'string') { + try { + urlOptions[numeric[len]] = parseInt(urlOptions[numeric[len]]); + } + catch(e) { + console.log('failed to parse URL hash parameter ' + numeric[len]); + urlOptions[numeric[len]] = 0; + } + } + } + + if(urlOptions.server !== null && urlOptions.server !== '') { + netdataServerStatic = document.location.origin.toString() + document.location.pathname.toString(); + netdataServer = urlOptions.server; + } + else + urlOptions.server = null; + if(urlOptions.before > 0 && urlOptions.after > 0) { urlOptions.pan_and_zoom = true; urlOptions.nowelcome = true; @@ -487,20 +646,111 @@ else urlOptions.pan_and_zoom = false; + if(urlOptions.highlight_before > 0 && urlOptions.highlight_after > 0) { + urlOptions.highlight = true; + } + else + urlOptions.highlight = false + + switch(urlOptions.mode) { + case 'print': + urlOptions.theme = 'white'; + urlOptions.welcome = false; + urlOptions.help = false; + urlOptions.show_alarms = false; + + if(urlOptions.pan_and_zoom === false) { + urlOptions.pan_and_zoom = true; + urlOptions.before = Date.now(); + urlOptions.after = urlOptions.before - 600000; + } + + netdataShowAlarms = false; + netdataRegistry = false; + this_is_demo = false; + break; + + case 'live': + default: + urlOptions.mode = 'live'; + break; + } + // console.log(urlOptions); }, hashUpdate: function() { - history.replaceState(null, '', urlOptions.genHash()); + history.replaceState(null, '', urlOptions.genHash(true)); }, netdataPanAndZoomCallback: function(status, after, before) { - urlOptions.pan_and_zoom = status; - urlOptions.after = after; - urlOptions.before = before; + //console.log(1); + //console.log(new Error().stack); + + if(netdataSnapshotData === null) { + urlOptions.pan_and_zoom = status; + urlOptions.after = after; + urlOptions.before = before; + urlOptions.hashUpdate(); + } + }, + + netdataHighlightCallback: function(status, after, before) { + //console.log(2); + //console.log(new Error().stack); + + if(status === true && (after === null || before === null || after <= 0 || before <= 0 || after >= before)) { + status = false; + after = 0; + before = 0; + } + + if(netdataSnapshotData === null) + urlOptions.highlight = status; + else + urlOptions.highlight = false; + + urlOptions.highlight_after = Math.round(after); + urlOptions.highlight_before = Math.round(before); urlOptions.hashUpdate(); - } + var show_eye = NETDATA.globalChartUnderlay.hasViewport(); + + if(status === true && after > 0 && before > 0 && after < before) { + var d1 = NETDATA.dateTime.localeDateString(after); + var d2 = NETDATA.dateTime.localeDateString(before); + if(d1 === d2) d2 = ''; + document.getElementById('navbar-highlight-content').innerHTML = + ((show_eye === true)?'<span class="navbar-highlight-bar highlight-tooltip" onclick="urlOptions.showHighlight();" title="restore the highlighted view" data-toggle="tooltip" data-placement="bottom">':'<span>').toString() + + 'highlighted time-frame' + + ' <b>' + d1 + ' <code>' + NETDATA.dateTime.localeTimeString(after) + '</code></b> to ' + + ' <b>' + d2 + ' <code>' + NETDATA.dateTime.localeTimeString(before) + '</code></b>, ' + + 'duration <b>' + NETDATA.seconds4human(Math.round((before - after) / 1000)) + '</b>' + + '</span>' + + '<span class="navbar-highlight-button-right highlight-tooltip" onclick="urlOptions.clearHighlight();" title="clear the highlighted time-frame" data-toggle="tooltip" data-placement="bottom"><i class="fas fa-times"></i></span>'; + + $('.navbar-highlight').show(); + + $('.highlight-tooltip').tooltip({ + html: true, + delay: {show: 500, hide: 0}, + container: 'body' + }); + } + else + $('.navbar-highlight').hide(); + }, + + clearHighlight: function() { + NETDATA.globalChartUnderlay.clear(); + + if(NETDATA.globalPanAndZoom.isActive() === true) + NETDATA.globalPanAndZoom.clearMaster(); + }, + + showHighlight: function() { + NETDATA.globalChartUnderlay.focus(); + } }; urlOptions.parseHash(); @@ -521,6 +771,7 @@ localStorageTested = true; } catch (e) { + console.log(e); localStorageTested = false; } } @@ -536,8 +787,13 @@ try { if(localStorageTest() === true) ret = localStorage.getItem(name); + else + console.log('localStorage is not available'); + } + catch(error) { + console.log(error); + return null; } - catch(error) {} if(typeof ret === 'undefined' || ret === null) return null; @@ -555,12 +811,17 @@ return true; } } - catch(error) {} + catch(error) { + console.log(error); + } return false; } function getTheme(def) { + if(urlOptions.mode === 'print') + return 'white'; + var ret = loadLocalStorage('netdataTheme'); if(typeof ret === 'undefined' || ret === null || ret === 'undefined') return def; @@ -569,6 +830,8 @@ } function setTheme(theme) { + if(urlOptions.mode === 'print') return false; + if(theme === netdataTheme) return false; return saveLocalStorage('netdataTheme', theme); } @@ -600,7 +863,7 @@ var x = 0, y = -1, n = 0, i, j; while (i = (j = t.charAt(x++)).charCodeAt(0)) { - var m = (i === 46 || (i >= 48 && i <= 57)); + var m = (i >= 48 && i <= 57); if (m !== n) { tz[++y] = ""; n = m; @@ -629,6 +892,35 @@ } // -------------------------------------------------------------------- + // saving files to client + + function saveTextToClient(data, filename) { + var blob = new Blob( [ data ], { + type: 'application/octet-stream' + }); + + var url = URL.createObjectURL( blob ); + var link = document.createElement( 'a' ); + link.setAttribute( 'href', url ); + link.setAttribute( 'download', filename ); + + var el = document.getElementById('hiddenDownloadLinks'); + el.innerHTML = ''; + el.appendChild(link); + + setTimeout(function(){ + el.removeChild(link); + URL.revokeObjectURL(url); + }, 60); + + link.click(); + } + + function saveObjectToClient(data, filename) { + saveTextToClient(JSON.stringify(data), filename); + } + + // -------------------------------------------------------------------- // registry call back to render my-netdata menu var netdataRegistryCallback = function(machines_array) { @@ -641,7 +933,7 @@ // there are mirrored hosts here el += '<li><a href="#" onClick="return false;" style="color: #666;" target="_blank">databases available on this host</a></li>'; - a1 += '<li><a href="#" onClick="return false;"><i class="fa fa-info-circle" aria-hidden="true" style="color: #666;"></i></a></li>'; + a1 += '<li><a href="#" onClick="return false;"><i class="fas fa-info-circle" style="color: #666;"></i></a></li>'; var base = document.location.origin.toString() + document.location.pathname.toString(); if(base.endsWith("/host/" + options.hostname + "/")) @@ -669,8 +961,8 @@ icon = "window-restore"; } - el += '<li id="registry_server_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');">' + hostname + '</a></li>'; - a1 += '<li id="registry_action_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');"><i class="fa fa-' + icon + '" aria-hidden="true" style="color: #999;"></i></a></li>'; + el += '<li id="registry_server_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '#" onClick="return gotoHostedModalHandler(\'' + url + '\');">' + hostname + '</a></li>'; + a1 += '<li id="registry_action_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '#" onClick="return gotoHostedModalHandler(\'' + url + '\');"><i class="fas fa-' + icon + '" style="color: #999;"></i></a></li>'; hosted++; i++; } @@ -699,8 +991,8 @@ while(len--) { var u = machines[i++]; found++; - el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>'; - 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>'; + el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '#" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>'; + a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fas fa-trash" style="color: #999;"></i></a></li>'; } } @@ -736,7 +1028,7 @@ a1 += '<li role="separator" class="divider"></li>'; el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>'; - a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>' + a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fas fa-cog" style="color: #999;"></i></a></li>' document.getElementById('mynetdata_servers').innerHTML = el; document.getElementById('mynetdata_servers2').innerHTML = el; @@ -745,7 +1037,6 @@ gotoServerInit(); }; - var this_is_demo = null; // FIXME function isdemo() { if(this_is_demo !== null) return this_is_demo; this_is_demo = false; @@ -764,14 +1055,14 @@ return this_is_demo; } - function netdataURL(url) { + function netdataURL(url, forReload) { if(typeof url === 'undefined') url = document.location.toString(); if(url.indexOf('#') !== -1) url = url.substring(0, url.indexOf('#')); - var hash = urlOptions.genHash(); + var hash = urlOptions.genHash(forReload); // console.log('netdataURL: ' + url + hash); @@ -779,7 +1070,7 @@ } function netdataReload(url) { - document.location = netdataURL(url); + document.location = netdataURL(url, true); // since we play with hash // this is needed to reload the page @@ -958,15 +1249,14 @@ data: null, hostname: 'netdata_server', // will be overwritten by the netdata server version: 'unknown', - categories: [], - categories_idx: {}, - families: [], - families_idx: {}, hosts: [], + duration: 0, // the default duration of the charts + update_every: 1, + chartsPerRow: 0, // chartsMinWidth: 1450, - chartsHeight: 180 + chartsHeight: 180, }; function chartsPerRow(total) { @@ -1016,8 +1306,10 @@ function scrollToId(hash) { if(hash && hash !== '' && document.getElementById(hash) !== null) { var offset = $('#' + hash).offset(); - if(typeof offset !== 'undefined') - $('html, body').animate({ scrollTop: offset.top - 30 }, 0); + if(typeof offset !== 'undefined') { + //console.log('scrolling to ' + hash + ' at ' + offset.top.toString()); + $('html, body').animate({scrollTop: offset.top - 30}, 0); + } } // we must return false to prevent the default action @@ -1120,9 +1412,9 @@ menuIcon: function(chart) { if(typeof chart.menu_pattern !== 'undefined') - return this.anyAttribute(this.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString(); + return this.anyAttribute(this.menu, 'icon', chart.menu_pattern, '<i class="fas fa-puzzle-piece"></i>').toString(); - return this.anyAttribute(this.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>'); + return this.anyAttribute(this.menu, 'icon', chart.menu, '<i class="fas fa-puzzle-piece"></i>'); }, menuInfo: function(chart) { @@ -1165,7 +1457,7 @@ var x = this.anyAttribute(this.context, 'info', id, null); if(x !== null) - return '<div class="chart-message netdata-chart-alignment" role="document">' + x + '</div>'; + return '<div class="shorten dashboard-context-info netdata-chart-alignment" role="document">' + x + '</div>'; else return ''; }, @@ -1307,120 +1599,178 @@ function headMain(os, charts, duration) { void(os); + if(urlOptions.mode === 'print') + return ''; + var head = ''; if(typeof charts['system.swap'] !== 'undefined') head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.swap"' - + ' data-dimensions="used"' - + ' data-append-options="percentage"' - + ' data-chart-library="easypiechart"' - + ' data-title="Used Swap"' - + ' data-units="%"' - + ' data-easypiechart-max-value="100"' - + ' data-width="9%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' data-colors="#DD4400"' - + ' role="application"></div>'; + + ' data-dimensions="used"' + + ' data-append-options="percentage"' + + ' data-chart-library="easypiechart"' + + ' data-title="Used Swap"' + + ' data-units="%"' + + ' data-easypiechart-max-value="100"' + + ' data-width="9%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-colors="#DD4400"' + + ' role="application"></div>'; if(typeof charts['system.io'] !== 'undefined') { head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.io"' - + ' data-dimensions="in"' - + ' data-chart-library="easypiechart"' - + ' data-title="Disk Read"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="in"' + + ' data-chart-library="easypiechart"' + + ' data-title="Disk Read"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.io.mainhead"' + + ' role="application"></div>'; head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.io"' - + ' data-dimensions="out"' - + ' data-chart-library="easypiechart"' - + ' data-title="Disk Write"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="out"' + + ' data-chart-library="easypiechart"' + + ' data-title="Disk Write"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.io.mainhead"' + + ' role="application"></div>'; + } + else if(typeof charts['system.pgpgio'] !== 'undefined') { + head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.pgpgio"' + + ' data-dimensions="in"' + + ' data-chart-library="easypiechart"' + + ' data-title="Disk Read"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.pgpgio.mainhead"' + + ' role="application"></div>'; + + head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.pgpgio"' + + ' data-dimensions="out"' + + ' data-chart-library="easypiechart"' + + ' data-title="Disk Write"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.pgpgio.mainhead"' + + ' role="application"></div>'; } if(typeof charts['system.cpu'] !== 'undefined') head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.cpu"' - + ' data-chart-library="gauge"' - + ' data-title="CPU"' - + ' data-units="%"' - + ' data-gauge-max-value="100"' - + ' data-width="20%"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[12] + '"' - + ' role="application"></div>'; - - if(typeof charts['system.ipv4'] !== 'undefined') { + + ' data-chart-library="gauge"' + + ' data-title="CPU"' + + ' data-units="%"' + + ' data-gauge-max-value="100"' + + ' data-width="20%"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-colors="' + NETDATA.colors[12] + '"' + + ' role="application"></div>'; + + if(typeof charts['system.net'] !== 'undefined') { + head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.net"' + + ' data-dimensions="received"' + + ' data-chart-library="easypiechart"' + + ' data-title="Net Inbound"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.net.mainhead"' + + ' role="application"></div>'; + + head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.net"' + + ' data-dimensions="sent"' + + ' data-chart-library="easypiechart"' + + ' data-title="Net Outbound"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.net.mainhead"' + + ' role="application"></div>'; + } + else if(typeof charts['system.ipv4'] !== 'undefined') { head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.ipv4"' - + ' data-dimensions="received"' - + ' data-chart-library="easypiechart"' - + ' data-title="IPv4 Inbound"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="received"' + + ' data-chart-library="easypiechart"' + + ' data-title="IPv4 Inbound"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.ipv4.mainhead"' + + ' role="application"></div>'; head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.ipv4"' - + ' data-dimensions="sent"' - + ' data-chart-library="easypiechart"' - + ' data-title="IPv4 Outbound"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="sent"' + + ' data-chart-library="easypiechart"' + + ' data-title="IPv4 Outbound"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.ipv4.mainhead"' + + ' role="application"></div>'; } else if(typeof charts['system.ipv6'] !== 'undefined') { head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.ipv6"' - + ' data-dimensions="received"' - + ' data-chart-library="easypiechart"' - + ' data-title="IPv6 Inbound"' - + ' data-units="kbps"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="received"' + + ' data-chart-library="easypiechart"' + + ' data-title="IPv6 Inbound"' + + ' data-units="kbps"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.ipv6.mainhead"' + + ' role="application"></div>'; head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.ipv6"' - + ' data-dimensions="sent"' - + ' data-chart-library="easypiechart"' - + ' data-title="IPv6 Outbound"' - + ' data-units="kbps"' - + ' data-width="11%"' - + ' data-before="0"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' role="application"></div>'; + + ' data-dimensions="sent"' + + ' data-chart-library="easypiechart"' + + ' data-title="IPv6 Outbound"' + + ' data-units="kbps"' + + ' data-width="11%"' + + ' data-before="0"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-common-units="system.ipv6.mainhead"' + + ' role="application"></div>'; } if(typeof charts['system.ram'] !== 'undefined') head += '<div class="netdata-container" style="margin-right: 10px;" data-netdata="system.ram"' - + ' data-dimensions="used|buffers|active|wired"' // active and wired are FreeBSD stats - + ' data-append-options="percentage"' - + ' data-chart-library="easypiechart"' - + ' data-title="Used RAM"' - + ' data-units="%"' - + ' data-easypiechart-max-value="100"' - + ' data-width="9%"' - + ' data-after="-' + duration.toString() + '"' - + ' data-points="' + duration.toString() + '"' - + ' data-colors="' + NETDATA.colors[7] + '"' - + ' role="application"></div>'; + + ' data-dimensions="used|buffers|active|wired"' // active and wired are FreeBSD stats + + ' data-append-options="percentage"' + + ' data-chart-library="easypiechart"' + + ' data-title="Used RAM"' + + ' data-units="%"' + + ' data-easypiechart-max-value="100"' + + ' data-width="9%"' + + ' data-after="-' + duration.toString() + '"' + + ' data-points="' + duration.toString() + '"' + + ' data-colors="' + NETDATA.colors[7] + '"' + + ' role="application"></div>'; return head; } function generateHeadCharts(type, chart, duration) { + if(urlOptions.mode === 'print') + return ''; + var head = ''; var hcharts = netdataDashboard.anyAttribute(netdataDashboard.context, type, chart.context, []); if(hcharts.length > 0) { @@ -1442,6 +1792,9 @@ // find the proper duration for per-second updates var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60; + options.duration = duration; + options.update_every = data.update_every; + var html = ''; var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">'; var mainhead = headMain(netdataDashboard.os, data.charts, duration); @@ -1456,7 +1809,7 @@ var menuid = NETDATA.name2id('menu_' + menu); sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">'; - html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">'; + html += '<div role="section" class="dashboard-section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].icon + ' ' + menus[menu].title + '</h1></div><div role="section" class="dashboard-subsection">'; if(menus[menu].info !== null) html += menus[menu].info; @@ -1476,10 +1829,10 @@ // generate an entry at the submenu var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu); sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>'; - shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>'; + shtml += '<div role="section" class="dashboard-section-container" id="' + submenuid + '"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>'; if(menus[menu].submenus[submenu].info !== null) - shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>'; + shtml += '<div class="dashboard-submenu-info netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>'; var head = '<div class="netdata-chart-row">'; var chtml = ''; @@ -1513,8 +1866,11 @@ } // generate the chart - chtml += netdataDashboard.contextInfo(chart.context) + '<div class="netdata-container" id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"' - + ' data-width="' + pcent_width.toString() + '%"' + if(urlOptions.mode === 'print') + chtml += '<div role="row" class="dashboard-print-row">'; + + chtml += '<div class="netdata-chartblock-container" style="width: ' + pcent_width.toString() + '%;">' + netdataDashboard.contextInfo(chart.context) + '<div class="netdata-container" id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"' + + ' data-width="100%"' + ' data-height="' + netdataDashboard.contextHeight(chart.context, options.chartsHeight).toString() + 'px"' + ' data-dygraph-valuerange="' + netdataDashboard.contextValueRange(chart.context) + '"' + ' data-before="0"' @@ -1524,7 +1880,10 @@ + ' data-decimal-digits="' + netdataDashboard.contextDecimalDigits(chart.context, -1) + '"' + chartCommonMin(chart.family, chart.context, chart.units) + chartCommonMax(chart.family, chart.context, chart.units) - + ' role="application"></div>'; + + ' role="application"></div></div>'; + + if(urlOptions.mode === 'print') + chtml += '</div>'; // console.log(' \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context + ' height: ' + menus[menu].submenus[submenu].height); } @@ -1538,16 +1897,33 @@ html += mhead + shtml + '</div></div><hr role="separator"/>'; } - sidebar += '<li class="" style="padding-top:15px;"><a href="https://github.com/firehol/netdata/wiki/Add-more-charts-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more charts</a></li>'; - sidebar += '<li class=""><a href="https://github.com/firehol/netdata/wiki/Add-more-alarms-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more alarms</a></li>'; - sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every === 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + seconds4human(data.update_every * data.history) + ' of real-time history.<br/> <br/><b>netdata</b><br/>v' + data.version.toString() +'</small></li>'; + sidebar += '<li class="" style="padding-top:15px;"><a href="https://github.com/firehol/netdata/wiki/Add-more-charts-to-netdata" target="_blank"><i class="fas fa-plus"></i> add more charts</a></li>'; + sidebar += '<li class=""><a href="https://github.com/firehol/netdata/wiki/Add-more-alarms-to-netdata" target="_blank"><i class="fas fa-plus"></i> add more alarms</a></li>'; + sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every === 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + NETDATA.seconds4human(data.update_every * data.history, { space: ' ' }) + ' of real-time history.<br/> <br/><b>netdata</b><br/>v' + data.version.toString() +'</small></li>'; sidebar += '</ul>'; div.innerHTML = html; document.getElementById('sidebar').innerHTML = sidebar; - finalizePage(); + + if(urlOptions.highlight === true) + NETDATA.globalChartUnderlay.init(null + , urlOptions.highlight_after + , urlOptions.highlight_before + , (urlOptions.after > 0) ? urlOptions.after : null + , (urlOptions.before > 0) ? urlOptions.before : null + ); + else + NETDATA.globalChartUnderlay.clear(); + + if(urlOptions.mode === 'print') + printPage(); + else + finalizePage(); } function renderChartsAndMenu(data) { + options.menus = {}; + options.submenu_names = {}; + var menus = options.menus; var charts = data.charts; var m, menu_key; @@ -1644,15 +2020,49 @@ function loadBootstrapTable(callback) { if(bootstrapTableLoaded === false) { bootstrapTableLoaded = true; - loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-1.11.0.min.js', function() { - loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-export-1.11.0.min.js', function() { - loadJs(NETDATA.serverDefault + 'lib/tableExport-1.6.0.min.js', callback); + loadJs('lib/bootstrap-table-1.11.0.min.js', function() { + loadJs('lib/bootstrap-table-export-1.11.0.min.js', function() { + loadJs('lib/tableExport-1.6.0.min.js', callback); }) }); } else callback(); } + var bootstrapSliderLoaded = false; + function loadBootstrapSlider(callback) { + if(bootstrapSliderLoaded === false) { + bootstrapSliderLoaded = true; + loadJs('lib/bootstrap-slider-10.0.0.min.js', function() { + NETDATA._loadCSS('css/bootstrap-slider-10.0.0.min.css'); + callback(); + }); + } + else callback(); + } + + var lzStringLoaded = false; + function loadLzString(callback) { + if(lzStringLoaded === false) { + lzStringLoaded = true; + loadJs('lib/lz-string-1.4.4.min.js', function() { + callback(); + }); + } + else callback(); + } + + var pakoLoaded = false; + function loadPako(callback) { + if(pakoLoaded === false) { + pakoLoaded = true; + loadJs('lib/pako-1.0.6.min.js', function() { + callback(); + }); + } + else callback(); + } + function alarmsUpdateModal() { var active = '<h3>Raised Alarms</h3><table class="table">'; var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">'; @@ -1711,7 +2121,7 @@ return '<code>' + alarm.lookup_method + '</code> ' + dimensions + ', of chart <code>' + alarm.chart + '</code>' - + ', starting <code>' + seconds4human(alarm.lookup_after + alarm.lookup_before) + '</code> and up to <code>' + seconds4human(alarm.lookup_before) + '</code>' + + ', starting <code>' + NETDATA.seconds4human(alarm.lookup_after + alarm.lookup_before, { space: ' ' }) + '</code> and up to <code>' + NETDATA.seconds4human(alarm.lookup_before, { space: ' ' }) + '</code>' + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ', ') + '</code>'):'') + '.'; } @@ -1727,7 +2137,7 @@ var has_alarm = (typeof alarm.warn !== 'undefined' || typeof alarm.crit !== 'undefined'); - var role_href = ((has_alarm === true)?('<br/> <br/>role: <b>' + alarm.recipient + '</b><br/> <br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small> <a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small>'):(' ')); + var role_href = ((has_alarm === true)?('<br/> <br/>role: <b>' + alarm.recipient + '</b><br/> <br/><b><i class="fas fa-chart-line"></i></b><small> <a href="#" onClick="scrollToChartAfterHidingModal(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small>'):(' ')); var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/> <br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/> <br/><span style="font-size: 18px">' + alarm.info + '</span>' + role_href + '</td>' + '<td><table class="table">' @@ -1747,25 +2157,25 @@ var delay = ''; if((alarm.delay_up_duration > 0 || alarm.delay_down_duration > 0) && alarm.delay_multiplier !== 0 && alarm.delay_max_duration > 0) { if(alarm.delay_up_duration === alarm.delay_down_duration) { - delay += '<small><br/>hysteresis ' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' }); + delay += '<small><br/>hysteresis ' + NETDATA.seconds4human(alarm.delay_up_duration, { space: ' ', negative_suffix: '' }); } else { delay = '<small><br/>hysteresis '; if(alarm.delay_up_duration > 0) { - delay += 'on escalation <code>' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' }) + '</code>, '; + delay += 'on escalation <code>' + NETDATA.seconds4human(alarm.delay_up_duration, { space: ' ', negative_suffix: '' }) + '</code>, '; } if(alarm.delay_down_duration > 0) { - delay += 'on recovery <code>' + seconds4human(alarm.delay_down_duration, { negative_suffix: '' }) + '</code>, '; + delay += 'on recovery <code>' + NETDATA.seconds4human(alarm.delay_down_duration, { space: ' ', negative_suffix: '' }) + '</code>, '; } } if(alarm.delay_multiplier !== 1.0) { delay += 'multiplied by <code>' + alarm.delay_multiplier.toString() + '</code>'; - delay += ', up to <code>' + seconds4human(alarm.delay_max_duration, { negative_suffix: '' }) + '</code>'; + delay += ', up to <code>' + NETDATA.seconds4human(alarm.delay_max_duration, { space: ' ', negative_suffix: '' }) + '</code>'; } delay += '</small>'; } - html += '<tr><td width="10%" style="text-align:right">check every</td><td>' + seconds4human(alarm.update_every, { negative_suffix: '' }) + '</td></tr>' + html += '<tr><td width="10%" style="text-align:right">check every</td><td>' + NETDATA.seconds4human(alarm.update_every, { space: ' ', negative_suffix: '' }) + '</td></tr>' + ((has_alarm === true)?('<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'):'') + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>' + '</table></td></tr>'; @@ -1880,7 +2290,7 @@ all += "</div>"; if(!count_active) - active += "<h4>Everything is normal. No raised alarms.</h4>"; + active += '<div style="width:100%; height: 100px; text-align: center;"><span style="font-size: 50px;"><i class="fas fa-thumbs-up"></i></span><br/>Everything is normal. No raised alarms.</div>'; else active += footer; @@ -2103,7 +2513,7 @@ formatter: function(value, row, index) { void(row); void(index); - return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); + return NETDATA.seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); }, align: 'center', valign: 'middle', @@ -2117,7 +2527,7 @@ formatter: function(value, row, index) { void(row); void(index); - return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); + return NETDATA.seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); }, align: 'center', valign: 'middle', @@ -2234,7 +2644,7 @@ void(row); void(index); - return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); + return NETDATA.seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); }, align: 'center', valign: 'middle', @@ -2276,70 +2686,6 @@ }); } - function seconds4human(seconds, options) { - var default_options = { - now: 'now', - space: ' ', - negative_suffix: 'ago', - hour: 'hour', - hours: 'hours', - minute: 'minute', - minutes: 'minutes', - second: 'second', - seconds: 'seconds', - and: 'and' - }; - - if(typeof options !== 'object') - options = default_options; - else { - var x; - for(x in default_options) { - if(typeof options[x] !== 'string') - options[x] = default_options[x]; - } - } - - if(typeof seconds === 'string') - seconds = parseInt(seconds); - - if(seconds === 0) - return options.now; - - var suffix = ''; - if(seconds < 0) { - seconds = -seconds; - if(options.negative_suffix !== '') suffix = options.space + options.negative_suffix; - } - - var hours = Math.floor(seconds / 3600); - seconds -= (hours * 3600); - - var minutes = Math.floor(seconds / 60); - seconds -= (minutes * 60); - - var txt = ''; - - if(hours > 1) txt += hours.toString() + options.space + options.hours; - else if(hours === 1) txt += hours.toString() + options.space + options.hour; - - if(hours > 0 && minutes > 0 && seconds === 0) - txt += options.space + options.and + options.space; - else if(hours > 0 && minutes > 0 && seconds > 0) - txt += ',' + options.space; - - if(minutes > 1) txt += minutes.toString() + options.space + options.minutes; - else if(minutes === 1) txt += minutes.toString() + options.space + options.minute; - - if((minutes > 0 || minutes > 0) && seconds > 0) - txt += options.space + options.and + options.space; - - if(seconds > 1) txt += Math.floor(seconds).toString() + options.space + options.seconds; - else if(seconds === 1) txt += Math.floor(seconds).toString() + options.space + options.second; - - return txt + suffix; - } - function alarmsCallback(data) { var count = 0; for(x in data.alarms) { @@ -2367,10 +2713,18 @@ options.hosts = data.hosts; // update the dashboard hostname - document.getElementById('hostname').innerHTML = options.hostname; + document.getElementById('hostname').innerHTML = options.hostname + ((netdataSnapshotData !== null)?' (snap)':'').toString(); document.getElementById('hostname').href = NETDATA.serverDefault; document.getElementById('netdataVersion').innerHTML = options.version; + if(netdataSnapshotData !== null) { + $('#alarmsButton').hide(); + $('#updateButton').hide(); + // $('#loadButton').hide(); + $('#saveButton').hide(); + $('#printButton').hide(); + } + // update the dashboard title document.title = options.hostname + ' netdata dashboard'; @@ -2408,8 +2762,8 @@ // download all the charts the server knows NETDATA.chartRegistry.downloadAll(netdata_url, function(data) { if(data !== null) { - if(typeof data.custom_info !== 'undefined' && data.custom_info !== "") { - loadJs(data.custom_info, function () { + if(typeof data.custom_info !== 'undefined' && data.custom_info !== "" && netdataSnapshotData === null) { + loadJs(NETDATA.serverDefault + data.custom_info, function () { $.extend(true, netdataDashboard, customDashboard); initializeDynamicDashboardWithData(data); }); @@ -2542,7 +2896,7 @@ } else if(sha1 === sha2) { save = true; - versionLog('<p><big>You already have the latest 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>'); + versionLog('<p><big>You already have the latest 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><i class="fas fa-star"></i></b> at its github page</a>.</p>'); } else { save = true; @@ -2559,19 +2913,1133 @@ } // ---------------------------------------------------------------------------- + // printing dashboards - function finalizePage() { - // resize all charts - without starting the background thread - // this has to be done while NETDATA is paused - // if we ommit this, the affix menu will be wrong, since all - // the Dom elements are initially zero-sized - NETDATA.parseDom(); + function showPageFooter() { + document.getElementById('footer').style.display = 'block'; + } + + + function printPreflight() { + var url = document.location.origin + document.location.search + '#' + urlOptions.genHash() + ';mode=print'; + var width = 990; + var height = screen.height * 90 / 100; + //console.log(url); + //console.log(document.location); + window.open(url, '', 'width=' + width.toString() + ',height=' + height.toString() + ',menubar=no,toolbar=no,personalbar=no,location=no,resizable=no,scrollbars=yes,status=no,chrome=yes,centerscreen=yes,attention=yes,dialog=yes'); + $('#printPreflightModal').modal('hide'); + } + + function printPage() { + var print_is_rendering = true; + + $('#printModal').on('hide.bs.modal', function(e) { + if(print_is_rendering === true) { + e.preventDefault(); + return false; + } + + return true; + }); + + $('#printModal').on('show.bs.modal', function() { + var print_options = { + stop_updates_when_focus_is_lost: false, + update_only_visible: false, + sync_selection: false, + eliminate_zero_dimensions: false, + pan_and_zoom_data_padding: false, + show_help: false, + legend_toolbox: false, + resize_charts: false, + pixels_per_point: 1 + }; - if(urlOptions.pan_and_zoom === true) + var x; + for(x in print_options) { + if (print_options.hasOwnProperty(x)) + NETDATA.options.current[x] = print_options[x]; + } + + NETDATA.parseDom(); + showPageFooter(); + + NETDATA.globalSelectionSync.stop(); NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before); + // NETDATA.onresize(); + + var el = document.getElementById('printModalProgressBar'); + var eltxt = document.getElementById('printModalProgressBarText'); + + function update_chart(idx) { + var state = NETDATA.options.targets[--idx]; + + var pcent = (NETDATA.options.targets.length - idx) * 100 / NETDATA.options.targets.length; + $(el).css('width', pcent+'%').attr('aria-valuenow', pcent); + eltxt.innerText = Math.round(pcent).toString() + '%, ' + state.id; + + setTimeout(function() { + state.updateChart(function () { + NETDATA.options.targets[idx].resizeForPrint(); + + if (idx > 0) { + update_chart(idx); + } + else { + print_is_rendering = false; + $('#printModal').modal('hide'); + window.print(); + window.close(); + } + }) + }, 0); + } + + print_is_rendering = true; + update_chart(NETDATA.options.targets.length); + }); + + $('#printModal').modal('show'); + } + + // -------------------------------------------------------------------- + + function jsonStringifyFn(obj) { + return JSON.stringify(obj, function (key, value) { + return (typeof value === 'function' ) ? value.toString() : value; + }); + } + + function jsonParseFn(str) { + return JSON.parse(str, function (key, value) { + if (typeof value != 'string') return value; + return ( value.substring(0, 8) == 'function') ? eval('(' + value + ')') : value; + }); + } + + // -------------------------------------------------------------------- + + var snapshotOptions = { + bytes_per_chart: 2048, + compressionDefault: 'pako.deflate.base64', + + compressions: { + 'none': { + bytes_per_point_memory: 5.2, + bytes_per_point_disk: 5.6, + + compress: function (s) { + return s; + }, + + compressed_length: function (s) { + return s.length; + }, + + uncompress: function (s) { + return s; + } + }, + + 'pako.deflate.base64': { + bytes_per_point_memory: 1.8, + bytes_per_point_disk: 1.9, + + compress: function (s) { + return btoa(pako.deflate(s, { to: 'string' })); + }, + + compressed_length: function (s) { + return s.length; + }, + + uncompress: function (s) { + return pako.inflate(atob(s), {to: 'string'}); + } + }, + + 'pako.deflate': { + bytes_per_point_memory: 1.4, + bytes_per_point_disk: 3.2, + + compress: function (s) { + return pako.deflate(s, { to: 'string' }); + }, + + compressed_length: function (s) { + return s.length; + }, + + uncompress: function (s) { + return pako.inflate(s, {to: 'string'}); + } + }, + + 'lzstring.utf16': { + bytes_per_point_memory: 1.7, + bytes_per_point_disk: 2.6, + + compress: function (s) { + return LZString.compressToUTF16(s); + }, + + compressed_length: function (s) { + return s.length * 2; + }, + + uncompress: function (s) { + return LZString.decompressFromUTF16(s); + } + }, + + 'lzstring.base64': { + bytes_per_point_memory: 2.1, + bytes_per_point_disk: 2.3, + + compress: function (s) { + return LZString.compressToBase64(s); + }, + + compressed_length: function (s) { + return s.length; + }, + + uncompress: function (s) { + return LZString.decompressFromBase64(s); + } + }, + + 'lzstring.uri': { + bytes_per_point_memory: 2.1, + bytes_per_point_disk: 2.3, + + compress: function (s) { + return LZString.compressToEncodedURIComponent(s); + }, + + compressed_length: function (s) { + return s.length; + }, + + uncompress: function (s) { + return LZString.decompressFromEncodedURIComponent(s); + } + } + } + }; + + // -------------------------------------------------------------------- + // loading snapshots + + function loadSnapshotModalLog(priority, msg) { + document.getElementById('loadSnapshotStatus').className = "alert alert-" + priority; + document.getElementById('loadSnapshotStatus').innerHTML = msg; + } + + var tmpSnapshotData = null; + function loadSnapshot() { + $('#loadSnapshotImport').addClass('disabled'); + + if(tmpSnapshotData === null) { + loadSnapshotModalLog('danger', 'no data have been loaded'); + return; + } + + loadPako(function() { + loadLzString(function () { + loadSnapshotModalLog('info', 'Please wait, activating snapshot...'); + $('#loadSnapshotModal').modal('hide'); + + netdataShowAlarms === false; + netdataRegistry = false; + netdataServer = tmpSnapshotData.server; + NETDATA.serverDefault = netdataServer; + + document.getElementById('charts_div').innerHTML = ''; + document.getElementById('sidebar').innerHTML = ''; + NETDATA.globalReset(); + + if (typeof tmpSnapshotData.hash !== 'undefined') + urlOptions.hash = tmpSnapshotData.hash; + else + urlOptions.hash = '#'; + + if (typeof tmpSnapshotData.info !== 'undefined') { + var info = jsonParseFn(tmpSnapshotData.info); + if (typeof info.menu !== 'undefined') + netdataDashboard.menu = info.menu; + + if (typeof info.submenu !== 'undefined') + netdataDashboard.submenu = info.submenu; + + if (typeof info.context !== 'undefined') + netdataDashboard.context = info.context; + } + + if (typeof tmpSnapshotData.compression !== 'string') + tmpSnapshotData.compression = 'none'; + + if (typeof snapshotOptions.compressions[tmpSnapshotData.compression] === 'undefined') { + alert('unknown compression method: ' + tmpSnapshotData.compression); + tmpSnapshotData.compression = 'none'; + } + + tmpSnapshotData.uncompress = snapshotOptions.compressions[tmpSnapshotData.compression].uncompress; + netdataSnapshotData = tmpSnapshotData; + + urlOptions.after = tmpSnapshotData.after_ms; + urlOptions.before = tmpSnapshotData.before_ms; + + if( typeof tmpSnapshotData.highlight_after_ms !== 'undefined' + && tmpSnapshotData.highlight_after_ms !== null + && tmpSnapshotData.highlight_after_ms > 0 + && typeof tmpSnapshotData.highlight_before_ms !== 'undefined' + && tmpSnapshotData.highlight_before_ms !== null + && tmpSnapshotData.highlight_before_ms > 0 + ) { + urlOptions.highlight_after = tmpSnapshotData.highlight_after_ms; + urlOptions.highlight_before = tmpSnapshotData.highlight_before_ms; + urlOptions.highlight = true; + } + else { + urlOptions.highlight_after = 0; + urlOptions.highlight_before = 0; + urlOptions.highlight = false; + } + + initializeDynamicDashboard(); + }); + }); + }; + + + function loadSnapshotPreflightFile(file) { + var fr = new FileReader(); + fr.onload = function(e) { + document.getElementById('loadSnapshotFilename').innerHTML = file.name; + var result = null; + try { + result = JSON.parse(e.target.result); + //console.log(result); + var date_after = new Date(result.after_ms); + var date_before = new Date(result.before_ms); + + if (typeof result.charts_ok === 'undefined') + result.charts_ok = 'unknown'; + + if (typeof result.charts_failed === 'undefined') + result.charts_failed = 0; + + if (typeof result.compression === 'undefined') + result.compression = 'none'; + + if (typeof result.data_size === 'undefined') + result.data_size = 0; + + document.getElementById('loadSnapshotFilename').innerHTML = '<code>' + file.name + '</code>'; + document.getElementById('loadSnapshotHostname').innerHTML = '<b>' + result.hostname + '</b>, netdata version: <b>' + result.netdata_version.toString() + '</b>'; + document.getElementById('loadSnapshotURL').innerHTML = result.url; + document.getElementById('loadSnapshotCharts').innerHTML = result.charts.charts_count.toString() + ' charts, ' + result.charts.dimensions_count.toString() + ' dimensions, ' + result.data_points.toString() + ' points per dimension, ' + Math.round(result.duration_ms / result.data_points).toString() + ' ms per point'; + document.getElementById('loadSnapshotInfo').innerHTML = 'version: <b>' + result.snapshot_version.toString() + '</b>, includes <b>' + result.charts_ok.toString() + '</b> unique chart data queries ' + ((result.charts_failed > 0) ? ('<b>' + result.charts_failed.toString() + '</b> failed') : '').toString() + ', compressed with <code>' + result.compression.toString() + '</code>, data size ' + (Math.round(result.data_size * 100 / 1024 / 1024) / 100).toString() + ' MB'; + document.getElementById('loadSnapshotTimeRange').innerHTML = '<b>' + NETDATA.dateTime.localeDateString(date_after) + ' ' + NETDATA.dateTime.localeTimeString(date_after) + '</b> to <b>' + NETDATA.dateTime.localeDateString(date_before) + ' ' + NETDATA.dateTime.localeTimeString(date_before) + '</b>'; + document.getElementById('loadSnapshotComments').innerHTML = ((result.comments) ? result.comments : '').toString(); + loadSnapshotModalLog('success', 'File loaded, click <b>Import</b> to render it!'); + $('#loadSnapshotImport').removeClass('disabled'); + + tmpSnapshotData = result; + } + catch (e) { + console.log(e); + document.getElementById('loadSnapshotStatus').className = "alert alert-danger"; + document.getElementById('loadSnapshotStatus').innerHTML = "Failed to parse this file!"; + $('#loadSnapshotImport').addClass('disabled'); + } + } + + //console.log(file); + fr.readAsText(file); + }; + + function loadSnapshotPreflightEmpty() { + document.getElementById('loadSnapshotFilename').innerHTML = ''; + document.getElementById('loadSnapshotHostname').innerHTML = ''; + document.getElementById('loadSnapshotURL').innerHTML = ''; + document.getElementById('loadSnapshotCharts').innerHTML = ''; + document.getElementById('loadSnapshotInfo').innerHTML = ''; + document.getElementById('loadSnapshotTimeRange').innerHTML = ''; + document.getElementById('loadSnapshotComments').innerHTML = ''; + $('#loadSnapshotImport').addClass('disabled'); + }; + + var loadSnapshotDragAndDropInitialized = false; + function loadSnapshotDragAndDropSetup() { + if(loadSnapshotDragAndDropInitialized === false) { + loadSnapshotDragAndDropInitialized = true; + $('#loadSnapshotDragAndDrop') + .on('drag dragstart dragend dragover dragenter dragleave drop', function (e) { + e.preventDefault(); + e.stopPropagation(); + }) + .on('drop', function (e) { + if(e.originalEvent.dataTransfer.files.length) { + loadSnapshotPreflightFile(e.originalEvent.dataTransfer.files.item(0)); + } + else { + loadSnapshotPreflightEmpty(); + loadSnapshotModalLog('danger', 'No file selected'); + } + }); + } + }; + + function loadSnapshotPreflight() { + var files = document.getElementById('loadSnapshotSelectFiles').files; + if (files.length <= 0) { + loadSnapshotPreflightEmpty(); + loadSnapshotModalLog('danger', 'No file selected'); + return; + } + + loadSnapshotModalLog('info', 'Loading file...'); + + loadSnapshotPreflightFile(files.item(0)); + } + + // -------------------------------------------------------------------- + // saving snapshots + + var saveSnapshotStop = false; + function saveSnapshotCancel() { + saveSnapshotStop = true; + } + + var saveSnapshotModalInitialized = false; + function saveSnapshotModalSetup() { + if(saveSnapshotModalInitialized === false) { + saveSnapshotModalInitialized = true; + $('#saveSnapshotModal') + .on('hide.bs.modal', saveSnapshotCancel) + .on('show.bs.modal', saveSnapshotModalInit) + .on('shown.bs.modal', function() { + $('#saveSnapshotResolutionSlider').find(".slider-handle:first").attr("tabindex", 1); + document.getElementById('saveSnapshotComments').focus(); + }); + } + }; + + function saveSnapshotModalLog(priority, msg) { + document.getElementById('saveSnapshotStatus').className = "alert alert-" + priority; + document.getElementById('saveSnapshotStatus').innerHTML = msg; + } + + function saveSnapshotModalShowExpectedSize() { + var points = Math.round(saveSnapshotViewDuration / saveSnapshotSelectedSecondsPerPoint); + var priority = 'info'; + var msg = 'A moderate snapshot.'; + + var sizemb = Math.round( + (options.data.charts_count * snapshotOptions.bytes_per_chart + + options.data.dimensions_count * points * snapshotOptions.compressions[saveSnapshotCompression].bytes_per_point_disk) + * 10 / 1024 / 1024) / 10; + + var memmb = Math.round( + (options.data.charts_count * snapshotOptions.bytes_per_chart + + options.data.dimensions_count * points * snapshotOptions.compressions[saveSnapshotCompression].bytes_per_point_memory) + * 10 / 1024 / 1024) / 10; + + if(sizemb < 10) { + priority = 'success'; + msg = 'A nice small snapshot!'; + } + if(sizemb > 50) { + priority = 'warning'; + msg = 'Will stress your browser...'; + } + if(sizemb > 100) { + priority = 'danger'; + msg = 'Hm... good luck...'; + } + + saveSnapshotModalLog(priority, 'The snapshot will have ' + points.toString() + ' points per dimension. Expected size on disk ' + sizemb + ' MB, at browser memory ' + memmb + ' MB.<br/>' + msg); + } + + var saveSnapshotCompression = snapshotOptions.compressionDefault; + function saveSnapshotSetCompression(name) { + saveSnapshotCompression = name; + document.getElementById('saveSnapshotCompressionName').innerHTML = saveSnapshotCompression; + saveSnapshotModalShowExpectedSize(); + } + + var saveSnapshotSlider = null; + var saveSnapshotSelectedSecondsPerPoint = 1; + var saveSnapshotViewDuration = 1; + function saveSnapshotModalInit() { + $('#saveSnapshotModalProgressSection').hide(); + $('#saveSnapshotResolutionRadio').show(); + saveSnapshotModalLog('info', 'Select resolution and click <b>Save</b>'); + $('#saveSnapshotExport').removeClass('disabled'); + + loadBootstrapSlider(function() { + saveSnapshotViewDuration = options.duration; + var start_ms = Math.round(Date.now() - saveSnapshotViewDuration * 1000); + + if(NETDATA.globalPanAndZoom.isActive() === true) { + saveSnapshotViewDuration = Math.round((NETDATA.globalPanAndZoom.force_before_ms - NETDATA.globalPanAndZoom.force_after_ms) / 1000); + start_ms = NETDATA.globalPanAndZoom.force_after_ms; + } + + var start_date = new Date(start_ms); + var yyyymmddhhssmm = start_date.getFullYear() + NETDATA.zeropad(start_date.getMonth() + 1) + NETDATA.zeropad(start_date.getDate()) + '-' + NETDATA.zeropad(start_date.getHours()) + NETDATA.zeropad(start_date.getMinutes()) + NETDATA.zeropad(start_date.getSeconds()); + + document.getElementById('saveSnapshotFilename').value = 'netdata-' + options.hostname.toString() + '-' + yyyymmddhhssmm.toString() + '-' + saveSnapshotViewDuration.toString() + '.snapshot' + saveSnapshotSetCompression(saveSnapshotCompression); + + var min = options.update_every; + var max = Math.round(saveSnapshotViewDuration / 100); + + if(NETDATA.globalPanAndZoom.isActive() === false) + max = Math.round(saveSnapshotViewDuration / 50); + + var view = Math.round(saveSnapshotViewDuration / Math.round($(document.getElementById('charts_div')).width() / 2)); + + // console.log('view duration: ' + saveSnapshotViewDuration + ', min: ' + min + ', max: ' + max + ', view: ' + view); + + if(max < 10) max = 10; + if(max < min) max = min; + if(view < min) view = min; + if(view > max) view = max; + + if(saveSnapshotSlider !== null) + saveSnapshotSlider.destroy(); + + saveSnapshotSlider = new Slider('#saveSnapshotResolutionSlider', { + ticks: [ min, view, max ], + min: min, + max: max, + step: options.update_every, + value: view, + scale: (max > 100)?'logarithmic':'linear', + tooltip: 'always', + formatter: function(value) { + if(value < 1) + value = 1; + + if(value < options.data.update_every) + value = options.data.update_every; + + saveSnapshotSelectedSecondsPerPoint = value; + saveSnapshotModalShowExpectedSize(); + + var seconds = ' seconds '; + if(value === 1) + seconds = ' second '; + + return value + seconds + 'per point' + ((value === options.data.update_every)?', server default':'').toString(); + } + }); + }); + } + + function saveSnapshot() { + loadPako(function () { + loadLzString(function () { + saveSnapshotStop = false; + $('#saveSnapshotModalProgressSection').show(); + $('#saveSnapshotResolutionRadio').hide(); + $('#saveSnapshotExport').addClass('disabled'); + + var filename = document.getElementById('saveSnapshotFilename').value; + // console.log(filename); + saveSnapshotModalLog('info', 'Generating snapshot as <code>' + filename.toString() + '</code>'); + + var save_options = { + stop_updates_when_focus_is_lost: false, + update_only_visible: false, + sync_selection: false, + eliminate_zero_dimensions: true, + pan_and_zoom_data_padding: false, + show_help: false, + legend_toolbox: false, + resize_charts: false, + pixels_per_point: 1 + }; + var backedup_options = {}; + + var x; + for (x in save_options) { + if (save_options.hasOwnProperty(x)) { + backedup_options[x] = NETDATA.options.current[x]; + NETDATA.options.current[x] = save_options[x]; + } + } + + var el = document.getElementById('saveSnapshotModalProgressBar'); + var eltxt = document.getElementById('saveSnapshotModalProgressBarText'); + + options.data.charts_by_name = null; + + var saveData = { + hostname: options.hostname, + server: NETDATA.serverDefault, + netdata_version: options.data.version, + snapshot_version: 1, + after_ms: Date.now() - options.duration * 1000, + before_ms: Date.now(), + highlight_after_ms: urlOptions.highlight_after, + highlight_before_ms: urlOptions.highlight_before, + duration_ms: options.duration * 1000, + update_every_ms: options.update_every * 1000, + data_points: 0, + url: ((urlOptions.server !== null) ? urlOptions.server : document.location.origin.toString() + document.location.pathname.toString() + document.location.search.toString()).toString(), + comments: document.getElementById('saveSnapshotComments').value.toString(), + hash: urlOptions.hash, + charts: options.data, + info: jsonStringifyFn({ + menu: netdataDashboard.menu, + submenu: netdataDashboard.submenu, + context: netdataDashboard.context + }), + charts_ok: 0, + charts_failed: 0, + compression: saveSnapshotCompression, + data_size: 0, + data: {} + }; + + if(typeof snapshotOptions.compressions[saveData.compression] === 'undefined') { + alert('unknown compression method: ' + saveData.compression); + saveData.compression = 'none'; + } + + var compress = snapshotOptions.compressions[saveData.compression].compress; + var compressed_length = snapshotOptions.compressions[saveData.compression].compressed_length; + + function pack_api1_v1_chart_data(state) { + if (state.library_name === null || state.data === null) + return; + + var data = state.data; + state.data = null; + data.state = null; + str = JSON.stringify(data); + + if (typeof str === 'string') { + var cstr = compress(str); + saveData.data[state.chartDataUniqueID()] = cstr; + return compressed_length(cstr); + } + else + return 0; + } + + var clearPanAndZoom = false; + if (NETDATA.globalPanAndZoom.isActive() === false) { + NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], saveData.after_ms, saveData.before_ms); + clearPanAndZoom = true; + } + + saveData.after_ms = NETDATA.globalPanAndZoom.force_after_ms; + saveData.before_ms = NETDATA.globalPanAndZoom.force_before_ms; + saveData.duration_ms = saveData.before_ms - saveData.after_ms; + saveData.data_points = Math.round((saveData.before_ms - saveData.after_ms) / (saveSnapshotSelectedSecondsPerPoint * 1000)); + saveSnapshotModalLog('info', 'Generating snapshot with ' + saveData.data_points.toString() + ' data points per dimension...'); + + var charts_count = 0; + var charts_ok = 0; + var charts_failed = 0; + + function saveSnapshotRestore() { + $('#saveSnapshotModal').modal('hide'); + + // restore the options + var x; + for (x in backedup_options) { + if (backedup_options.hasOwnProperty(x)) + NETDATA.options.current[x] = backedup_options[x]; + } + + $(el).css('width', '0%').attr('aria-valuenow', 0); + eltxt.innerText = '0%'; + + if (clearPanAndZoom) + NETDATA.globalPanAndZoom.clearMaster(); + + NETDATA.options.force_data_points = 0; + NETDATA.options.fake_chart_rendering = false; + NETDATA.onscroll_updater_enabled = true; + NETDATA.onresize(); + NETDATA.unpause(); + + $('#saveSnapshotExport').removeClass('disabled'); + } + + NETDATA.globalSelectionSync.stop(); + NETDATA.options.force_data_points = saveData.data_points; + NETDATA.options.fake_chart_rendering = true; + NETDATA.onscroll_updater_enabled = false; + NETDATA.abort_all_refreshes(); + + var size = 0; + var info = ' Resolution: <b>' + saveSnapshotSelectedSecondsPerPoint.toString() + ((saveSnapshotSelectedSecondsPerPoint === 1)?' second ':' seconds ').toString() + 'per point</b>.'; + + function update_chart(idx) { + if (saveSnapshotStop === true) { + saveSnapshotModalLog('info', 'Cancelled!'); + saveSnapshotRestore(); + return; + } + + var state = NETDATA.options.targets[--idx]; + + var pcent = (NETDATA.options.targets.length - idx) * 100 / NETDATA.options.targets.length; + $(el).css('width', pcent + '%').attr('aria-valuenow', pcent); + eltxt.innerText = Math.round(pcent).toString() + '%, ' + state.id; + + setTimeout(function () { + charts_count++; + state.isVisible(true); + state.current.force_after_ms = saveData.after_ms; + state.current.force_before_ms = saveData.before_ms; + + state.updateChart(function (status, reason) { + state.current.force_after_ms = null; + state.current.force_before_ms = null; + + if (status === true) { + charts_ok++; + // state.log('ok'); + size += pack_api1_v1_chart_data(state); + } + else { + charts_failed++; + state.log('failed to be updated: ' + reason); + } + + saveSnapshotModalLog((charts_failed) ? 'danger' : 'info', 'Generated snapshot data size <b>' + (Math.round(size * 100 / 1024 / 1024) / 100).toString() + ' MB</b>. ' + ((charts_failed) ? (charts_failed.toString() + ' charts have failed to be downloaded') : '').toString() + info); + + if (idx > 0) { + update_chart(idx); + } + else { + saveData.charts_ok = charts_ok; + saveData.charts_failed = charts_failed; + saveData.data_size = size; + // console.log(saveData.compression + ': ' + (size / (options.data.dimensions_count * Math.round(saveSnapshotViewDuration / saveSnapshotSelectedSecondsPerPoint))).toString()); + + // save it + // console.log(saveData); + saveObjectToClient(saveData, filename); + + if (charts_failed > 0) + alert(charts_failed.toString() + ' failed to be downloaded'); + + saveSnapshotRestore(); + saveData = null; + } + }) + }, 0); + } + + update_chart(NETDATA.options.targets.length); + }); + }); + } + + // -------------------------------------------------------------------- + // activate netdata on the page + + function dashboardSettingsSetup() { + var update_options_modal = function() { + // console.log('update_options_modal'); + + var sync_option = function(option) { + var self = $('#' + option); + + if(self.prop('checked') !== NETDATA.getOption(option)) { + // console.log('switching ' + option.toString()); + self.bootstrapToggle(NETDATA.getOption(option)?'on':'off'); + } + }; + + var theme_sync_option = function(option) { + var self = $('#' + option); + + self.bootstrapToggle(netdataTheme === 'slate'?'on':'off'); + }; + var units_sync_option = function(option) { + var self = $('#' + option); + + if(self.prop('checked') !== (NETDATA.getOption('units') === 'auto')) { + self.bootstrapToggle(NETDATA.getOption('units') === 'auto' ? 'on' : 'off'); + } + + if(self.prop('checked') === true) { + $('#settingsLocaleTempRow').show(); + $('#settingsLocaleTimeRow').show(); + } + else { + $('#settingsLocaleTempRow').hide(); + $('#settingsLocaleTimeRow').hide(); + } + }; + var temp_sync_option = function(option) { + var self = $('#' + option); + + if(self.prop('checked') !== (NETDATA.getOption('temperature') === 'celsius')) { + self.bootstrapToggle(NETDATA.getOption('temperature') === 'celsius' ? 'on' : 'off'); + } + }; + var timezone_sync_option = function(option) { + var self = $('#' + option); + + document.getElementById('browser_timezone').innerText = NETDATA.options.browser_timezone; + document.getElementById('server_timezone').innerText = NETDATA.options.server_timezone; + document.getElementById('current_timezone').innerText = (NETDATA.options.current.timezone === 'default')?'unset, using browser default':NETDATA.options.current.timezone; + + if(self.prop('checked') === NETDATA.dateTime.using_timezone) { + self.bootstrapToggle(NETDATA.dateTime.using_timezone ? 'off' : 'on'); + } + }; + + sync_option('eliminate_zero_dimensions'); + sync_option('destroy_on_hide'); + sync_option('async_on_scroll'); + sync_option('parallel_refresher'); + sync_option('concurrent_refreshes'); + sync_option('sync_selection'); + sync_option('sync_pan_and_zoom'); + sync_option('stop_updates_when_focus_is_lost'); + sync_option('smooth_plot'); + sync_option('pan_and_zoom_data_padding'); + sync_option('show_help'); + sync_option('seconds_as_time'); + theme_sync_option('netdata_theme_control'); + units_sync_option('units_conversion'); + temp_sync_option('units_temp'); + timezone_sync_option('local_timezone'); + + if(NETDATA.getOption('parallel_refresher') === false) { + $('#concurrent_refreshes_row').hide(); + } + else { + $('#concurrent_refreshes_row').show(); + } + }; + NETDATA.setOption('setOptionCallback', update_options_modal); + + // handle options changes + $('#eliminate_zero_dimensions').change(function() { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); }); + $('#destroy_on_hide').change(function() { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); }); + $('#async_on_scroll').change(function() { NETDATA.setOption('async_on_scroll', $(this).prop('checked')); }); + $('#parallel_refresher').change(function() { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); }); + $('#concurrent_refreshes').change(function() { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); }); + $('#sync_selection').change(function() { NETDATA.setOption('sync_selection', $(this).prop('checked')); }); + $('#sync_pan_and_zoom').change(function() { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); }); + $('#stop_updates_when_focus_is_lost').change(function() { + urlOptions.update_always = !$(this).prop('checked'); + urlOptions.hashUpdate(); + + NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always); + }); + $('#smooth_plot').change(function() { NETDATA.setOption('smooth_plot', $(this).prop('checked')); }); + $('#pan_and_zoom_data_padding').change(function() { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); }); + $('#seconds_as_time').change(function() { NETDATA.setOption('seconds_as_time', $(this).prop('checked')); }); + $('#local_timezone').change(function() { + if($(this).prop('checked')) + selected_server_timezone('default', true); + else + selected_server_timezone('default', false); + }); + + + $('#units_conversion').change(function() { + NETDATA.setOption('units', $(this).prop('checked')?'auto':'original'); + }); + $('#units_temp').change(function() { + NETDATA.setOption('temperature', $(this).prop('checked')?'celsius':'fahrenheit'); + }); + + $('#show_help').change(function() { + urlOptions.help = $(this).prop('checked'); + urlOptions.hashUpdate(); + + NETDATA.setOption('show_help', urlOptions.help); + netdataReload(); + }); + + // this has to be the last + // it reloads the page + $('#netdata_theme_control').change(function() { + urlOptions.theme = $(this).prop('checked')?'slate':'white'; + urlOptions.hashUpdate(); + + if(setTheme(urlOptions.theme)) + netdataReload(); + }); + } + + function scrollDashboardTo() { + if(netdataSnapshotData !== null && typeof netdataSnapshotData.hash !== 'undefined') { + //console.log(netdataSnapshotData.hash); + scrollToId(netdataSnapshotData.hash.replace('#','')); + } + else { + // check if we have to jump to a specific section + scrollToId(urlOptions.hash.replace('#', '')); + + if (urlOptions.chart !== null) { + NETDATA.alarms.scrollToChart(urlOptions.chart); + //urlOptions.hash = '#' + NETDATA.name2id('menu_' + charts[c].menu + '_submenu_' + charts[c].submenu); + //urlOptions.hash = '#chart_' + NETDATA.name2id(urlOptions.chart); + //console.log('hash = ' + urlOptions.hash); + } + } + } + + var modalHiddenCallback = null; + function scrollToChartAfterHidingModal(chart) { + modalHiddenCallback = function() { + NETDATA.alarms.scrollToChart(chart); + }; + } + + var runOnceOnDashboardLastRun = 0; + function runOnceOnDashboardWithjQuery() { + if(runOnceOnDashboardLastRun !== 0) { + scrollDashboardTo(); + + // restore the scrollspy at the proper position + $(document.body).scrollspy('refresh'); + $(document.body).scrollspy('process'); + + return; + } + + runOnceOnDashboardLastRun = Date.now(); + + // ------------------------------------------------------------------------ + // bootstrap modals + + // prevent bootstrap modals from scrolling the page + // maintains the current scroll position + // https://stackoverflow.com/a/34754029/4525767 + + var scrollPos = 0; + var modal_depth = 0; // how many modals are currently open + var modal_shown = false; // set to true, if a modal is shown + var netdata_paused_on_modal = false; // set to true, if the modal paused netdata + var scrollspyOffset = $(window).height() / 3; // will be updated below - the offset of scrollspy to select an item + + $('.modal') + .on('show.bs.modal', function () { + if(modal_depth === 0) { + scrollPos = window.scrollY; + + $('body').css({ + overflow: 'hidden', + position: 'fixed', + top: -scrollPos + }); + + modal_shown = true; + + if (NETDATA.options.pauseCallback === null) { + NETDATA.pause(function () {}); + netdata_paused_on_modal = true; + } + else + netdata_paused_on_modal = false; + } + + modal_depth++; + //console.log(urlOptions.after); + + }) + .on('hide.bs.modal', function () { + + modal_depth--; + + if(modal_depth <= 0) { + modal_depth = 0; + + $('body') + .css({ + overflow: '', + position: '', + top: '' + }); + + // scroll to the position we had open before the modal + $('html, body') + .animate({scrollTop: scrollPos}, 0); + + // unpause netdata, if we paused it + if (netdata_paused_on_modal === true) { + NETDATA.unpause(); + netdata_paused_on_modal = false; + } + + // restore the scrollspy at the proper position + $(document.body).scrollspy('process'); + } + //console.log(urlOptions.after); + }) + .on('hidden.bs.modal', function () { + if(modal_depth === 0) + modal_shown = false; + + if(typeof modalHiddenCallback === 'function') + modalHiddenCallback(); + + modalHiddenCallback = null; + //console.log(urlOptions.after); + }); + + // ------------------------------------------------------------------------ + // sidebar / affix + + $('#sidebar') + .affix({ + offset: { + top: (isdemo())?150:0, + bottom: 0 + } + }) + .on('affixed.bs.affix', function() { + // fix scrolling of very long affix lists + // http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long + + $(this).removeAttr('style'); + }) + .on( 'affix-top.bs.affix', function() { + // fix bootstrap affix click bug + // https://stackoverflow.com/a/37847981/4525767 + + if(modal_shown) return false; + }) + .on('activate.bs.scrollspy', function (e) { + // change the URL based on the current position of the screen + + if(modal_shown === false) { + var el = $(e.target); + var hash = el.find('a').attr('href'); + if (typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) { + urlOptions.hash = hash; + urlOptions.hashUpdate(); + } + } + }); + + Ps.initialize(document.getElementById('sidebar'), { + wheelSpeed: 0.5, + wheelPropagation: true, + swipePropagation: true, + minScrollbarLength: null, + maxScrollbarLength: null, + useBothWheelAxes: false, + suppressScrollX: true, + suppressScrollY: false, + scrollXMarginOffset: 0, + scrollYMarginOffset: 0, + theme: 'default' + }); + + + // ------------------------------------------------------------------------ + // scrollspy + + if(scrollspyOffset > 250) scrollspyOffset = 250; + if(scrollspyOffset < 75) scrollspyOffset = 75; + document.body.setAttribute('data-offset', scrollspyOffset); + + // scroll the dashboard, before activating the scrollspy, so that our + // hash will not be updated before we got the chance to scroll to it + scrollDashboardTo(); + + $(document.body).scrollspy({ + target: '#sidebar', + offset: scrollspyOffset // controls the diff of the <hX> element to the top, to select it + }); + + + // ------------------------------------------------------------------------ + // my-netdata menu + + Ps.initialize(document.getElementById('myNetdataDropdownUL'), { + wheelSpeed: 1, + wheelPropagation: false, + swipePropagation: false, + minScrollbarLength: null, + maxScrollbarLength: null, + useBothWheelAxes: false, + suppressScrollX: true, + suppressScrollY: false, + scrollXMarginOffset: 0, + scrollYMarginOffset: 0, + theme: 'default' + }); + + $('#myNetdataDropdownParent') + .on('show.bs.dropdown', function () { + var hash = urlOptions.genHash(); + $('.registry_link').each(function(idx) { + this.setAttribute('href', this.getAttribute("href").replace(/#.*$/, hash)); + }); + + NETDATA.pause(function() {}); + }) + .on('shown.bs.dropdown', function () { + Ps.update(document.getElementById('myNetdataDropdownUL')); + }) + .on('hidden.bs.dropdown', function () { + NETDATA.unpause(); + }); + + + $('#deleteRegistryModal') + .on('hidden.bs.modal', function() { + deleteRegistryGuid = null; + }); + + + // ------------------------------------------------------------------------ + // update modal + + $('#updateModal') + .on('show.bs.modal', function() { + versionLog('checking, please wait...'); + }) + .on('shown.bs.modal', function() { + notifyForUpdate(true); + }); + + + // ------------------------------------------------------------------------ + // alarms modal + + $('#alarmsModal') + .on('shown.bs.modal', function() { + alarmsUpdateModal(); + }) + .on('hidden.bs.modal', function() { + document.getElementById('alarms_active').innerHTML = + document.getElementById('alarms_all').innerHTML = + document.getElementById('alarms_log').innerHTML = + 'loading...'; + }); + + + // ------------------------------------------------------------------------ + + dashboardSettingsSetup(); + loadSnapshotDragAndDropSetup(); + saveSnapshotModalSetup(); + showPageFooter(); + // ------------------------------------------------------------------------ // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js + $.fn.shorten = function(settings) { "use strict"; @@ -2579,8 +4047,8 @@ showChars: 750, minHideChars: 10, ellipsesText: "...", - moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information', - lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information', + moreText: '<i class="fas fa-expand"></i> show more information', + lessText: '<i class="fas fa-compress"></i> show less information', onLess: function() { NETDATA.onscroll(); }, onMore: function() { NETDATA.onscroll(); }, errMsg: null, @@ -2692,178 +4160,53 @@ } var html = '<div class="shortcontent">' + c + - '</div><div class="allcontent">' + content + - '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>'; + '</div><div class="allcontent">' + content + + '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>'; $this.html(html); $this.find(".allcontent").hide(); // Hide all text $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened } }); - }; - $(".chart-message").shorten(); - // ------------------------------------------------------------------------ - - // callback for us to track PanAndZoom operations - NETDATA.globalPanAndZoom.callback = urlOptions.netdataPanAndZoomCallback; - - // let it run (update the charts) - NETDATA.unpause(); - - // check if we have to jump to a specific section - scrollToId(urlOptions.hash.replace('#','')); - - if(urlOptions.chart !== null) { - NETDATA.alarms.scrollToChart(urlOptions.chart); - //urlOptions.hash = '#' + NETDATA.name2id('menu_' + charts[c].menu + '_submenu_' + charts[c].submenu); - //urlOptions.hash = '#chart_' + NETDATA.name2id(urlOptions.chart); - //console.log('hash = ' + urlOptions.hash); - } - - var $sidebar = $('#sidebar'); - /* activate bootstrap sidebar (affix) */ - $sidebar.affix({ - offset: { - top: (isdemo())?150:0, - bottom: 0 - } - }); - - /* fix scrolling of very long affix lists - http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long - */ - $sidebar.on('affixed.bs.affix', function() { - $(this).removeAttr('style'); - }); - - /* activate bootstrap scrollspy (needed for sidebar) */ - var scrollspyOffset = $(window).height() / 5; - if(scrollspyOffset > 200) scrollspyOffset = 200; - if(scrollspyOffset < 50) scrollspyOffset = 50; - $(document.body).scrollspy({ - target: '#sidebar', - offset: scrollspyOffset // controls the diff of the <hX> element to the top, to select it - }); - - // change the URL based on the current position of the screen - $sidebar.on('activate.bs.scrollspy', function (e) { - //console.log(e); - var el = $(e.target); - //if(el.find('ul').size() === 0) { - var hash = el.find('a').attr('href'); - // console.log(hash); - if(typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) { - urlOptions.hash = hash; - //console.log(urlOptions.hash); - urlOptions.hashUpdate(); - } - //else console.log('hash: not accepting ' + hash); - //} - //else console.log('el.find(): not found'); - }); - - document.getElementById('footer').style.display = 'block'; - - var update_options_modal = function() { - // console.log('update_options_modal'); - - var sync_option = function(option) { - var self = $('#' + option); - - if(self.prop('checked') !== NETDATA.getOption(option)) { - // console.log('switching ' + option.toString()); - self.bootstrapToggle(NETDATA.getOption(option)?'on':'off'); - } - }; - - var theme_sync_option = function(option) { - var self = $('#' + option); - - self.bootstrapToggle(netdataTheme === 'slate'?'on':'off'); - }; - - sync_option('eliminate_zero_dimensions'); - sync_option('destroy_on_hide'); - sync_option('async_on_scroll'); - sync_option('parallel_refresher'); - sync_option('concurrent_refreshes'); - sync_option('sync_selection'); - sync_option('sync_pan_and_zoom'); - sync_option('stop_updates_when_focus_is_lost'); - sync_option('smooth_plot'); - sync_option('pan_and_zoom_data_padding'); - sync_option('show_help'); - theme_sync_option('netdata_theme_control'); + } - if(NETDATA.getOption('parallel_refresher') === false) { - $('#concurrent_refreshes_row').hide(); - } - else { - $('#concurrent_refreshes_row').show(); - } - }; - NETDATA.setOption('setOptionCallback', update_options_modal); + function finalizePage() { + // resize all charts - without starting the background thread + // this has to be done while NETDATA is paused + // if we ommit this, the affix menu will be wrong, since all + // the Dom elements are initially zero-sized + NETDATA.parseDom(); - // handle options changes - $('#eliminate_zero_dimensions').change(function() { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); }); - $('#destroy_on_hide').change(function() { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); }); - $('#async_on_scroll').change(function() { NETDATA.setOption('async_on_scroll', $(this).prop('checked')); }); - $('#parallel_refresher').change(function() { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); }); - $('#concurrent_refreshes').change(function() { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); }); - $('#sync_selection').change(function() { NETDATA.setOption('sync_selection', $(this).prop('checked')); }); - $('#sync_pan_and_zoom').change(function() { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); }); - $('#stop_updates_when_focus_is_lost').change(function() { - urlOptions.update_always = !$(this).prop('checked'); - urlOptions.hashUpdate(); + // ------------------------------------------------------------------------ - NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always); - }); - $('#smooth_plot').change(function() { NETDATA.setOption('smooth_plot', $(this).prop('checked')); }); - $('#pan_and_zoom_data_padding').change(function() { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); }); - $('#show_help').change(function() { - urlOptions.help = $(this).prop('checked'); - urlOptions.hashUpdate(); + NETDATA.globalPanAndZoom.callback = null; + NETDATA.globalChartUnderlay.callback = null; - NETDATA.setOption('show_help', urlOptions.help); - netdataReload(); - }); + if(urlOptions.pan_and_zoom === true && NETDATA.options.targets.length > 0) + NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before); - // this has to be the last - // it reloads the page - $('#netdata_theme_control').change(function() { - urlOptions.theme = $(this).prop('checked')?'slate':'white'; - urlOptions.hashUpdate(); + // callback for us to track PanAndZoom operations + NETDATA.globalPanAndZoom.callback = urlOptions.netdataPanAndZoomCallback; + NETDATA.globalChartUnderlay.callback = urlOptions.netdataHighlightCallback; - if(setTheme(urlOptions.theme)) - netdataReload(); - }); + // ------------------------------------------------------------------------ - var $updateModal = $('#updateModal'); - $updateModal.on('show.bs.modal', function() { - versionLog('checking, please wait...'); - }); + // let it run (update the charts) + NETDATA.unpause(); - $updateModal.on('shown.bs.modal', function() { - notifyForUpdate(true); - }); + runOnceOnDashboardWithjQuery(); + $(".shorten").shorten(); - var $alarmsModal = $('#alarmsModal'); - $alarmsModal.on('shown.bs.modal', function() { - NETDATA.pause(alarmsUpdateModal); + $('[data-toggle="tooltip"]').tooltip({ + animated: 'fade', + trigger: 'hover', + html: true, + delay: {show: 500, hide: 0}, + container: 'body' }); + $('[data-toggle="popover"]').popover(); - $alarmsModal.on('hidden.bs.modal', function() { - NETDATA.unpause(); - document.getElementById('alarms_active').innerHTML = - document.getElementById('alarms_all').innerHTML = - document.getElementById('alarms_log').innerHTML = - 'loading...'; - }); - - $('#deleteRegistryModal').on('hidden.bs.modal', function() { - deleteRegistryGuid = null; - }); if(isdemo()) { // do not to give errors on netdata demo servers for 60 seconds @@ -2892,53 +4235,15 @@ if(urlOptions.show_alarms === true) setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000); - var sidebar = document.getElementById('sidebar'); - Ps.initialize(sidebar, { - wheelSpeed: 0.5, - wheelPropagation: true, - swipePropagation: true, - minScrollbarLength: null, - maxScrollbarLength: null, - useBothWheelAxes: false, - suppressScrollX: true, - suppressScrollY: false, - scrollXMarginOffset: 0, - scrollYMarginOffset: 0, - theme: 'default' - }); - Ps.update(sidebar); - - var registry = document.getElementById('myNetdataDropdownUL'); - Ps.initialize(registry, { - wheelSpeed: 1, - wheelPropagation: false, - swipePropagation: false, - minScrollbarLength: null, - maxScrollbarLength: null, - useBothWheelAxes: false, - suppressScrollX: true, - suppressScrollY: false, - scrollXMarginOffset: 0, - scrollYMarginOffset: 0, - theme: 'default' - }); - Ps.update(registry); - NETDATA.onresizeCallback = function() { - Ps.update(sidebar); - Ps.update(registry); + Ps.update(document.getElementById('sidebar')); + Ps.update(document.getElementById('myNetdataDropdownUL')); }; + NETDATA.onresizeCallback(); - $('#myNetdataDropdownParent') - .on('show.bs.dropdown', function () { - NETDATA.pause(function() {}); - }) - .on('shown.bs.dropdown', function () { - Ps.update(registry); - }) - .on('hidden.bs.dropdown', function () { - NETDATA.unpause(); - }); + if(netdataSnapshotData !== null) { + NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], netdataSnapshotData.after_ms, netdataSnapshotData.before_ms); + } // var netdataEnded = performance.now(); // console.log('start up time: ' + (netdataEnded - netdataStarted).toString() + ' ms'); @@ -2959,17 +4264,17 @@ // parallel javascript downloader in netdata var netdataPrepCallback = function() { NETDATA.requiredCSS.push({ - url: NETDATA.serverDefault + 'css/bootstrap-toggle-2.2.2.min.css', + url: NETDATA.serverStatic + 'css/bootstrap-toggle-2.2.2.min.css', isAlreadyLoaded: function() { return false; } }); NETDATA.requiredJs.push({ - url: NETDATA.serverDefault + 'lib/bootstrap-toggle-2.2.2.min.js', + url: NETDATA.serverStatic + 'lib/bootstrap-toggle-2.2.2.min.js', isAlreadyLoaded: function() { return false; } }); NETDATA.requiredJs.push({ - url: NETDATA.serverDefault + 'dashboard_info.js?v20170916-1', + url: NETDATA.serverStatic + 'dashboard_info.js?v20171208-1', async: false, isAlreadyLoaded: function() { return false; } }); @@ -2983,13 +4288,68 @@ } }; + var selected_server_timezone = function(timezone, status) { + //console.log('called with timezone: ' + timezone + ", status: " + ((typeof status === 'undefined')?'undefined':status).toString()); + + // clear the error + document.getElementById('timezone_error_message').innerHTML = ''; + + if (typeof status === 'undefined') { + // the user selected a timezone from the menu + + NETDATA.setOption('user_set_server_timezone', timezone); + + if (NETDATA.dateTime.init(timezone) === false) { + NETDATA.dateTime.init(); + + if(!$('#local_timezone').prop('checked')) + $('#local_timezone').bootstrapToggle('on'); + + document.getElementById('timezone_error_message').innerHTML = 'Ooops! That timezone was not accepted by your browser. Please open a github issue to help us fix it.'; + NETDATA.setOption('user_set_server_timezone', NETDATA.options.server_timezone); + } + else { + if($('#local_timezone').prop('checked')) + $('#local_timezone').bootstrapToggle('off'); + } + } + else if (status === true) { + // the user wants the browser default timezone to be activated + + NETDATA.dateTime.init(); + } + else { + // the user wants the server default timezone to be activated + //console.log('found ' + NETDATA.options.current.user_set_server_timezone); + + if (NETDATA.options.current.user_set_server_timezone === 'default') + NETDATA.options.current.user_set_server_timezone = NETDATA.options.server_timezone; + + timezone = NETDATA.options.current.user_set_server_timezone; + + if (NETDATA.dateTime.init(timezone) === false) { + NETDATA.dateTime.init(); + + if(!$('#local_timezone').prop('checked')) + $('#local_timezone').bootstrapToggle('on'); + + document.getElementById('timezone_error_message').innerHTML = 'Sorry. The timezone "' + timezone.toString() + '" is not accepted by your browser. Please select one from the list.'; + NETDATA.setOption('user_set_server_timezone', NETDATA.options.server_timezone); + } + } + + document.getElementById('current_timezone').innerText = (NETDATA.options.current.timezone === 'default')?'unset, using browser default':NETDATA.options.current.timezone; + return false; + } + // our entry point // var netdataStarted = performance.now(); + var netdataCallback = initializeDynamicDashboard; </script> </head> -<body data-spy="scroll" data-target="#sidebar"> +<body data-spy="scroll" data-target="#sidebar" data-offset="100"> <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;"> netdata<br/><div style="font-size: 3vh;">Real-time performance monitoring, done right!</div> </div> @@ -3001,7 +4361,7 @@ <div class="container"> <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;"> <ul class="nav navbar-nav"> - <li class="dropdown" id="myNetdataDropdownParent"> + <li class="dropdown" id="myNetdataDropdownParent" title="your other netdata servers" data-toggle="tooltip" data-placement="right"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a> <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu" id="myNetdataDropdownUL"> <div class="row"> @@ -3027,17 +4387,20 @@ <span class="icon-bar"></span> <span class="icon-bar"></span> </button> - <a href="/" class="navbar-brand" id="hostname" title="reload the dashboard">netdata</a> + <a href="/" class="navbar-brand" id="hostname" title="server hostname<br/>click it to reload the dashboard" data-toggle="tooltip" data-placement="bottom">netdata</a> </div> <nav class="collapse navbar-collapse navbar-right" role="navigation"> <ul class="nav navbar-nav"> - <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i> <span class="hidden-sm">Alarms </span><span id="alarms_count_badge" class="badge"></span></a></li> - <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i> <span class="hidden-sm">Settings</span></a></li> - <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i> <span class="hidden-sm hidden-md">Update </span><span id="update_badge" class="badge"></span></a></li> - <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata on github"><i class="fa fa-github"></i></a></li> - <li><a href="https://twitter.com/linuxnetdata" class="btn" target="_blank" title="netdata on twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a></li> - <li><a href="https://www.facebook.com/linuxnetdata/" class="btn" target="_blank" title="netdata on facebook"><i class="fa fa-facebook-official" aria-hidden="true"></i></a></li> - <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i> <span class="hidden-sm hidden-md">Help</span></a></li> + <li id="alarmsButton" title="check the health monitoring alarms and their log" data-toggle="tooltip" data-placement="bottom"><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fas fa-bell"></i> <span class="hidden-sm hidden-md">Alarms </span><span id="alarms_count_badge" class="badge"></span></a></li> + <li title="change dashboard settings" data-toggle="tooltip" data-placement="bottom"><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fas fa-cog"></i> <span class="hidden-sm hidden-md">Settings</span></a></li> + <li title="check for netdata updates<br/>you should keep your netdata updated" data-toggle="tooltip" data-placement="bottom" class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fas fa-cloud-download-alt"></i> <span class="hidden-sm hidden-md">Update </span><span id="update_badge" class="badge"></span></a></li> + <li title="the netdata wiki home at github<br/>remember to <b>give netdata a <i class="fas fa-star"></i></b> !" data-toggle="tooltip" data-placement="bottom" class="hidden-sm hidden-md"><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fab fa-github"></i></a></li> + <li title="follow netdata on twitter" data-toggle="tooltip" data-placement="bottom" class="hidden-sm hidden-md"><a href="https://twitter.com/linuxnetdata" class="btn" target="_blank"><i class="fab fa-twitter"></i></a></li> + <li title="like netdata on facebook" data-toggle="tooltip" data-placement="bottom" class="hidden-sm hidden-md"><a href="https://www.facebook.com/linuxnetdata/" class="btn" target="_blank"><i class="fab fa-facebook"></i></a></li> + <li title="import / load a netdata snapshot" data-toggle="tooltip" data-placement="bottom" id="loadButton"><a href="#" class="btn" data-toggle="modal" data-target="#loadSnapshotModal"><i class="fas fa-download"></i> <span class="hidden-sm hidden-md hidden-lg">Import</span></a></li> + <li title="export / save a netdata snapshot" data-toggle="tooltip" data-placement="bottom" id="saveButton"><a href="#" class="btn" data-toggle="modal" data-target="#saveSnapshotModal"><i class="fas fa-upload"></i> <span class="hidden-sm hidden-md hidden-lg">Export</span></a></li> + <li title="print this dashboard to PDF" data-toggle="tooltip" data-placement="bottom" id="printButton"><a href="#" class="btn" data-toggle="modal" data-target="#printPreflightModal"><i class="fas fa-print"></i> <span class="hidden-sm hidden-md hidden-lg">Print</span></a></li> + <li title="get help on using the charts" data-toggle="tooltip" data-placement="bottom" class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fas fa-question-circle"></i> <span class="hidden-sm hidden-md">Help</span></a></li> <li class="dropdown hidden-sm hidden-md hidden-lg"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a> <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu"> @@ -3048,6 +4411,9 @@ </nav> </div> </nav> + <div class="navbar-highlight"> + <div id="navbar-highlight-content" class="navbar-highlight-content"></div> + </div> <div id="masthead" style="display: none;"> <div class="container"> @@ -3081,7 +4447,7 @@ <div class="charts-body" role="main"> <div id="charts_div"></div> </div> - <div class="sidebar-body hidden-xs hidden-sm" id="sidebar-body" role="complementary"> + <div class="sidebar-body hidden-xs hidden-sm hidden-print" id="sidebar-body" role="complementary"> <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav> </div> </div> @@ -3092,44 +4458,44 @@ <div class="col-md-10" role="main"> <div class="p"> <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/> - <i class="fa fa-copyright"></i> Copyright 2016-2017, <a href="mailto:costa@tsaousis.gr">Costa Tsaousis</a>.<br/> + <i class="fas fa-copyright"></i> Copyright 2016-2017, <a href="mailto:costa@tsaousis.gr">Costa Tsaousis</a>.<br/> Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/> </div> <div class="p"> <small> <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools: - <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library, - <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library, + <i class="fas fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library, - <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> + <i class="fas fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library, + <i class="fas fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library, - <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library, + <i class="fas fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>, - <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>, + <i class="fas fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>, - <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>, + <i class="fas fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>, - <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> + <i class="fas fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>, + <i class="fas 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> - <i class="fa fa-circle"></i> <a href="https://github.com/noraesae/perfect-scrollbar" target="_blank">perfect-scrollbar</a>, - <i class="fa fa-copyright"></i> Copyright 2016, Hyunje Alex Jun and other contributors, <a href="https://github.com/noraesae/perfect-scrollbar/blob/master/LICENSE" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="https://github.com/noraesae/perfect-scrollbar" target="_blank">perfect-scrollbar</a>, + <i class="fas fa-copyright"></i> Copyright 2016, Hyunje Alex Jun and other contributors, <a href="https://github.com/noraesae/perfect-scrollbar/blob/master/LICENSE" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>, - <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> + <i class="fas fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>, + <i class="fas 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> - <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. + <i class="fas 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. - <i class="fa fa-circle"></i> <a href="http://bootstrap-table.wenzhixin.net.cn/" target="_blank">bootstrap-table</a>, - <i class="fa fa-copyright"></i> Copyright (c) 2012-2016 Zhixin Wen, <a href="https://github.com/wenzhixin/bootstrap-table/blob/master/LICENSE" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="http://bootstrap-table.wenzhixin.net.cn/" target="_blank">bootstrap-table</a>, + <i class="fas fa-copyright"></i> Copyright (c) 2012-2016 Zhixin Wen, <a href="https://github.com/wenzhixin/bootstrap-table/blob/master/LICENSE" target="_blank">MIT License</a> - <i class="fa fa-circle"></i> <a href="https://github.com/hhurz/tableExport.jquery.plugin" target="_blank">tableExport.jquery.plugin</a>, - <i class="fa fa-copyright"></i> Copyright (c) 2015,2016 hhurz, <a href="http://rawgit.com/hhurz/tableExport.jquery.plugin/master/tableExport.js" target="_blank">MIT License</a> + <i class="fas fa-circle"></i> <a href="https://github.com/hhurz/tableExport.jquery.plugin" target="_blank">tableExport.jquery.plugin</a>, + <i class="fas fa-copyright"></i> Copyright (c) 2015,2016 hhurz, <a href="http://rawgit.com/hhurz/tableExport.jquery.plugin/master/tableExport.js" target="_blank">MIT License</a> </small> </div> @@ -3137,6 +4503,182 @@ </div> </div> + <div class="modal fade" id="printPreflightModal" tabindex="-1" role="dialog" aria-labelledby="printPreflightModalLabel"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="printPreflightModalLabel">Print this netdata dashboard</h4> + </div> + <div class="modal-body"> + <p> + netdata dashboards cannot be captured, since we are lazy loading and hiding all but the visible charts. + <br/> + To capture the whole page with all the charts rendered, a new browser window will pop-up that will render all the charts at once. + The new browser window will maintain the current pan and zoom settings of the charts. So, align the charts before proceeding. + </p> + <p> + <small> + This process will put some CPU and memory pressure on your browser.<br/> + For the netdata server, we will sequencially download all the charts, to avoid congesting network and server resources.<br/> + <b>Please, do not print netdata dashboards on paper!</b> + </small> + </p> + </div> + <div class="modal-footer"> + <a href="#" onclick="printPreflight(); return false;" type="button" class="btn btn-default">Print</a> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + </div> + </div> + </div> + </div> + + <div class="modal fade" id="printModal" tabindex="-1" role="dialog" aria-labelledby="printModalLabel" data-keyboard="false" data-backdrop="static"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="printModalLabel">Preparing dashboard for printing...</h4> + </div> + <div class="modal-body"> + Please wait while we initialize and render all the charts on the dashboard. + <div class="progress progress-striped active" style="height: 2em !important;"> + <div id="printModalProgressBar" class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em;"> + <span id="printModalProgressBarText" style="padding-left: 10px; padding-top: 4px; font-size: 1.2em; text-align: left; width: 100%; position: absolute; display: block; color: black;"></span> + </div> + </div> + The print dialog will appear as soon as we finish rendering the page. + </div> + <div class="modal-footer"> + </div> + </div> + </div> + </div> + + <div class="modal fade" id="loadSnapshotModal" tabindex="-1" role="dialog" aria-labelledby="loadSnapshotModalLabel"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="loadSnapshotModalLabel">Import a netdata snapshot</h4> + </div> + <div id="loadSnapshotDragAndDrop" class="modal-body"> + <p> + netdata can export and import dashboard snapshots. + Any netdata can import the snapshot of any other netdata. + The snapshots are not uploaded to a server. They are handled entirely by your web browser, on your computer. + </p> + <p style="text-align: center;"> + <label class="btn btn-default"> + Click here to select the netdata snapshot file to import + <input type="file" id="loadSnapshotSelectFiles" value="Import" style="display: none;" + onchange="loadSnapshotPreflight();"> + </label> + </p> + <div id="loadSnapshotStatus" class="alert alert-info" role="alert"> + Browse for a snapshot file (or drag it and drop it here), then click <b>Import</b> to render it. + </div> + <p> + <table class="table"> + <tbody> + <tr><th>Filename</th><td id="loadSnapshotFilename"></td></tr> + <tr><th>Hostname</th><td id="loadSnapshotHostname"></td></tr> + <tr><th>Origin URL</th><td id="loadSnapshotURL"></td></tr> + <tr><th>Charts Info</th><td id="loadSnapshotCharts"></td></tr> + <tr><th>Snapshot Info</th><td id="loadSnapshotInfo"></td></tr> + <tr><th>Time Range</th><td id="loadSnapshotTimeRange"></td></tr> + <tr><th>Comments</th><td id="loadSnapshotComments"></td></tr> + </tbody> + </table> + </p> + </div> + <div class="modal-footer"> + <a id="loadSnapshotImport" href="#" onclick="loadSnapshot(); return false;" type="button" class="btn btn-success disabled">Import</a> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + </div> + </div> + </div> + </div> + + <div class="modal fade" id="saveSnapshotModal" tabindex="-1" role="dialog" aria-labelledby="saveSnapshotModalLabel" data-keyboard="false" data-backdrop="static"> + <div class="modal-dialog modal-lg" role="document"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> + <h4 class="modal-title" id="saveSnapshotModalLabel">Export a snapshot</h4> + </div> + <div class="modal-body"> + <div id="saveSnapshotModalProgressSection" hidden> + Please wait while we collect all the dashboard data... + <div class="progress progress-striped active" style="height: 2em !important;"> + <div id="saveSnapshotModalProgressBar" class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em;"> + <span id="saveSnapshotModalProgressBarText" style="padding-left: 10px; padding-top: 4px; font-size: 1.2em; text-align: left; width: 100%; position: absolute; display: block;"></span> + </div> + </div> + </div> + + <div id="saveSnapshotResolutionRadio" style="text-align: center;"> + Select the desired resolution of the snapshot. This is the <b>seconds of data per point</b>. + <br/> + + <br/> + + <br/> + <input id="saveSnapshotResolutionSlider" data-slider-id='saveSnapshotResolutionSlider' type="text" style="width: 80%;" tabindex="0"/> + <br/> <br/> + <div class="input-group"> + <span class="input-group-addon" id="sizing-saveSnapshotFilename" style="width: 100px;">Filename</span> + <input id="saveSnapshotFilename" class="form-control" placeholder="Filename of the generated snapshot" aria-describedby="sizing-saveSnapshotFilename" tabindex="2"/> + <div class="input-group-btn"> + <div class="input-group-btn"> + <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span id="saveSnapshotCompressionName">Compression</span> <span class="caret"></span></button> + <ul class="dropdown-menu dropdown-menu-right"> + <li class="disabled"><a href="#" class="disabled">Select Compression</a></li> + <li role="separator" class="divider"></li> + <li><a href="#" onclick="saveSnapshotSetCompression('none'); return false;">uncompressed</a></li> + <li role="separator" class="divider"></li> + <li><a href="#" onclick="saveSnapshotSetCompression('pako.deflate'); return false;">pako.deflate (gzip, binary)</a></li> + <li><a href="#" onclick="saveSnapshotSetCompression('pako.deflate.base64'); return false;">pako.deflate.base64 (gzip, ascii)</a></li> + <li role="separator" class="divider"></li> + <li><a href="#" onclick="saveSnapshotSetCompression('lzstring.uri'); return false;">lzstring.uri (LZ, ascii)</a></li> + <li><a href="#" onclick="saveSnapshotSetCompression('lzstring.utf16'); return false;">lzstring.utf16 (LZ, utf16)</a></li> + <li><a href="#" onclick="saveSnapshotSetCompression('lzstring.base64'); return false;">lzstring.base64 (LZ, ascii)</a></li> + </ul> + </div><!-- /btn-group --> + </div> + </div> + <div class="input-group" style="padding-top: 10px; width: 100%"> + <span class="input-group-addon" id="sizing-saveSnapshotComments" style="width: 100px;">Comments</span> + <input id="saveSnapshotComments" class="form-control" placeholder="Any comments about this snapshot?" aria-describedby="sizing-saveSnapshotComments" tabindex="3"/> + </div> + </div> + + + <div id="saveSnapshotStatus" class="alert alert-info" role="alert"> + Select snaphost resolution. This controls the size the snapshot file. + </div> + <p> + The generated snapshot will include all charts of this dashboard, <b>for the visible timeframe</b>, so align, pan and zoom the charts as needed. + The scroll position of the dashboard will also be saved. + The snapshot will be downloaded as a file, to your computer, that can be imported back into any netdata dashboard (no need to import it back on this server). + </p> + <p> + <small> + Snapshot files include all the information of the dashboard, including the URL of the origin server, its netdata unique ID, etc. + So, if you share the snapshot file with third parties, they will be able to access the origin server, if this server is exposed on the internet. + <br/> + Snapshots are handled entirely by the web browser. The netdata servers are not aware of them. + </small> + </p> + </div> + <div class="modal-footer"> + <a id="saveSnapshotExport" href="#" onclick="saveSnapshot(); return false;" type="button" class="btn btn-success" tabindex="4">Export</a> + <button type="button" class="btn btn-default" data-dismiss="modal" tabindex="5">Cancel</button> + </div> + </div> + </div> + </div> + <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> @@ -3216,7 +4758,7 @@ <hr/> <div class="p"> <h4>Drag Chart Contents</h4> - Drag the contents of a chart to pan it horizontally. + Drag the contents of a chart, by pressing the left mouse button and moving the mouse, to pan it horizontally. <br/> 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). <br/> @@ -3230,7 +4772,7 @@ <hr/> <div class="p"> <h4>SHIFT + Drag</h4> - 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: + While pressing the <code>SHIFT</code> key, press the left mouse button 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: <ul> <li>The already loaded chart contents are zoomed (low resolution)</li> <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li> @@ -3239,8 +4781,13 @@ </div> <hr/> <div class="p"> + <h4>Highlight Timeframe</h4> + While pressing the <code>ALT</code> key, press the left mouse button on the contents of a chart and move the mouse to select an area. The selected are will be highlighted on all charts. + </div> + <hr/> + <div class="p"> <h4>SHIFT + Mouse Wheel</h4> - 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. + While pressing the <code>SHIFT</code> 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. <br/> Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart. </div> @@ -3353,6 +4900,7 @@ <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li> <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li> <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li> + <li role="presentation"><a href="#settings_locale" aria-controls="settings_locale" role="tab" data-toggle="tab">Locale</a></li> </ul> <!-- Tab panes --> @@ -3384,7 +4932,7 @@ <tr class="option-row"> <td class="option-control"><input id="async_on_scroll" type="checkbox" data-toggle="toggle" data-on="Async" data-off="Sync" data-width="110px"></td> <td class="option-info"><strong>Page scroll handling?</strong><br/> - <small>When set to <b>Sync</b>, charts will be examined for their visibility synchronously. On slow computers this may impact the smoothness of page scrolling. To work asynchronously set it to <b>Async</b>. When set to <b>Sync</b>, the performance of page scrolling is monitored and this setting switches automatically to <b>Async</b> if the browser is found slow. Set it to <b>Sync</b> for best visual experience. Set it to <b>Async</b> for smoother page scrolling.</small> + <small>When set to <b>Sync</b>, charts will be examined for their visibility immediately after scrolling. On slow computers this may impact the smoothness of page scrolling. To update the page when scrolling ends, set it to <b>Async</b>. Set it to <b>Sync</b> for immediate chart updates when scrolling. Set it to <b>Async</b> for smoother page scrolling on slower computers.</small> </td> </tr> </table> @@ -3463,6 +5011,416 @@ </div> </form> </div> + <div role="tabpanel" class="tab-pane" id="settings_locale"> + <form id="optionsForm4" method="get" class="form-horizontal"> + <div class="form-group"> + <table> + <tr class="option-row"> + <td colspan="2" align="center"> + <small> + <b>These settings are applied gradually, as charts are updated. To force them, refresh the dashboard now</b>. + </small> + </td> + </tr> + <tr class="option-row"> + <td class="option-control"><input id="units_conversion" type="checkbox" checked data-toggle="toggle" data-on="Scale Units" data-off="Fixed Units" data-onstyle="success" data-width="110px"></td> + <td class="option-info"><strong>Enable auto-scaling of select units?</strong><br/> + <small>When set to <b>Scale Units</b> the values shown will dynamically be scaled (e.g. 1000 kilobits will be shown as 1 megabit). + Netdata can auto-scale these original units: <code>kilobits/s</code>, <code>kilobytes/s</code>, <code>KB/s</code>, + <code>KB</code>, <code>MB</code>, and <code>GB</code>. + When set to <b>Fixed Units</b> all the values will be rendered using the original units maintained by the netdata server. + </small> + </td> + </tr> + <tr id="settingsLocaleTempRow" class="option-row"> + <td class="option-control"><input id="units_temp" type="checkbox" checked data-toggle="toggle" data-on="Celsius" data-off="Fahrenheit" data-width="110px"></td> + <td class="option-info"><strong>Which units to use for temperatures?</strong><br/> + <small>Set the temperature units of the dashboard. + </small> + </td> + </tr> + <tr id="settingsLocaleTimeRow" class="option-row"> + <td class="option-control"><input id="seconds_as_time" type="checkbox" checked data-toggle="toggle" data-on="Time" data-off="Seconds" data-onstyle="success" data-width="110px"></td> + <td class="option-info"><strong>Convert seconds to time?</strong><br/> + <small>When set to <b>Time</b>, charts that present <code>seconds</code> will show <code>DDd:HH:MM:SS</code>. + When set to <b>Seconds</b>, the raw number of seconds will be presented. + </small> + </td> + </tr> + <tr class="option-row"> + <td class="option-control"><input id="local_timezone" type="checkbox" checked data-toggle="toggle" data-on="Your Time" data-off="Server Time" data-onstyle="success" data-offstyle="danger" data-width="110px"></td> + <td class="option-info"><strong>Show browser local time or server time?</strong><br/> + <small>When set to <b>Your Time</b>, the charts will use your browser local time. When set to <b>Server Time</b> the charts will use the server time. + <br/> + Set it to <b>Your Time</b> to have a common time-reference, no matter where the server is and which time zone it uses (all your dashboards will report your local time). + Set it to <b>Server Time</b> when you need to compare netdata charts with server log files. + <br/> + Your browser time zone is: <b><span id="browser_timezone">-</span></b>.<br/> + The server reported timezone is: <b><span id="server_timezone">-</span></b> (you can set this in netdata.conf <code>[global].timezone</code>).<br/> + The current time zone on the dashboard is: <b><span id="current_timezone">-</span></b>. + <br/> + <div class="dropup"> + <button class="btn btn-default dropdown-toggle" type="button" id="dropdownTimeZone" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> + Select Server Time Zone + <span class="caret"></span> + </button> + <ul class="dropdown-menu scrollable-menu-50" aria-labelledby="dropdownTimeZone"> + <li><a href=# onclick="return selected_server_timezone('Africa/Abidjan');">Africa/Abidjan</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Accra');">Africa/Accra</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Algiers');">Africa/Algiers</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Bissau');">Africa/Bissau</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Cairo');">Africa/Cairo</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Casablanca');">Africa/Casablanca</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Ceuta');">Africa/Ceuta</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/El_Aaiun');">Africa/El_Aaiun</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Johannesburg');">Africa/Johannesburg</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Khartoum');">Africa/Khartoum</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Lagos');">Africa/Lagos</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Maputo');">Africa/Maputo</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Monrovia');">Africa/Monrovia</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Nairobi');">Africa/Nairobi</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Ndjamena');">Africa/Ndjamena</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Tripoli');">Africa/Tripoli</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Tunis');">Africa/Tunis</a></li> + <li><a href=# onclick="return selected_server_timezone('Africa/Windhoek');">Africa/Windhoek</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Adak');">America/Adak</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Anchorage');">America/Anchorage</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Araguaina');">America/Araguaina</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Buenos_Aires');">America/Argentina/Buenos_Aires</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Catamarca');">America/Argentina/Catamarca</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Cordoba');">America/Argentina/Cordoba</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Jujuy');">America/Argentina/Jujuy</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/La_Rioja');">America/Argentina/La_Rioja</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Mendoza');">America/Argentina/Mendoza</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Rio_Gallegos');">America/Argentina/Rio_Gallegos</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Salta');">America/Argentina/Salta</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/San_Juan');">America/Argentina/San_Juan</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/San_Luis');">America/Argentina/San_Luis</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Tucuman');">America/Argentina/Tucuman</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Argentina/Ushuaia');">America/Argentina/Ushuaia</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Asuncion');">America/Asuncion</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Atikokan');">America/Atikokan</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Bahia');">America/Bahia</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Bahia_Banderas');">America/Bahia_Banderas</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Barbados');">America/Barbados</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Belem');">America/Belem</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Belize');">America/Belize</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Blanc-Sablon');">America/Blanc-Sablon</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Boa_Vista');">America/Boa_Vista</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Bogota');">America/Bogota</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Boise');">America/Boise</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Cambridge_Bay');">America/Cambridge_Bay</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Campo_Grande');">America/Campo_Grande</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Cancun');">America/Cancun</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Caracas');">America/Caracas</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Cayenne');">America/Cayenne</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Chicago');">America/Chicago</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Chihuahua');">America/Chihuahua</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Costa_Rica');">America/Costa_Rica</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Creston');">America/Creston</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Cuiaba');">America/Cuiaba</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Curacao');">America/Curacao</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Danmarkshavn');">America/Danmarkshavn</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Dawson');">America/Dawson</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Dawson_Creek');">America/Dawson_Creek</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Denver');">America/Denver</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Detroit');">America/Detroit</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Edmonton');">America/Edmonton</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Eirunepe');">America/Eirunepe</a></li> + <li><a href=# onclick="return selected_server_timezone('America/El_Salvador');">America/El_Salvador</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Fortaleza');">America/Fortaleza</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Fort_Nelson');">America/Fort_Nelson</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Glace_Bay');">America/Glace_Bay</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Godthab');">America/Godthab</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Goose_Bay');">America/Goose_Bay</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Grand_Turk');">America/Grand_Turk</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Guatemala');">America/Guatemala</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Guayaquil');">America/Guayaquil</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Guyana');">America/Guyana</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Halifax');">America/Halifax</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Havana');">America/Havana</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Hermosillo');">America/Hermosillo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Indianapolis');">America/Indiana/Indianapolis</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Knox');">America/Indiana/Knox</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Marengo');">America/Indiana/Marengo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Petersburg');">America/Indiana/Petersburg</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Tell_City');">America/Indiana/Tell_City</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Vevay');">America/Indiana/Vevay</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Vincennes');">America/Indiana/Vincennes</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Indiana/Winamac');">America/Indiana/Winamac</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Inuvik');">America/Inuvik</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Iqaluit');">America/Iqaluit</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Jamaica');">America/Jamaica</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Juneau');">America/Juneau</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Kentucky/Louisville');">America/Kentucky/Louisville</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Kentucky/Monticello');">America/Kentucky/Monticello</a></li> + <li><a href=# onclick="return selected_server_timezone('America/La_Paz');">America/La_Paz</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Lima');">America/Lima</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Los_Angeles');">America/Los_Angeles</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Maceio');">America/Maceio</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Managua');">America/Managua</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Manaus');">America/Manaus</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Martinique');">America/Martinique</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Matamoros');">America/Matamoros</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Mazatlan');">America/Mazatlan</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Menominee');">America/Menominee</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Merida');">America/Merida</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Metlakatla');">America/Metlakatla</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Mexico_City');">America/Mexico_City</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Miquelon');">America/Miquelon</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Moncton');">America/Moncton</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Monterrey');">America/Monterrey</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Montevideo');">America/Montevideo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Nassau');">America/Nassau</a></li> + <li><a href=# onclick="return selected_server_timezone('America/New_York');">America/New_York</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Nipigon');">America/Nipigon</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Nome');">America/Nome</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Noronha');">America/Noronha</a></li> + <li><a href=# onclick="return selected_server_timezone('America/North_Dakota/Beulah');">America/North_Dakota/Beulah</a></li> + <li><a href=# onclick="return selected_server_timezone('America/North_Dakota/Center');">America/North_Dakota/Center</a></li> + <li><a href=# onclick="return selected_server_timezone('America/North_Dakota/New_Salem');">America/North_Dakota/New_Salem</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Ojinaga');">America/Ojinaga</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Panama');">America/Panama</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Pangnirtung');">America/Pangnirtung</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Paramaribo');">America/Paramaribo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Phoenix');">America/Phoenix</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Port-au-Prince');">America/Port-au-Prince</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Port_of_Spain');">America/Port_of_Spain</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Porto_Velho');">America/Porto_Velho</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Puerto_Rico');">America/Puerto_Rico</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Punta_Arenas');">America/Punta_Arenas</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Rainy_River');">America/Rainy_River</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Rankin_Inlet');">America/Rankin_Inlet</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Recife');">America/Recife</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Regina');">America/Regina</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Resolute');">America/Resolute</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Rio_Branco');">America/Rio_Branco</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Santarem');">America/Santarem</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Santiago');">America/Santiago</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Santo_Domingo');">America/Santo_Domingo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Sao_Paulo');">America/Sao_Paulo</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Scoresbysund');">America/Scoresbysund</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Sitka');">America/Sitka</a></li> + <li><a href=# onclick="return selected_server_timezone('America/St_Johns');">America/St_Johns</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Swift_Current');">America/Swift_Current</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Tegucigalpa');">America/Tegucigalpa</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Thule');">America/Thule</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Thunder_Bay');">America/Thunder_Bay</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Tijuana');">America/Tijuana</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Toronto');">America/Toronto</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Vancouver');">America/Vancouver</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Whitehorse');">America/Whitehorse</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Winnipeg');">America/Winnipeg</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Yakutat');">America/Yakutat</a></li> + <li><a href=# onclick="return selected_server_timezone('America/Yellowknife');">America/Yellowknife</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Casey');">Antarctica/Casey</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Davis');">Antarctica/Davis</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/DumontDUrville');">Antarctica/DumontDUrville</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Macquarie');">Antarctica/Macquarie</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Mawson');">Antarctica/Mawson</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Palmer');">Antarctica/Palmer</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Rothera');">Antarctica/Rothera</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Syowa');">Antarctica/Syowa</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Troll');">Antarctica/Troll</a></li> + <li><a href=# onclick="return selected_server_timezone('Antarctica/Vostok');">Antarctica/Vostok</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Almaty');">Asia/Almaty</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Amman');">Asia/Amman</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Anadyr');">Asia/Anadyr</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Aqtau');">Asia/Aqtau</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Aqtobe');">Asia/Aqtobe</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Ashgabat');">Asia/Ashgabat</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Atyrau');">Asia/Atyrau</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Baghdad');">Asia/Baghdad</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Baku');">Asia/Baku</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Bangkok');">Asia/Bangkok</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Barnaul');">Asia/Barnaul</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Beirut');">Asia/Beirut</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Bishkek');">Asia/Bishkek</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Brunei');">Asia/Brunei</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Chita');">Asia/Chita</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Choibalsan');">Asia/Choibalsan</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Colombo');">Asia/Colombo</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Damascus');">Asia/Damascus</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Dhaka');">Asia/Dhaka</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Dili');">Asia/Dili</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Dubai');">Asia/Dubai</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Dushanbe');">Asia/Dushanbe</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Famagusta');">Asia/Famagusta</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Gaza');">Asia/Gaza</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Hebron');">Asia/Hebron</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Ho_Chi_Minh');">Asia/Ho_Chi_Minh</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Hong_Kong');">Asia/Hong_Kong</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Hovd');">Asia/Hovd</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Irkutsk');">Asia/Irkutsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Jakarta');">Asia/Jakarta</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Jayapura');">Asia/Jayapura</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Jerusalem');">Asia/Jerusalem</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kabul');">Asia/Kabul</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kamchatka');">Asia/Kamchatka</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Karachi');">Asia/Karachi</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kathmandu');">Asia/Kathmandu</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Khandyga');">Asia/Khandyga</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kolkata');">Asia/Kolkata</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Krasnoyarsk');">Asia/Krasnoyarsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kuala_Lumpur');">Asia/Kuala_Lumpur</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Kuching');">Asia/Kuching</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Macau');">Asia/Macau</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Magadan');">Asia/Magadan</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Makassar');">Asia/Makassar</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Manila');">Asia/Manila</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Nicosia');">Asia/Nicosia</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Novokuznetsk');">Asia/Novokuznetsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Novosibirsk');">Asia/Novosibirsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Omsk');">Asia/Omsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Oral');">Asia/Oral</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Pontianak');">Asia/Pontianak</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Pyongyang');">Asia/Pyongyang</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Qatar');">Asia/Qatar</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Qyzylorda');">Asia/Qyzylorda</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Riyadh');">Asia/Riyadh</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Sakhalin');">Asia/Sakhalin</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Samarkand');">Asia/Samarkand</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Seoul');">Asia/Seoul</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Shanghai');">Asia/Shanghai</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Singapore');">Asia/Singapore</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Srednekolymsk');">Asia/Srednekolymsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Taipei');">Asia/Taipei</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Tashkent');">Asia/Tashkent</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Tbilisi');">Asia/Tbilisi</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Tehran');">Asia/Tehran</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Thimphu');">Asia/Thimphu</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Tokyo');">Asia/Tokyo</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Tomsk');">Asia/Tomsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Ulaanbaatar');">Asia/Ulaanbaatar</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Urumqi');">Asia/Urumqi</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Ust-Nera');">Asia/Ust-Nera</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Vladivostok');">Asia/Vladivostok</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Yakutsk');">Asia/Yakutsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Yangon');">Asia/Yangon</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Yekaterinburg');">Asia/Yekaterinburg</a></li> + <li><a href=# onclick="return selected_server_timezone('Asia/Yerevan');">Asia/Yerevan</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Azores');">Atlantic/Azores</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Bermuda');">Atlantic/Bermuda</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Canary');">Atlantic/Canary</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Cape_Verde');">Atlantic/Cape_Verde</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Faroe');">Atlantic/Faroe</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Madeira');">Atlantic/Madeira</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Reykjavik');">Atlantic/Reykjavik</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/South_Georgia');">Atlantic/South_Georgia</a></li> + <li><a href=# onclick="return selected_server_timezone('Atlantic/Stanley');">Atlantic/Stanley</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Adelaide');">Australia/Adelaide</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Brisbane');">Australia/Brisbane</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Broken_Hill');">Australia/Broken_Hill</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Currie');">Australia/Currie</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Darwin');">Australia/Darwin</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Eucla');">Australia/Eucla</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Hobart');">Australia/Hobart</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Lindeman');">Australia/Lindeman</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Lord_Howe');">Australia/Lord_Howe</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Melbourne');">Australia/Melbourne</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Perth');">Australia/Perth</a></li> + <li><a href=# onclick="return selected_server_timezone('Australia/Sydney');">Australia/Sydney</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Amsterdam');">Europe/Amsterdam</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Andorra');">Europe/Andorra</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Astrakhan');">Europe/Astrakhan</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Athens');">Europe/Athens</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Belgrade');">Europe/Belgrade</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Berlin');">Europe/Berlin</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Brussels');">Europe/Brussels</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Bucharest');">Europe/Bucharest</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Budapest');">Europe/Budapest</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Chisinau');">Europe/Chisinau</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Copenhagen');">Europe/Copenhagen</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Dublin');">Europe/Dublin</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Gibraltar');">Europe/Gibraltar</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Helsinki');">Europe/Helsinki</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Istanbul');">Europe/Istanbul</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Kaliningrad');">Europe/Kaliningrad</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Kiev');">Europe/Kiev</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Kirov');">Europe/Kirov</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Lisbon');">Europe/Lisbon</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/London');">Europe/London</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Luxembourg');">Europe/Luxembourg</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Madrid');">Europe/Madrid</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Malta');">Europe/Malta</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Minsk');">Europe/Minsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Monaco');">Europe/Monaco</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Moscow');">Europe/Moscow</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Oslo');">Europe/Oslo</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Paris');">Europe/Paris</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Prague');">Europe/Prague</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Riga');">Europe/Riga</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Rome');">Europe/Rome</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Samara');">Europe/Samara</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Saratov');">Europe/Saratov</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Simferopol');">Europe/Simferopol</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Sofia');">Europe/Sofia</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Stockholm');">Europe/Stockholm</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Tallinn');">Europe/Tallinn</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Tirane');">Europe/Tirane</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Ulyanovsk');">Europe/Ulyanovsk</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Uzhgorod');">Europe/Uzhgorod</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Vienna');">Europe/Vienna</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Vilnius');">Europe/Vilnius</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Volgograd');">Europe/Volgograd</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Warsaw');">Europe/Warsaw</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Zaporozhye');">Europe/Zaporozhye</a></li> + <li><a href=# onclick="return selected_server_timezone('Europe/Zurich');">Europe/Zurich</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Chagos');">Indian/Chagos</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Christmas');">Indian/Christmas</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Cocos');">Indian/Cocos</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Kerguelen');">Indian/Kerguelen</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Mahe');">Indian/Mahe</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Maldives');">Indian/Maldives</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Mauritius');">Indian/Mauritius</a></li> + <li><a href=# onclick="return selected_server_timezone('Indian/Reunion');">Indian/Reunion</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Apia');">Pacific/Apia</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Auckland');">Pacific/Auckland</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Bougainville');">Pacific/Bougainville</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Chatham');">Pacific/Chatham</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Chuuk');">Pacific/Chuuk</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Easter');">Pacific/Easter</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Efate');">Pacific/Efate</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Enderbury');">Pacific/Enderbury</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Fakaofo');">Pacific/Fakaofo</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Fiji');">Pacific/Fiji</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Funafuti');">Pacific/Funafuti</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Galapagos');">Pacific/Galapagos</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Gambier');">Pacific/Gambier</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Guadalcanal');">Pacific/Guadalcanal</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Guam');">Pacific/Guam</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Honolulu');">Pacific/Honolulu</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Kiritimati');">Pacific/Kiritimati</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Kosrae');">Pacific/Kosrae</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Kwajalein');">Pacific/Kwajalein</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Majuro');">Pacific/Majuro</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Marquesas');">Pacific/Marquesas</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Nauru');">Pacific/Nauru</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Niue');">Pacific/Niue</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Norfolk');">Pacific/Norfolk</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Noumea');">Pacific/Noumea</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Pago_Pago');">Pacific/Pago_Pago</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Palau');">Pacific/Palau</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Pitcairn');">Pacific/Pitcairn</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Pohnpei');">Pacific/Pohnpei</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Port_Moresby');">Pacific/Port_Moresby</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Rarotonga');">Pacific/Rarotonga</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Tahiti');">Pacific/Tahiti</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Tarawa');">Pacific/Tarawa</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Tongatapu');">Pacific/Tongatapu</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Wake');">Pacific/Wake</a></li> + <li><a href=# onclick="return selected_server_timezone('Pacific/Wallis');">Pacific/Wallis</a></li> + </ul> + </div> + <b><span id="timezone_error_message"></span></b> + + </small> + </td> + </tr> + </table> + </div> + </form> + </div> </div> </div> <div class="modal-footer"> @@ -3490,12 +5448,10 @@ <hr/> </div> <div> - For progress reports and key netdata updates: <strong><a href="https://twitter.com/linuxnetdata" target="_blank">follow netdata on <i class="fa fa-twitter" aria-hidden="true"></i> twitter</a></strong>. + For progress reports and key netdata updates: <strong><a href="https://twitter.com/linuxnetdata" target="_blank">follow netdata on <i class="fab fa-twitter"></i> twitter</a></strong>. <br/> - <small> - You can also <a href="https://www.facebook.com/linuxnetdata/" target="_blank">follow netdata on <i class="fa fa-facebook" aria-hidden="true"></i> facebook</a>, - or <a href="https://github.com/firehol/netdata" target="_blank">watch netdata on <i class="fa fa-github" aria-hidden="true"></i> github</a>. - </small> + You can also <a href="https://www.facebook.com/linuxnetdata/" target="_blank">follow netdata on <i class="fab fa-facebook"></i> facebook</a>, + or <a href="https://github.com/firehol/netdata" target="_blank">watch netdata on <i class="fab fa-github"></i> github</a>. </div> </div> <div class="modal-footer"> @@ -3546,13 +5502,13 @@ You can copy and paste the following ID to all your browsers (e.g. work and home). <br/> All the browsers with the same ID will identify <b>you</b>, so please don't share this with others. - <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;"> + <div style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;"> <form action="#"> <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;"> </form> - </p> + </div> Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser. - <p style="padding-top: 10px;"><small> + <div style="padding-top: 10px;"><small> Keep in mind that: <ul> <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li> @@ -3560,7 +5516,7 @@ <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li> <li>to get a new ID, just clear your browser cookies.</li> </ul> - </small></p> + </small></div> <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div> </div> <div class="modal-footer"> @@ -3595,6 +5551,7 @@ </div> </div> </div> + <div id="hiddenDownloadLinks" style="display: none;" hidden></div> + <script type="text/javascript" src="dashboard.js?v20171208-5"></script> </body> </html> -<script type="text/javascript" src="dashboard.js?v20170815-14"></script> |