X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=web%2Fdashboard.js;h=b34accdecb0948a45a1769631e1f2d5a02681b8a;hb=b060bae83cc36fdc4f14120228e4c9b0d1ec42e8;hp=5bf42ff8b8fbfd2eded57b33675380f5b6481bcd;hpb=6e72b3fe8660168b3edab8e2fad8771c1918c3b0;p=netdata.git diff --git a/web/dashboard.js b/web/dashboard.js index 5bf42ff8..b34accde 100644 --- a/web/dashboard.js +++ b/web/dashboard.js @@ -1,35 +1,54 @@ +// ---------------------------------------------------------------------------- // You can set the following variables before loading this script: -// -// var netdataNoDygraphs = true; // do not use dygraph -// var netdataNoSparklines = true; // do not use sparkline -// var netdataNoPeitys = true; // do not use peity -// var netdataNoGoogleCharts = true; // do not use google -// var netdataNoMorris = true; // do not use morris -// var netdataNoEasyPieChart = true; // do not use easy pie chart -// var netdataNoGauge = true; // do not use gauge.js -// var netdataNoD3 = true; // do not use D3 -// var netdataNoC3 = true; // do not use C3 -// var netdataNoBootstrap = true; // do not load bootstrap -// var netdataDontStart = true; // do not start the thread to process the charts -// var netdataErrorCallback = null; // Callback function that will be invoked upon error -// var netdataRegistry = true; // Update the registry (default disabled) -// var netdataRegistryCallback = null; // Callback function that will be invoked with one param, -// the URLs from the registry -// var netdataShowHelp = false; // enable/disable help (default enabled) -// var netdataShowAlarms = true; // enable/disable alarms checks and notifications (default disabled) -// -// var netdataRegistryAfterMs = 1500 // the time to consult to registry on startup -// -// var netdataCallback = null; // a function to call when netdata is ready -// // netdata will be running while this is called (call NETDATA.pause to stop it) -// var netdataPrepCallback = null; // a callback to be called before netdata does anything else -// -// You can also set the default netdata server, using the following. -// When this variable is not set, we assume the page is hosted on your -// netdata server already. -// var netdataServer = "http://yourhost:19999"; // set your NetData server +/*global netdataNoDygraphs *//* boolean, disable dygraph charts + * (default: false) */ +/*global netdataNoSparklines *//* boolean, disable sparkline charts + * (default: false) */ +/*global netdataNoPeitys *//* boolean, disable peity charts + * (default: false) */ +/*global netdataNoGoogleCharts *//* boolean, disable google charts + * (default: false) */ +/*global netdataNoMorris *//* boolean, disable morris charts + * (default: false) */ +/*global netdataNoEasyPieChart *//* boolean, disable easypiechart charts + * (default: false) */ +/*global netdataNoGauge *//* boolean, disable gauge.js charts + * (default: false) */ +/*global netdataNoD3 *//* boolean, disable d3 charts + * (default: false) */ +/*global netdataNoC3 *//* boolean, disable c3 charts + * (default: false) */ +/*global netdataNoBootstrap *//* boolean, disable bootstrap - disables help too + * (default: false) */ +/*global netdataDontStart *//* boolean, do not start the thread to process the charts + * (default: false) */ +/*global netdataErrorCallback *//* function, callback to be called when the dashboard encounters an error + * (default: null) */ +/*global netdataRegistry:true *//* boolean, use the netdata registry + * (default: false) */ +/*global netdataNoRegistry *//* boolean, included only for compatibility with existing custom dashboard + * (obsolete - do not use this any more) */ +/*global netdataRegistryCallback *//* function, callback that will be invoked with one param: the URLs from the registry + * (default: null) */ +/*global netdataShowHelp:true *//* boolean, disable charts help + * (default: true) */ +/*global netdataShowAlarms:true *//* boolean, enable alarms checks and notifications + * (default: false) */ +/*global netdataRegistryAfterMs:true *//* ms, delay registry use at started + * (default: 1500) */ +/*global netdataCallback *//* function, callback to be called when netdata is ready to start + * (default: null) + * netdata will be running while this is called + * (call NETDATA.pause to stop it) */ +/*global netdataPrepCallback *//* function, callback to be called before netdata does anything else + * (default: null) */ +/*global netdataServer *//* string, the URL of the netdata server to use + * (default: the URL the page is hosted at) */ + +// ---------------------------------------------------------------------------- // global namespace + var NETDATA = window.NETDATA || {}; (function(window, document) { @@ -111,7 +130,7 @@ var NETDATA = window.NETDATA || {}; NETDATA.peity_js = NETDATA.serverDefault + 'lib/jquery.peity-3.2.0.min.js'; NETDATA.sparkline_js = NETDATA.serverDefault + 'lib/jquery.sparkline-2.1.2.min.js'; NETDATA.easypiechart_js = NETDATA.serverDefault + 'lib/jquery.easypiechart-97b5824.min.js'; - NETDATA.gauge_js = NETDATA.serverDefault + 'lib/gauge-d5260c3.min.js'; + NETDATA.gauge_js = NETDATA.serverDefault + 'lib/gauge-1.3.2.min.js'; NETDATA.dygraph_js = NETDATA.serverDefault + 'lib/dygraph-combined-dd74404.js'; NETDATA.dygraph_smooth_js = NETDATA.serverDefault + 'lib/dygraph-smooth-plotter-dd74404.js'; NETDATA.raphael_js = NETDATA.serverDefault + 'lib/raphael-2.2.4-min.js'; @@ -199,6 +218,29 @@ var NETDATA = window.NETDATA || {}; if(netdataRegistry === false && typeof netdataRegistryCallback === 'function') netdataRegistry = true; + + // ---------------------------------------------------------------------------------------------------------------- + // detect if this is probably a slow device + + var isSlowDeviceResult = undefined; + var isSlowDevice = function() { + if(isSlowDeviceResult !== undefined) + return isSlowDeviceResult; + + try { + var ua = navigator.userAgent.toLowerCase(); + + var iOS = /ipad|iphone|ipod/.test(ua) && !window.MSStream; + var android = /android/.test(ua) && !window.MSStream; + isSlowDeviceResult = (iOS === true || android === true); + } + catch (e) { + isSlowDeviceResult = false; + } + + return isSlowDeviceResult; + }; + // ---------------------------------------------------------------------------------------------------------------- // the defaults for all charts @@ -214,7 +256,7 @@ var NETDATA = window.NETDATA || {}; before: 0, // panning after: -600, // panning pixels_per_point: 1, // the detail of the chart - fill_luminance: 0.8 // luminance of colors in solit areas + fill_luminance: 0.8 // luminance of colors in solid areas }; // ---------------------------------------------------------------------------------------------------------------- @@ -233,12 +275,12 @@ var NETDATA = window.NETDATA || {}; // new elements we have to check. auto_refresher_fast_weight: 0, // this is the current time in ms, spent - // rendering charts continiously. + // rendering charts continuously. // used with .current.fast_render_timeframe page_is_visible: true, // when true, this page is visible - auto_refresher_stop_until: 0, // timestamp in ms - used internaly, to stop the + auto_refresher_stop_until: 0, // timestamp in ms - used internally, to stop the // auto-refresher for some time (when a chart is // performing pan or zoom, we need to stop refreshing // all other charts, to have the maximum speed for @@ -252,7 +294,7 @@ var NETDATA = window.NETDATA || {}; // the current profile // we may have many... current: { - pixels_per_point: 1, // the minimum pixels per point for all charts + pixels_per_point: isSlowDevice()?5:1, // the minimum pixels per point for all charts // increase this to speed javascript up // each chart library has its own limit too // the max of this and the chart library is used @@ -262,7 +304,7 @@ var NETDATA = window.NETDATA || {}; idle_between_charts: 100, // ms - how much time to wait between chart updates - fast_render_timeframe: 200, // ms - render continously until this time of continious + fast_render_timeframe: 200, // ms - render continuously until this time of continuous // rendering has been reached // this setting is used to make it render e.g. 10 // charts at once, sleep idle_between_charts time @@ -276,8 +318,8 @@ var NETDATA = window.NETDATA || {}; idle_lost_focus: 500, // ms - when the window does not have focus, check // if focus has been regained, every this time - global_pan_sync_time: 1000, // ms - when you pan or zoon a chart, the background - // autorefreshing of charts is paused for this amount + global_pan_sync_time: 1000, // ms - when you pan or zoom a chart, the background + // auto-refreshing of charts is paused for this amount // of time sync_selection_delay: 1500, // ms - when you pan or zoom a chart, wait this amount @@ -294,11 +336,11 @@ var NETDATA = window.NETDATA || {}; update_only_visible: true, // enable or disable visibility management - parallel_refresher: true, // enable parallel refresh of charts + parallel_refresher: (isSlowDevice() === false), // enable parallel refresh of charts concurrent_refreshes: true, // when parallel_refresher is enabled, sync also the charts - destroy_on_hide: false, // destroy charts when they are not visible + destroy_on_hide: (isSlowDevice() === true), // destroy charts when they are not visible show_help: netdataShowHelp, // when enabled the charts will show some help show_help_delay_show_ms: 500, @@ -311,7 +353,7 @@ var NETDATA = window.NETDATA || {}; double_click_speed: 500, // ms - time between clicks / taps to detect double click/tap - smooth_plot: true, // enable smooth plot, where possible + smooth_plot: (isSlowDevice() === false), // enable smooth plot, where possible charts_selection_animation_delay: 50, // delay to animate charts when syncing selection @@ -363,6 +405,28 @@ var NETDATA = window.NETDATA || {}; callback: {} // only used for resetting back to defaults }; + NETDATA.localStorageTested = -1; + NETDATA.localStorageTest = function() { + if(NETDATA.localStorageTested !== -1) + return NETDATA.localStorageTested; + + if(typeof Storage !== "undefined" && typeof localStorage === 'object') { + var test = 'test'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + NETDATA.localStorageTested = true; + } + catch (e) { + NETDATA.localStorageTested = false; + } + } + else + NETDATA.localStorageTested = false; + + return NETDATA.localStorageTested; + }; + NETDATA.localStorageGet = function(key, def, callback) { var ret = def; @@ -371,7 +435,7 @@ var NETDATA = window.NETDATA || {}; NETDATA.localStorage.callback[key.toString()] = callback; } - if(typeof Storage !== "undefined" && typeof localStorage === 'object') { + if(NETDATA.localStorageTest() === true) { try { // console.log('localStorage: loading "' + key.toString() + '"'); ret = localStorage.getItem(key.toString()); @@ -413,7 +477,7 @@ var NETDATA = window.NETDATA || {}; NETDATA.localStorage.callback[key.toString()] = callback; } - if(typeof Storage !== "undefined" && typeof localStorage === 'object') { + if(NETDATA.localStorageTest() === true) { // console.log('localStorage: saving "' + key.toString() + '" with value "' + JSON.stringify(value) + '"'); try { localStorage.setItem(key.toString(), JSON.stringify(value)); @@ -719,7 +783,7 @@ var NETDATA = window.NETDATA || {}; // find the common min var m = min; for(var i in t) - if(t[i] < m) m = t[i]; + if(t.hasOwnProperty(i) && t[i] < m) m = t[i]; //state.log('commonMin ' + state.__commonMin + ' updated: ' + m); this.latest[name] = m; @@ -774,7 +838,7 @@ var NETDATA = window.NETDATA || {}; // find the common max var m = max; for(var i in t) - if(t[i] > m) m = t[i]; + if(t.hasOwnProperty(i) && t[i] > m) m = t[i]; //state.log('commonMax ' + state.__commonMax + ' updated: ' + m); this.latest[name] = m; @@ -873,8 +937,8 @@ var NETDATA = window.NETDATA || {}; // every time a chart is panned or zoomed // we set the timestamp here // then we use it as a sequence number - // to find if other charts are syncronized - // to this timerange + // to find if other charts are synchronized + // to this time-range master: null, // the master chart (state), to which all others // are synchronized @@ -924,14 +988,12 @@ var NETDATA = window.NETDATA || {}; // is the given state the master of the global // pan and zoom sync? isMaster: function(state) { - if(this.master === state) return true; - return false; + return (this.master === state); }, // are we currently have a global pan and zoom sync? isActive: function() { - if(this.master !== null && this.force_before_ms !== null && this.force_after_ms !== null && this.seq !== 0) return true; - return false; + return (this.master !== null && this.force_before_ms !== null && this.force_after_ms !== null && this.seq !== 0); }, // check if a chart, other than the master @@ -943,10 +1005,7 @@ var NETDATA = window.NETDATA || {}; //if(state.needsRecreation()) // return true; - if(state.tm.pan_and_zoom_seq === this.seq) - return false; - - return true; + return (state.tm.pan_and_zoom_seq !== this.seq); } }; @@ -956,18 +1015,14 @@ var NETDATA = window.NETDATA || {}; // FIXME // move color assignment to dimensions, here - dimensionStatus = function(parent, label, name_div, value_div, color) { + var dimensionStatus = function(parent, label, name_div, value_div, color) { this.enabled = false; this.parent = parent; this.label = label; this.name_div = null; this.value_div = null; this.color = NETDATA.themes.current.foreground; - - if(parent.unselected_count === 0) - this.selected = true; - else - this.selected = false; + this.selected = (parent.unselected_count === 0); this.setOptions(name_div, value_div, color); }; @@ -1072,7 +1127,7 @@ var NETDATA = window.NETDATA || {}; // ---------------------------------------------------------------------------------------------------------------- - dimensionsVisibility = function(state) { + var dimensionsVisibility = function(state) { this.state = state; this.len = 0; this.dimensions = {}; @@ -1127,7 +1182,7 @@ var NETDATA = window.NETDATA || {}; }; dimensionsVisibility.prototype.selected2BooleanArray = function(array) { - var ret = new Array(); + var ret = []; this.selected_count = 0; this.unselected_count = 0; @@ -1181,7 +1236,7 @@ var NETDATA = window.NETDATA || {}; // ---------------------------------------------------------------------------------------------------------------- // Our state object, where all per-chart values are stored - chartState = function(element) { + var chartState = function(element) { var self = $(element); this.element = element; @@ -1292,7 +1347,6 @@ var NETDATA = window.NETDATA || {}; this.override_options = self.data('override-options') || null; // override options to pass to netdata this.running = false; // boolean - true when the chart is being refreshed now - this.validated = false; // boolean - has the chart been validated? this.enabled = true; // boolean - is the chart enabled for refresh? this.paused = false; // boolean - is the chart paused for any reason? this.selected = false; // boolean - is the chart shown a selection? @@ -1309,9 +1363,7 @@ var NETDATA = window.NETDATA || {}; this.value_decimal_detail = -1; var d = self.data('decimal-digits'); if(typeof d === 'number') { - this.value_decimal_detail = 1; - while(d-- > 0) - this.value_decimal_detail *= 10; + this.value_decimal_detail = d; } this.auto = { @@ -1363,8 +1415,9 @@ var NETDATA = window.NETDATA || {}; // find the element that needs to be updated var refresh_dt_element_name = self.data('dt-element-name') || null; // string - the element to print refresh_dt_ms - if(refresh_dt_element_name !== null) + if(refresh_dt_element_name !== null) { this.refresh_dt_element = document.getElementById(refresh_dt_element_name) || null; + } else this.refresh_dt_element = null; @@ -1555,10 +1608,7 @@ var NETDATA = window.NETDATA || {}; }; var isHidden = function() { - if(typeof that.___chartIsHidden___ !== 'undefined') - return true; - - return false; + return (typeof that.___chartIsHidden___ !== 'undefined'); }; // hide the chart, when it is not visible - called from isVisible() @@ -1610,10 +1660,7 @@ var NETDATA = window.NETDATA || {}; }; var canBeRendered = function() { - if(isHidden() === true || that.isVisible(true) === false) - return false; - - return true; + return (isHidden() === false && that.isVisible(true) === true); }; // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers @@ -1825,6 +1872,8 @@ var NETDATA = window.NETDATA || {}; this.element_legend_childs.resize_handler.onmouseup = this.element_legend_childs.resize_handler.ontouchend = function(e) { + void(e); + // remove all the hooks document.onmouseup = document.onmousemove = @@ -1899,10 +1948,7 @@ var NETDATA = window.NETDATA || {}; if(NETDATA.options.current.sync_selection === false) return false; - if(NETDATA.globalSelectionSync.dont_sync_before > Date.now()) - return false; - - return true; + return (NETDATA.globalSelectionSync.dont_sync_before <= Date.now()); }; this.globalSelectionSyncIsMaster = function() { @@ -1937,7 +1983,7 @@ var NETDATA = window.NETDATA || {}; var targets = NETDATA.options.targets; var len = targets.length; while(len--) { - st = targets[len]; + var st = targets[len]; if(st === this) { if(this.debug === true) @@ -1956,14 +2002,11 @@ var NETDATA = window.NETDATA || {}; // can the chart participate to the global selection sync as a slave? this.globalSelectionSyncIsEligible = function() { - if(this.enabled === true + return (this.enabled === true && this.library !== null && typeof this.library.setSelection === 'function' && this.isVisible() === true - && this.chart_created === true) - return true; - - return false; + && this.chart_created === true); }; // this chart becomes a slave of the global selection sync @@ -2022,13 +2065,10 @@ var NETDATA = window.NETDATA || {}; }; this.setSelection = function(t) { - if(typeof this.library.setSelection === 'function') { - if(this.library.setSelection(this, t) === true) - this.selected = true; - else - this.selected = false; - } - else this.selected = true; + if(typeof this.library.setSelection === 'function') + this.selected = (this.library.setSelection(this, t) === true); + else + this.selected = true; if(this.selected === true && this.debug === true) this.log('selection set to ' + t.toString()); @@ -2038,13 +2078,10 @@ var NETDATA = window.NETDATA || {}; this.clearSelection = function() { if(this.selected === true) { - if(typeof this.library.clearSelection === 'function') { - if(this.library.clearSelection(this) === true) - this.selected = false; - else - this.selected = true; - } - else this.selected = false; + if(typeof this.library.clearSelection === 'function') + this.selected = (this.library.clearSelection(this) !== true); + else + this.selected = false; if(this.selected === false && this.debug === true) this.log('selection cleared'); @@ -2057,9 +2094,7 @@ var NETDATA = window.NETDATA || {}; // find if a timestamp (ms) is shown in the current chart this.timeIsVisible = function(t) { - if(t >= this.data_after && t <= this.data_before) - return true; - return false; + return (t >= this.data_after && t <= this.data_before); }; this.calculateRowForTime = function(t) { @@ -2210,19 +2245,69 @@ var NETDATA = window.NETDATA || {}; return ret; }; + var __legendFormatValueChartDecimalsLastMin = undefined; + var __legendFormatValueChartDecimalsLastMax = undefined; + var __legendFormatValueChartDecimals = -1; + this.legendFormatValueDecimalsFromMinMax = function(min, max) { + if(min === __legendFormatValueChartDecimalsLastMin && max === __legendFormatValueChartDecimalsLastMax) + return; + + __legendFormatValueChartDecimalsLastMin = min; + __legendFormatValueChartDecimalsLastMax = max; + + if(this.data !== null && this.data.min === this.data.max) + __legendFormatValueChartDecimals = -1; + + else if(this.value_decimal_detail !== -1) + __legendFormatValueChartDecimals = this.value_decimal_detail; + + else { + var delta; + + if (min === max) + delta = Math.abs(min); + else + delta = Math.abs(max - min); + + if (delta > 1000) __legendFormatValueChartDecimals = 0; + else if (delta > 10) __legendFormatValueChartDecimals = 1; + else if (delta > 1) __legendFormatValueChartDecimals = 2; + else if (delta > 0.1) __legendFormatValueChartDecimals = 2; + else __legendFormatValueChartDecimals = 4; + } + }; + this.legendFormatValue = function(value) { - if(value === null || value === 'undefined') return '-'; - if(typeof value !== 'number') return value; - - if(this.value_decimal_detail !== -1) - return (Math.round(value * this.value_decimal_detail) / this.value_decimal_detail).toLocaleString(); - - var abs = Math.abs(value); - if(abs >= 1000) return (Math.round(value)).toLocaleString(); - if(abs >= 100 ) return (Math.round(value * 10) / 10).toLocaleString(); - if(abs >= 1 ) return (Math.round(value * 100) / 100).toLocaleString(); - if(abs >= 0.1 ) return (Math.round(value * 1000) / 1000).toLocaleString(); - return (Math.round(value * 10000) / 10000).toLocaleString(); + if(typeof value !== 'number') return '-'; + + var dmin, dmax; + + if(__legendFormatValueChartDecimals < 0) { + dmin = 0; + var abs = value; + if(abs > 1000) dmax = 0; + else if(abs > 10 ) dmax = 1; + else if(abs > 1) dmax = 2; + else if(abs > 0.1) dmax = 2; + else dmax = 4; + } + else { + dmin = dmax = __legendFormatValueChartDecimals; + } + + if(this.value_decimal_detail !== -1) { + dmin = dmax = this.value_decimal_detail; + } + + return value.toLocaleString(undefined, { + // style: 'decimal', + // minimumIntegerDigits: 1, + // minimumSignificantDigits: 1, + // maximumSignificantDigits: 1, + useGrouping: true, + minimumFractionDigits: dmin, + maximumFractionDigits: dmax + }); }; this.legendSetLabelValue = function(label, value) { @@ -2292,33 +2377,44 @@ var NETDATA = window.NETDATA || {}; } }; + this.legendSetDateLast = { + ms: 0, + date: undefined, + time: undefined + }; + this.legendSetDate = function(ms) { if(typeof ms !== 'number') { this.legendShowUndefined(); return; } - var d = new Date(ms); + if(this.legendSetDateLast.ms !== ms) { + var d = new Date(ms); + this.legendSetDateLast.ms = ms; + this.legendSetDateLast.date = d.toLocaleDateString(); + this.legendSetDateLast.time = d.toLocaleTimeString(); + } - if(this.element_legend_childs.title_date) - this.__legendSetDateString(d.toLocaleDateString()); + if(this.element_legend_childs.title_date !== null) + this.__legendSetDateString(this.legendSetDateLast.date); - if(this.element_legend_childs.title_time) - this.__legendSetTimeString(d.toLocaleTimeString()); + if(this.element_legend_childs.title_time !== null) + this.__legendSetTimeString(this.legendSetDateLast.time); - if(this.element_legend_childs.title_units) + if(this.element_legend_childs.title_units !== null) this.__legendSetUnitsString(this.units) }; this.legendShowUndefined = function() { - if(this.element_legend_childs.title_date) + if(this.element_legend_childs.title_date !== null) this.__legendSetDateString(' '); - if(this.element_legend_childs.title_time) + if(this.element_legend_childs.title_time !== null) this.__legendSetTimeString(this.chart.name); - if(this.element_legend_childs.title_units) - this.__legendSetUnitsString(' ') + if(this.element_legend_childs.title_units !== null) + this.__legendSetUnitsString(' '); if(this.data && this.element_legend_childs.series !== null) { var labels = this.data.dimension_names; @@ -2326,8 +2422,7 @@ var NETDATA = window.NETDATA || {}; while(i--) { var label = labels[i]; - if(typeof label === 'undefined') continue; - if(typeof this.element_legend_childs.series[label] === 'undefined') continue; + if(typeof label === 'undefined' || typeof this.element_legend_childs.series[label] === 'undefined') continue; this.legendSetLabelValue(label, null); } } @@ -2400,8 +2495,8 @@ var NETDATA = window.NETDATA || {}; this.chartColors = function() { if(this.colors !== null) return this.colors; - this.colors = new Array(); - this.colors_available = new Array(); + this.colors = []; + this.colors_available = []; // add the standard colors var len = NETDATA.themes.current.colors.length; @@ -2526,7 +2621,7 @@ var NETDATA = window.NETDATA || {}; + state.chart.chart_type + '" style="background-color: ' + 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + NETDATA.options.current['color_fill_opacity_' + state.chart.chart_type] + ')' - + '">' + + '">'; var text = document.createTextNode(' ' + name); label.name.appendChild(text); @@ -2739,16 +2834,19 @@ var NETDATA = window.NETDATA || {}; this.element_legend_childs.title_date.className += " netdata-legend-title-date"; this.element_legend.appendChild(this.element_legend_childs.title_date); + this.__last_shown_legend_date = undefined; this.element_legend.appendChild(document.createElement('br')); this.element_legend_childs.title_time.className += " netdata-legend-title-time"; this.element_legend.appendChild(this.element_legend_childs.title_time); + this.__last_shown_legend_time = undefined; this.element_legend.appendChild(document.createElement('br')); this.element_legend_childs.title_units.className += " netdata-legend-title-units"; this.element_legend.appendChild(this.element_legend_childs.title_units); + this.__last_shown_legend_units = undefined; this.element_legend.appendChild(document.createElement('br')); @@ -2767,7 +2865,7 @@ var NETDATA = window.NETDATA || {}; placement: 'bottom', title: 'Chart Legend', delay: { show: NETDATA.options.current.show_help_delay_show_ms, hide: NETDATA.options.current.show_help_delay_hide_ms }, - content: 'You can click or tap on the values or the labels to select dimentions. By pressing SHIFT or CONTROL, you can enable or disable multiple dimensions.
Help, can be disabled from the settings.' + content: 'You can click or tap on the values or the labels to select dimensions. By pressing SHIFT or CONTROL, you can enable or disable multiple dimensions.
Help, can be disabled from the settings.' }); } else { @@ -2799,7 +2897,7 @@ var NETDATA = window.NETDATA || {}; } } else { - var tmp = new Array(); + var tmp = []; keys = Object.keys(this.chart.dimensions); for(i = 0, len = keys.length; i < len ;i++) { dim = keys[i]; @@ -3004,12 +3102,12 @@ var NETDATA = window.NETDATA || {}; if(NETDATA.options.current.pan_and_zoom_data_padding === true && this.requested_padding !== null) { if(this.view_after < this.data_after) { - // console.log('adusting view_after from ' + this.view_after + ' to ' + this.data_after); + // console.log('adjusting view_after from ' + this.view_after + ' to ' + this.data_after); this.view_after = this.data_after; } if(this.view_before > this.data_before) { - // console.log('adusting view_before from ' + this.view_before + ' to ' + this.data_before); + // console.log('adjusting view_before from ' + this.view_before + ' to ' + this.data_before); this.view_before = this.data_before; } } @@ -3041,7 +3139,8 @@ var NETDATA = window.NETDATA || {}; if(this.debug === true) this.log('max updates of ' + this.updates_since_last_creation.toString() + ' reached. Forcing re-generation.'); - this.chart_created = false; + init(); + return; } // check and update the legend @@ -3582,10 +3681,10 @@ var NETDATA = window.NETDATA || {}; // ---------------------------------------------------------------------------------------------------------------- - // this is purely sequencial charts refresher + // this is purely sequential charts refresher // it is meant to be autonomous NETDATA.chartRefresherNoParallel = function(index) { - if(NETDATA.options.debug.mail_loop === true) + if(NETDATA.options.debug.main_loop === true) console.log('NETDATA.chartRefresherNoParallel(' + index + ')'); if(NETDATA.options.updated_dom === true) { @@ -3628,41 +3727,11 @@ var NETDATA = window.NETDATA || {}; } }; - // this is part of the parallel refresher - // its cause is to refresh sequencially all the charts - // that depend on chart library initialization - // it will call the parallel refresher back - // as soon as it sees a chart that its chart library - // is initialized - NETDATA.chartRefresher_uninitialized = function() { - if(NETDATA.options.updated_dom === true) { - // the dom has been updated - // get the dom parts again - NETDATA.parseDom(NETDATA.chartRefresher); - return; - } - - if(NETDATA.options.sequencial.length === 0) - NETDATA.chartRefresher(); - else { - var state = NETDATA.options.sequencial.pop(); - if(state.library.initialized === true) - NETDATA.chartRefresher(); - else - state.autoRefresh(NETDATA.chartRefresher_uninitialized); - } - }; - NETDATA.chartRefresherWaitTime = function() { return NETDATA.options.current.idle_parallel_loops; }; // the default refresher - // it will create 2 sets of charts: - // - the ones that can be refreshed in parallel - // - the ones that depend on something else - // the first set will be executed in parallel - // the second will be given to NETDATA.chartRefresher_uninitialized() NETDATA.chartRefresher = function() { // console.log('auto-refresher...'); @@ -3695,7 +3764,7 @@ var NETDATA = window.NETDATA || {}; return; } - var parallel = new Array(); + var parallel = []; var targets = NETDATA.options.targets; var len = targets.length; var state; @@ -3742,7 +3811,7 @@ var NETDATA = window.NETDATA || {}; if(NETDATA.options.debug.main_loop === true) console.log('DOM updated - there are ' + targets.length + ' charts on page.'); - NETDATA.options.targets = new Array(); + NETDATA.options.targets = []; var len = targets.length; while(len--) { // the initialization will take care of sizing @@ -3788,12 +3857,14 @@ var NETDATA = window.NETDATA || {}; $('a[data-toggle="tab"]').on('shown.bs.tab', NETDATA.onscroll); // bootstrap modal switching - $('.modal').on('hidden.bs.modal', NETDATA.onscroll); - $('.modal').on('shown.bs.modal', NETDATA.onscroll); + var $modal = $('.modal'); + $modal.on('hidden.bs.modal', NETDATA.onscroll); + $modal.on('shown.bs.modal', NETDATA.onscroll); // bootstrap collapse switching - $('.collapse').on('hidden.bs.collapse', NETDATA.onscroll); - $('.collapse').on('shown.bs.collapse', NETDATA.onscroll); + var $collapse = $('.collapse'); + $collapse.on('hidden.bs.collapse', NETDATA.onscroll); + $collapse.on('shown.bs.collapse', NETDATA.onscroll); NETDATA.parseDom(NETDATA.chartRefresher); @@ -4053,7 +4124,7 @@ var NETDATA = window.NETDATA || {}; return true; }; - NETDATA.dygraphClearSelection = function(state, t) { + NETDATA.dygraphClearSelection = function(state) { if(typeof state.dygraph_instance !== 'undefined') { state.dygraph_instance.clearSelection(); } @@ -4200,125 +4271,205 @@ var NETDATA = window.NETDATA || {}; var self = $(state.element); - var chart_type = state.chart.chart_type; + var chart_type = self.data('dygraph-type') || state.chart.chart_type; if(chart_type === 'stacked' && data.dimensions === 1) chart_type = 'area'; - chart_type = self.data('dygraph-type') || chart_type; - var smooth = (chart_type === 'line' && !NETDATA.chartLibraries.dygraph.isSparkline(state))?true:false; - smooth = self.data('dygraph-smooth') || smooth; + var highlightCircleSize = (NETDATA.chartLibraries.dygraph.isSparkline(state) === true)?3:4; - if(NETDATA.dygraph.smooth === false) - smooth = false; - - var strokeWidth = (chart_type === 'stacked')?0.1:((smooth)?1.5:0.7) - var highlightCircleSize = (NETDATA.chartLibraries.dygraph.isSparkline(state))?3:4; + var smooth = (NETDATA.dygraph.smooth === true) + ?(self.data('dygraph-smooth') || (chart_type === 'line' && NETDATA.chartLibraries.dygraph.isSparkline(state) === false)) + :false; state.dygraph_options = { - colors: self.data('dygraph-colors') || state.chartColors(), + colors: self.data('dygraph-colors') || state.chartColors(), // leave a few pixels empty on the right of the chart - rightGap: self.data('dygraph-rightgap') || 5, - showRangeSelector: self.data('dygraph-showrangeselector') || false, - showRoller: self.data('dygraph-showroller') || false, - - title: self.data('dygraph-title') || state.title, - titleHeight: self.data('dygraph-titleheight') || 19, - - legend: self.data('dygraph-legend') || 'always', // we need this to get selection events - labels: data.result.labels, - labelsDiv: self.data('dygraph-labelsdiv') || state.element_legend_childs.hidden, - labelsDivStyles: self.data('dygraph-labelsdivstyles') || { 'fontSize':'1px' }, - labelsDivWidth: self.data('dygraph-labelsdivwidth') || state.chartWidth() - 70, - labelsSeparateLines: self.data('dygraph-labelsseparatelines') || true, - labelsShowZeroValues: self.data('dygraph-labelsshowzerovalues') || true, - labelsKMB: false, - labelsKMG2: false, - showLabelsOnHighlight: self.data('dygraph-showlabelsonhighlight') || true, - hideOverlayOnMouseOut: self.data('dygraph-hideoverlayonmouseout') || true, - - includeZero: self.data('dygraph-includezero') || ((chart_type === 'stacked')? true : false), - xRangePad: self.data('dygraph-xrangepad') || 0, - yRangePad: self.data('dygraph-yrangepad') || 1, - - valueRange: self.data('dygraph-valuerange') || [ null, null ], - - ylabel: state.units, - yLabelWidth: self.data('dygraph-ylabelwidth') || 12, - - // the function to plot the chart - plotter: null, - - // The width of the lines connecting data points. This can be used to increase the contrast or some graphs. - strokeWidth: self.data('dygraph-strokewidth') || strokeWidth, - strokePattern: self.data('dygraph-strokepattern') || undefined, - - // The size of the dot to draw on each point in pixels (see drawPoints). A dot is always drawn when a point is "isolated", - // i.e. there is a missing point on either side of it. This also controls the size of those dots. - drawPoints: self.data('dygraph-drawpoints') || false, - - // Draw points at the edges of gaps in the data. This improves visibility of small data segments or other data irregularities. - drawGapEdgePoints: self.data('dygraph-drawgapedgepoints') || true, - - connectSeparatedPoints: self.data('dygraph-connectseparatedpoints') || false, - pointSize: self.data('dygraph-pointsize') || 1, - - // enabling this makes the chart with little square lines - stepPlot: self.data('dygraph-stepplot') || false, - - // Draw a border around graph lines to make crossing lines more easily distinguishable. Useful for graphs with many lines. - strokeBorderColor: self.data('dygraph-strokebordercolor') || NETDATA.themes.current.background, - strokeBorderWidth: self.data('dygraph-strokeborderwidth') || (chart_type === 'stacked')?0.0:0.0, - - fillGraph: self.data('dygraph-fillgraph') || ((chart_type === 'area' || chart_type === 'stacked')?true:false), - fillAlpha: self.data('dygraph-fillalpha') || ((chart_type === 'stacked')?NETDATA.options.current.color_fill_opacity_stacked:NETDATA.options.current.color_fill_opacity_area), - stackedGraph: self.data('dygraph-stackedgraph') || ((chart_type === 'stacked')?true:false), - stackedGraphNaNFill: self.data('dygraph-stackedgraphnanfill') || 'none', - - drawAxis: self.data('dygraph-drawaxis') || true, - axisLabelFontSize: self.data('dygraph-axislabelfontsize') || 10, - axisLineColor: self.data('dygraph-axislinecolor') || NETDATA.themes.current.axis, - axisLineWidth: self.data('dygraph-axislinewidth') || 1.0, - - drawGrid: self.data('dygraph-drawgrid') || true, - gridLinePattern: self.data('dygraph-gridlinepattern') || null, - gridLineWidth: self.data('dygraph-gridlinewidth') || 1.0, - gridLineColor: self.data('dygraph-gridlinecolor') || NETDATA.themes.current.grid, - - maxNumberWidth: self.data('dygraph-maxnumberwidth') || 8, - sigFigs: self.data('dygraph-sigfigs') || null, - digitsAfterDecimal: self.data('dygraph-digitsafterdecimal') || 2, - valueFormatter: self.data('dygraph-valueformatter') || function(x){ return x.toFixed(2); }, - - highlightCircleSize: self.data('dygraph-highlightcirclesize') || highlightCircleSize, - highlightSeriesOpts: self.data('dygraph-highlightseriesopts') || null, // TOO SLOW: { strokeWidth: 1.5 }, - highlightSeriesBackgroundAlpha: self.data('dygraph-highlightseriesbackgroundalpha') || null, // TOO SLOW: (chart_type === 'stacked')?0.7:0.5, - - pointClickCallback: self.data('dygraph-pointclickcallback') || undefined, - visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names), + rightGap: self.data('dygraph-rightgap') + || 5, + + showRangeSelector: self.data('dygraph-showrangeselector') + || false, + + showRoller: self.data('dygraph-showroller') + || false, + + title: self.data('dygraph-title') + || state.title, + + titleHeight: self.data('dygraph-titleheight') + || 19, + + legend: self.data('dygraph-legend') + || 'always', // we need this to get selection events + + labels: data.result.labels, + + labelsDiv: self.data('dygraph-labelsdiv') + || state.element_legend_childs.hidden, + + labelsDivStyles: self.data('dygraph-labelsdivstyles') + || { 'fontSize':'1px' }, + + labelsDivWidth: self.data('dygraph-labelsdivwidth') + || state.chartWidth() - 70, + + labelsSeparateLines: self.data('dygraph-labelsseparatelines') + || true, + + labelsShowZeroValues: self.data('dygraph-labelsshowzerovalues') + || true, + + labelsKMB: false, + labelsKMG2: false, + + showLabelsOnHighlight: self.data('dygraph-showlabelsonhighlight') + || true, + + hideOverlayOnMouseOut: self.data('dygraph-hideoverlayonmouseout') + || true, + + includeZero: self.data('dygraph-includezero') + || (chart_type === 'stacked'), + + xRangePad: self.data('dygraph-xrangepad') + || 0, + + yRangePad: self.data('dygraph-yrangepad') + || 1, + + valueRange: self.data('dygraph-valuerange') + || [ null, null ], + + ylabel: state.units, + + yLabelWidth: self.data('dygraph-ylabelwidth') + || 12, + + // the function to plot the chart + plotter: null, + + // The width of the lines connecting data points. + // This can be used to increase the contrast or some graphs. + strokeWidth: self.data('dygraph-strokewidth') + || ((chart_type === 'stacked')?0.1:((smooth === true)?1.5:0.7)), + + strokePattern: self.data('dygraph-strokepattern') + || undefined, + + // The size of the dot to draw on each point in pixels (see drawPoints). + // A dot is always drawn when a point is "isolated", + // i.e. there is a missing point on either side of it. + // This also controls the size of those dots. + drawPoints: self.data('dygraph-drawpoints') + || false, + + // Draw points at the edges of gaps in the data. + // This improves visibility of small data segments or other data irregularities. + drawGapEdgePoints: self.data('dygraph-drawgapedgepoints') + || true, + + connectSeparatedPoints: self.data('dygraph-connectseparatedpoints') + || false, + + pointSize: self.data('dygraph-pointsize') + || 1, + + // enabling this makes the chart with little square lines + stepPlot: self.data('dygraph-stepplot') + || false, + + // Draw a border around graph lines to make crossing lines more easily + // distinguishable. Useful for graphs with many lines. + strokeBorderColor: self.data('dygraph-strokebordercolor') + || NETDATA.themes.current.background, + + strokeBorderWidth: self.data('dygraph-strokeborderwidth') + || (chart_type === 'stacked')?0.0:0.0, + + fillGraph: self.data('dygraph-fillgraph') + || (chart_type === 'area' || chart_type === 'stacked'), + + fillAlpha: self.data('dygraph-fillalpha') + || ((chart_type === 'stacked') + ?NETDATA.options.current.color_fill_opacity_stacked + :NETDATA.options.current.color_fill_opacity_area), + + stackedGraph: self.data('dygraph-stackedgraph') + || (chart_type === 'stacked'), + + stackedGraphNaNFill: self.data('dygraph-stackedgraphnanfill') + || 'none', + + drawAxis: self.data('dygraph-drawaxis') + || true, + + axisLabelFontSize: self.data('dygraph-axislabelfontsize') + || 10, + + axisLineColor: self.data('dygraph-axislinecolor') + || NETDATA.themes.current.axis, + + axisLineWidth: self.data('dygraph-axislinewidth') + || 1.0, + + drawGrid: self.data('dygraph-drawgrid') + || true, + + gridLinePattern: self.data('dygraph-gridlinepattern') + || null, + + gridLineWidth: self.data('dygraph-gridlinewidth') + || 1.0, + + gridLineColor: self.data('dygraph-gridlinecolor') + || NETDATA.themes.current.grid, + + maxNumberWidth: self.data('dygraph-maxnumberwidth') + || 8, + + sigFigs: self.data('dygraph-sigfigs') + || null, + + digitsAfterDecimal: self.data('dygraph-digitsafterdecimal') + || 2, + + valueFormatter: self.data('dygraph-valueformatter') + || undefined, + + highlightCircleSize: self.data('dygraph-highlightcirclesize') + || highlightCircleSize, + + highlightSeriesOpts: self.data('dygraph-highlightseriesopts') + || null, // TOO SLOW: { strokeWidth: 1.5 }, + + highlightSeriesBackgroundAlpha: self.data('dygraph-highlightseriesbackgroundalpha') + || null, // TOO SLOW: (chart_type === 'stacked')?0.7:0.5, + + pointClickCallback: self.data('dygraph-pointclickcallback') + || undefined, + + visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names), + axes: { x: { pixelsPerLabel: 50, ticker: Dygraph.dateTicker, axisLabelFormatter: function (d, gran) { + void(gran); return NETDATA.zeropad(d.getHours()) + ":" + NETDATA.zeropad(d.getMinutes()) + ":" + NETDATA.zeropad(d.getSeconds()); - }, - valueFormatter: function (ms) { - //var d = new Date(ms); - //return d.toLocaleDateString() + ' ' + d.toLocaleTimeString(); - - // no need to return anything here - return ' '; - } }, y: { pixelsPerLabel: 15, - valueFormatter: function (x) { - // we format legends with the state object - // no need to do anything here - // return (Math.round(x*100) / 100).toLocaleString(); - // return state.legendFormatValue(x); - return x; + axisLabelFormatter: function (y) { + + // unfortunately, we have to call this every single time + state.legendFormatValueDecimalsFromMinMax( + this.axes_[0].extremeRange[0], + this.axes_[0].extremeRange[1] + ); + + return state.legendFormatValue(y); } } }, @@ -4336,6 +4487,8 @@ var NETDATA = window.NETDATA || {}; var series = data.series[i]; if(series.isVisible === true) state.legendSetLabelValue(series.label, series.y); + else + state.legendSetLabelValue(series.label, null); } } @@ -4357,6 +4510,8 @@ var NETDATA = window.NETDATA || {}; } }, zoomCallback: function(minDate, maxDate, yRanges) { + void(yRanges); + if(NETDATA.options.debug.dygraph === true) state.log('dygraphZoomCallback()'); @@ -4370,6 +4525,8 @@ var NETDATA = window.NETDATA || {}; state.updateChartPanOrZoom(minDate, maxDate); }, highlightCallback: function(event, x, points, row, seriesName) { + void(seriesName); + if(NETDATA.options.debug.dygraph === true || state.debug === true) state.log('dygraphHighlightCallback()'); @@ -4379,7 +4536,7 @@ var NETDATA = window.NETDATA || {}; // the time it thinks is selected is wrong // here we calculate the time t based on the row number selected // which is ok - var t = state.data_after + row * state.data_update_every; + // var t = state.data_after + row * state.data_update_every; // console.log('row = ' + row + ', x = ' + x + ', t = ' + t + ' ' + ((t === x)?'SAME':(Math.abs(x-t)<=state.data_update_every)?'SIMILAR':'DIFFERENT') + ', rows in db: ' + state.data_points + ' visible(x) = ' + state.timeIsVisible(x) + ' visible(t) = ' + state.timeIsVisible(t) + ' r(x) = ' + state.calculateRowForTime(x) + ' r(t) = ' + state.calculateRowForTime(t) + ' range: ' + state.data_after + ' - ' + state.data_before + ' real: ' + state.data.after + ' - ' + state.data.before + ' every: ' + state.data_update_every); state.globalSelectionSync(x); @@ -4389,6 +4546,8 @@ var NETDATA = window.NETDATA || {}; // state.dygraph_instance.plugins_[0].plugin.legend_div_.style.zIndex = 10000; }, unhighlightCallback: function(event) { + void(event); + if(NETDATA.options.debug.dygraph === true || state.debug === true) state.log('dygraphUnhighlightCallback()'); @@ -4472,17 +4631,26 @@ var NETDATA = window.NETDATA || {}; } }, click: function(event, dygraph, context) { + void(dygraph); + void(context); + if(NETDATA.options.debug.dygraph === true || state.debug === true) state.log('interactionModel.click()'); event.preventDefault(); }, dblclick: function(event, dygraph, context) { + void(event); + void(dygraph); + void(context); + if(NETDATA.options.debug.dygraph === true || state.debug === true) state.log('interactionModel.dblclick()'); NETDATA.resetAllCharts(state); }, wheel: function(event, dygraph, context) { + void(context); + if(NETDATA.options.debug.dygraph === true || state.debug === true) state.log('interactionModel.wheel()'); @@ -4494,7 +4662,7 @@ var NETDATA = window.NETDATA || {}; var xOffset = g.toDomCoords(g.xAxisRange()[0], null)[0]; var yar0 = g.yAxisRange(0); - // This is calculating the pixel of the higest value. (Top pixel) + // This is calculating the pixel of the highest value. (Top pixel) var yOffset = g.toDomCoords(null, yar0[1])[1]; // x y w and h are relative to the corner of the drawing area, @@ -4605,7 +4773,7 @@ var NETDATA = window.NETDATA || {}; Dygraph.defaultInteractionModel.touchstart(event, dygraph, context); // we overwrite the touch directions at the end, to overwrite - // the internal default of dygraphs + // the internal default of dygraph context.touchDirections = { x: true, y: false }; state.dygraph_last_touch_start = Date.now(); @@ -4634,7 +4802,7 @@ var NETDATA = window.NETDATA || {}; // if it didn't move, it is a selection if(state.dygraph_last_touch_move === 0 && state.dygraph_last_touch_page_x !== 0) { - // internal api of dygraphs + // internal api of dygraph var pct = (state.dygraph_last_touch_page_x - (dygraph.plotter_.area.x + state.element.getBoundingClientRect().left)) / dygraph.plotter_.area.w; var t = Math.round(state.data_after + (state.data_before - state.data_after) * pct); if(NETDATA.dygraphSetSelection(state, t) === true) @@ -4690,7 +4858,7 @@ var NETDATA = window.NETDATA || {}; state.__commonMax = self.data('common-max') || null; } else { - state.log('incompatible version of dygraphs detected'); + state.log('incompatible version of Dygraph detected'); state.__commonMin = null; state.__commonMax = null; } @@ -4976,10 +5144,16 @@ var NETDATA = window.NETDATA || {}; }; NETDATA.d3ChartUpdate = function(state, data) { + void(state); + void(data); + return false; }; NETDATA.d3ChartCreate = function(state, data) { + void(state); + void(data); + return false; }; @@ -5174,10 +5348,11 @@ var NETDATA = window.NETDATA || {}; NETDATA.easypiechartClearSelection = function(state) { if(typeof state.easyPieChartEvent !== 'undefined') { - if(state.easyPieChartEvent.timer !== null) + if(state.easyPieChartEvent.timer !== undefined) { clearTimeout(state.easyPieChartEvent.timer); + } - state.easyPieChartEvent.timer = null; + state.easyPieChartEvent.timer = undefined; } if(state.isAutoRefreshable() === true && state.data !== null) { @@ -5202,7 +5377,7 @@ var NETDATA = window.NETDATA || {}; if(typeof state.easyPieChartEvent === 'undefined') { state.easyPieChartEvent = { - timer: null, + timer: undefined, value: 0, pcent: 0 }; @@ -5217,11 +5392,11 @@ var NETDATA = window.NETDATA || {}; state.easyPieChartEvent.pcent = pcent; state.easyPieChartLabel.innerText = state.legendFormatValue(value); - if(state.easyPieChartEvent.timer === null) { + if(state.easyPieChartEvent.timer === undefined) { state.easyPieChart_instance.disableAnimation(); state.easyPieChartEvent.timer = setTimeout(function() { - state.easyPieChartEvent.timer = null; + state.easyPieChartEvent.timer = undefined; state.easyPieChart_instance.update(state.easyPieChartEvent.pcent); }, NETDATA.options.current.charts_selection_animation_delay); } @@ -5421,9 +5596,10 @@ var NETDATA = window.NETDATA || {}; // is always between min and max var pcent = (value - min) * 100 / (max - min); - // these should never happen - if(pcent < 0) pcent = 0; - if(pcent > 100) pcent = 100; + // bug fix for gauge.js 1.3.1 + // if the value is the absolute min or max, the chart is broken + if(pcent < 0.001) pcent = 0.001; + if(pcent > 99.999) pcent = 99.999; state.gauge_instance.set(pcent); // console.log('gauge set ' + pcent + ', value ' + value + ', min ' + min + ', max ' + max); @@ -5450,10 +5626,11 @@ var NETDATA = window.NETDATA || {}; NETDATA.gaugeClearSelection = function(state) { if(typeof state.gaugeEvent !== 'undefined') { - if(state.gaugeEvent.timer !== null) + if(state.gaugeEvent.timer !== undefined) { clearTimeout(state.gaugeEvent.timer); + } - state.gaugeEvent.timer = null; + state.gaugeEvent.timer = undefined; } if(state.isAutoRefreshable() === true && state.data !== null) { @@ -5479,7 +5656,7 @@ var NETDATA = window.NETDATA || {}; if(typeof state.gaugeEvent === 'undefined') { state.gaugeEvent = { - timer: null, + timer: undefined, value: 0, min: 0, max: 0 @@ -5499,11 +5676,11 @@ var NETDATA = window.NETDATA || {}; state.gaugeEvent.max = max; NETDATA.gaugeSetLabels(state, value, min, max); - if(state.gaugeEvent.timer === null) { + if(state.gaugeEvent.timer === undefined) { NETDATA.gaugeAnimation(state, false); state.gaugeEvent.timer = setTimeout(function() { - state.gaugeEvent.timer = null; + state.gaugeEvent.timer = undefined; NETDATA.gaugeSet(state, state.gaugeEvent.value, state.gaugeEvent.min, state.gaugeEvent.max); }, NETDATA.options.current.charts_selection_animation_delay); } @@ -5583,19 +5760,22 @@ var NETDATA = window.NETDATA || {}; var options = { lines: 12, // The number of lines to draw - angle: 0.15, // The length of each line - lineWidth: 0.44, // 0.44 The line thickness + angle: 0.15, // The span of the gauge arc + lineWidth: 0.50, // The line thickness + radiusScale: 0.85, // Relative radius pointer: { length: 0.8, // 0.9 The radius of the inner circle strokeWidth: 0.035, // The rotation offset color: pointerColor // Fill color }, + limitMax: true, // If false, the max value of the gauge will be updated if value surpass max + limitMin: true, // If true, the min value of the gauge will be fixed unless you set it manually colorStart: startColor, // Colors colorStop: stopColor, // just experiment with them strokeColor: strokeColor, // to see which ones work best for you - limitMax: true, - generateGradient: (generateGradient === true)?true:false, - gradientType: 0 + generateGradient: (generateGradient === true), + gradientType: 0, + highDpiSupport: true // High resolution support }; if (generateGradient.constructor === Array) { @@ -5605,13 +5785,13 @@ var NETDATA = window.NETDATA || {}; // data-gauge-gradient-percent-color-50="#999900" // data-gauge-gradient-percent-color-100="#000000" - options.percentColors = new Array(); + options.percentColors = []; var len = generateGradient.length; while(len--) { var pcent = generateGradient[len]; - var color = self.data('gauge-gradient-percent-color-' + pcent.toString()) || false; + var color = self.attr('data-gauge-gradient-percent-color-' + pcent.toString()) || false; if(color !== false) { - var a = new Array(); + var a = []; a[0] = pcent / 100; a[1] = color; options.percentColors.unshift(a); @@ -5621,6 +5801,7 @@ var NETDATA = window.NETDATA || {}; delete options.percentColors; } else if(generateGradient === false && NETDATA.themes.current.gauge_gradient === true) { + //noinspection PointlessArithmeticExpressionJS options.percentColors = [ [0.0, NETDATA.colorLuminance(startColor, (lum_d * 10) - (lum_d * 0))], [0.1, NETDATA.colorLuminance(startColor, (lum_d * 10) - (lum_d * 1))], @@ -5722,31 +5903,21 @@ var NETDATA = window.NETDATA || {}; toolboxPanAndZoom: NETDATA.dygraphToolboxPanAndZoom, initialized: false, enabled: true, - format: function(state) { return 'json'; }, - options: function(state) { return 'ms|flip'; }, + format: function(state) { void(state); return 'json'; }, + options: function(state) { void(state); return 'ms|flip'; }, legend: function(state) { - if(this.isSparkline(state) === false) - return 'right-side'; - else - return null; + return (this.isSparkline(state) === false)?'right-side':null; }, - autoresize: function(state) { return true; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return true; }, + autoresize: function(state) { void(state); return true; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return true; }, pixels_per_point: function(state) { - if(this.isSparkline(state) === false) - return 3; - else - return 2; + return (this.isSparkline(state) === false)?3:2; }, - isSparkline: function(state) { if(typeof state.dygraph_sparkline === 'undefined') { var t = $(state.element).data('dygraph-theme'); - if(t === 'sparkline') - state.dygraph_sparkline = true; - else - state.dygraph_sparkline = false; + state.dygraph_sparkline = (t === 'sparkline'); } return state.dygraph_sparkline; } @@ -5756,126 +5927,126 @@ var NETDATA = window.NETDATA || {}; create: NETDATA.sparklineChartCreate, update: NETDATA.sparklineChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'array'; }, - options: function(state) { return 'flip|abs'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 3; } + format: function(state) { void(state); return 'array'; }, + options: function(state) { void(state); return 'flip|abs'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 3; } }, "peity": { initialize: NETDATA.peityInitialize, create: NETDATA.peityChartCreate, update: NETDATA.peityChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'ssvcomma'; }, - options: function(state) { return 'null2zero|flip|abs'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 3; } + format: function(state) { void(state); return 'ssvcomma'; }, + options: function(state) { void(state); return 'null2zero|flip|abs'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 3; } }, "morris": { initialize: NETDATA.morrisInitialize, create: NETDATA.morrisChartCreate, update: NETDATA.morrisChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'json'; }, - options: function(state) { return 'objectrows|ms'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 50; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 15; } + format: function(state) { void(state); return 'json'; }, + options: function(state) { void(state); return 'objectrows|ms'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 50; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 15; } }, "google": { initialize: NETDATA.googleInitialize, create: NETDATA.googleChartCreate, update: NETDATA.googleChartUpdate, resize: null, - setSelection: undefined, //function(state, t) { return true; }, - clearSelection: undefined, //function(state) { return true; }, + setSelection: undefined, //function(state, t) { void(state); return true; }, + clearSelection: undefined, //function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'datatable'; }, - options: function(state) { return ''; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 300; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 4; } + format: function(state) { void(state); return 'datatable'; }, + options: function(state) { void(state); return ''; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 300; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 4; } }, "raphael": { initialize: NETDATA.raphaelInitialize, create: NETDATA.raphaelChartCreate, update: NETDATA.raphaelChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'json'; }, - options: function(state) { return ''; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 3; } + format: function(state) { void(state); return 'json'; }, + options: function(state) { void(state); return ''; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 3; } }, "c3": { initialize: NETDATA.c3Initialize, create: NETDATA.c3ChartCreate, update: NETDATA.c3ChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'csvjsonarray'; }, - options: function(state) { return 'milliseconds'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 15; } + format: function(state) { void(state); return 'csvjsonarray'; }, + options: function(state) { void(state); return 'milliseconds'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 15; } }, "d3": { initialize: NETDATA.d3Initialize, create: NETDATA.d3ChartCreate, update: NETDATA.d3ChartUpdate, resize: null, - setSelection: undefined, // function(state, t) { return true; }, - clearSelection: undefined, // function(state) { return true; }, + setSelection: undefined, // function(state, t) { void(state); return true; }, + clearSelection: undefined, // function(state) { void(state); return true; }, toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'json'; }, - options: function(state) { return ''; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return false; }, - pixels_per_point: function(state) { return 3; } + format: function(state) { void(state); return 'json'; }, + options: function(state) { void(state); return ''; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return false; }, + pixels_per_point: function(state) { void(state); return 3; } }, "easypiechart": { initialize: NETDATA.easypiechartInitialize, @@ -5887,13 +6058,13 @@ var NETDATA = window.NETDATA || {}; toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'array'; }, - options: function(state) { return 'absolute'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return true; }, - pixels_per_point: function(state) { return 3; }, + format: function(state) { void(state); return 'array'; }, + options: function(state) { void(state); return 'absolute'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return true; }, + pixels_per_point: function(state) { void(state); return 3; }, aspect_ratio: 100 }, "gauge": { @@ -5906,13 +6077,13 @@ var NETDATA = window.NETDATA || {}; toolboxPanAndZoom: null, initialized: false, enabled: true, - format: function(state) { return 'array'; }, - options: function(state) { return 'absolute'; }, - legend: function(state) { return null; }, - autoresize: function(state) { return false; }, - max_updates_to_recreate: function(state) { return 5000; }, - track_colors: function(state) { return true; }, - pixels_per_point: function(state) { return 3; }, + format: function(state) { void(state); return 'array'; }, + options: function(state) { void(state); return 'absolute'; }, + legend: function(state) { void(state); return null; }, + autoresize: function(state) { void(state); return false; }, + max_updates_to_recreate: function(state) { void(state); return 5000; }, + track_colors: function(state) { void(state); return true; }, + pixels_per_point: function(state) { void(state); return 3; }, aspect_ratio: 70 } }; @@ -5938,10 +6109,7 @@ var NETDATA = window.NETDATA || {}; if(typeof $().emulateTransitionEnd === 'function') return true; else { - if(typeof netdataNoBootstrap !== 'undefined' && netdataNoBootstrap) - return true; - else - return false; + return (typeof netdataNoBootstrap !== 'undefined' && netdataNoBootstrap === true); } } }, @@ -5955,10 +6123,7 @@ var NETDATA = window.NETDATA || {}; { url: NETDATA.themes.current.bootstrap_css, isAlreadyLoaded: function() { - if(typeof netdataNoBootstrap !== 'undefined' && netdataNoBootstrap) - return true; - else - return false; + return (typeof netdataNoBootstrap !== 'undefined' && netdataNoBootstrap === true); } }, { @@ -6010,7 +6175,7 @@ var NETDATA = window.NETDATA || {}; if(async === false) NETDATA.loadRequiredJs(++index, callback); - }) + }); if(async === true) NETDATA.loadRequiredJs(++index, callback); @@ -6050,7 +6215,7 @@ var NETDATA = window.NETDATA || {}; last_notification_id: 0, // the id of the last alarm_log we have raised an alarm for first_notification_id: 0, // the id of the first alarm_log entry for this session // this is used to prevent CLEAR notifications for past events - // notifications_shown: new Array(), + // notifications_shown: [], server: null, // the server to connect to for fetching alarms current: null, // the list of raised alarms - updated in the background @@ -6064,16 +6229,18 @@ var NETDATA = window.NETDATA || {}; return; } - var value = entry.value; + var value_string = entry.value_string; + if(NETDATA.alarms.current !== null) { + // get the current value_string var t = NETDATA.alarms.current.alarms[entry.chart + '.' + entry.name]; - if(typeof t !== 'undefined' && entry.status === t.status) - value = t.value; + if(typeof t !== 'undefined' && entry.status === t.status && typeof t.value_string !== 'undefined') + value_string = t.value_string; } var name = entry.name.replace(/_/g, ' '); var status = entry.status.toLowerCase(); - var title = name + ' = ' + ((value === null)?'NaN':Math.floor(value)).toString() + ' ' + entry.units; + var title = name + ' = ' + value_string.toString(); var tag = entry.alarm_id; var icon = 'images/seo-performance-128.png'; var interaction = false; @@ -6102,8 +6269,12 @@ var NETDATA = window.NETDATA || {}; // console.log('alarm' + entry.unique_id + ' switch to CLEAR from ' + entry.old_status); return; } - title = name + ' back to normal'; - icon = 'images/check-mark-2-128-green.png' + if(entry.no_clear_notification === true) { + // console.log('alarm' + entry.unique_id + ' is CLEAR but has no_clear_notification flag'); + return; + } + title = name + ' back to normal (' + value_string.toString() + ')'; + icon = 'images/check-mark-2-128-green.png'; interaction = false; break; @@ -6119,7 +6290,7 @@ var NETDATA = window.NETDATA || {}; if(entry.old_status === 'WARNING') status = 'escalated to ' + entry.status.toLowerCase(); - icon = 'images/alert-128-red.png' + icon = 'images/alert-128-red.png'; interaction = true; break; @@ -6361,12 +6532,12 @@ var NETDATA = window.NETDATA || {}; // Registry of netdata hosts NETDATA.registry = { - server: null, // the netdata registry server - person_guid: null, // the unique ID of this browser / user - machine_guid: null, // the unique ID the netdata server that served dashboard.js - hostname: null, // the hostname of the netdata server that served dashboard.js - machines: null, // the user's other URLs - machines_array: null, // the user's other URLs in an array + server: null, // the netdata registry server + person_guid: null, // the unique ID of this browser / user + machine_guid: null, // the unique ID the netdata server that served dashboard.js + hostname: 'unknown', // the hostname of the netdata server that served dashboard.js + machines: null, // the user's other URLs + machines_array: null, // the user's other URLs in an array person_urls: null, parsePersonUrls: function(person_urls) { @@ -6375,9 +6546,8 @@ var NETDATA = window.NETDATA || {}; if(person_urls) { NETDATA.registry.machines = {}; - NETDATA.registry.machines_array = new Array(); + NETDATA.registry.machines_array = []; - var now = Date.now(); var apu = person_urls; var i = apu.length; while(i--) { @@ -6390,7 +6560,7 @@ var NETDATA = window.NETDATA || {}; last_t: apu[i][2], accesses: apu[i][3], name: apu[i][4], - alternate_urls: new Array() + alternate_urls: [] }; obj.alternate_urls.push(apu[i][1]);