Split js 2 (#4581)

* Mild cleanup of dashboard.js (#4461)

* Balancing of else clauses

* More cleanup, fixed nasty bug introduced by previous commit

* More cleanup

* More refactoring

* Wip

* More refactoring

* Wip

* Cleanup, wip

* Refactor for-loop

* Remove .hasOwnProperties, wip

* Split dashboard.js into multiple files, wip #4479

* Fixed a bug in common min/max

* Extracted more files from dashboard.js

* Extracted more code, wip

* Extract units-conversion.js and sparkline.js

* Do not include morris.js, c3.js and raphael.js in dashbaord.js

They are extracted as separate files but not included in dashboards.js

* Removed refs to obsolete charting libraries #4492

* Extracted google-charts #4479

* Extracted google-charts

* Extracted more charting libraries, cleanup

* Organize charting libs in subfolder

* Apply WebStorm formatter (mostly adds missing braces)

* Additional formatting with WebStorm #4461

* Extracted d3pie, peity, localstorage

* Extracted options.js, fixed some issues with dependencies, wip

* Extracted boot.js

* Fixes in for loops #4461

* Removed extrtacted d3pie from main file

* Extracted registry.js

* Extracted alarms.js

* Extracted error-handling.js

* Extracted fast formatting to utils.js

* Extracted chart libraries registration code

* Extracted some js/css loading code into boot.js

* Added some info on generating dashboard.js

* Fixed issues reported by LGTM

* added slitted dashboard.js to makefiles

* Minor

* Please keep build-dashboard-js

It's useful during development, I will clean this up in the mid-term

* Moved server-detection to utils

* Extracted themes.js

* Extracted common.js

* Extracted dependencies.js

* Extracted server-detection.js

* Extracted timeout.js

* Extracted chart-registry.js

* Remove excessive requestAnimationFrame compat checks, fixes #4501

* Remove that == this #4514

* Wip, #4514

* Wip, #4514

* More that -> this conversions

* Configure LGTM to ignore web/gui/src #4515

* (x === false) -> (!x) #4461

* Cleaned up commented === false clauses

* Properly configure LGTM to ignore web/gui/src #4515

* Snake-case to camel-case #4509

* wip #4509

* Minor

* Updated Makefile.am

* Case changes, wip #4509

* Removed double underscores

* Wip #4509

* Wip #4509

* merged dashboard.js

* deleted build-dashboard-js.sh
This commit is contained in:
George Moschovitis 2018-11-08 11:37:06 +02:00 committed by Costa Tsaousis
parent d160906f3e
commit fe5646ce76
13 changed files with 1719 additions and 1724 deletions

View File

@ -18,6 +18,7 @@ path_classifiers:
- collectors/node.d.plugin/node_modules/net-snmp.js
- collectors/node.d.plugin/node_modules/pixl-xml.js
- web/gui/lib/
- web/gui/src/
- web/gui/css/
test:
- tests/

View File

@ -11,6 +11,8 @@ CLEANFILES = \
DASHBOARD_JS_FILES = \
src/dashboard.js/prologue.js.inc \
src/dashboard.js/utils.js \
src/dashboard.js/server-detection.js \
src/dashboard.js/dependencies.js \
src/dashboard.js/error-handling.js \
src/dashboard.js/compatibility.js \
src/dashboard.js/xss.js \
@ -18,6 +20,8 @@ DASHBOARD_JS_FILES = \
src/dashboard.js/units-conversion.js \
src/dashboard.js/options.js \
src/dashboard.js/localstorage.js \
src/dashboard.js/timeout.js \
src/dashboard.js/themes.js \
src/dashboard.js/charting/dygraph.js \
src/dashboard.js/charting/sparkline.js \
src/dashboard.js/charting/google-charts.js \
@ -27,6 +31,8 @@ DASHBOARD_JS_FILES = \
src/dashboard.js/charting/d3.js \
src/dashboard.js/charting/peity.js \
src/dashboard.js/charting.js \
src/dashboard.js/chart-registry.js \
src/dashboard.js/common.js \
src/dashboard.js/main.js \
src/dashboard.js/alarms.js \
src/dashboard.js/registry.js \

File diff suppressed because it is too large Load Diff

View File

@ -3760,7 +3760,7 @@
NETDATA.options.force_data_points = saveData.data_points;
NETDATA.options.fake_chart_rendering = true;
NETDATA.onscroll_updater_enabled = false;
NETDATA.abort_all_refreshes();
NETDATA.abortAllRefreshes();
var size = 0;
var info = ' Resolution: <b>' + saveSnapshotSelectedSecondsPerPoint.toString() + ((saveSnapshotSelectedSecondsPerPoint === 1)?' second ':' seconds ').toString() + 'per point</b>.';

View File

@ -0,0 +1,94 @@
// *** src/dashboard.js/chart-registry.js
// Chart Registry
// When multiple charts need the same chart, we avoid downloading it
// multiple times (and having it in browser memory multiple time)
// by using this registry.
// Every time we download a chart definition, we save it here with .add()
// Then we try to get it back with .get(). If that fails, we download it.
NETDATA.fixHost = function (host) {
while (host.slice(-1) === '/') {
host = host.substring(0, host.length - 1);
}
return host;
};
NETDATA.chartRegistry = {
charts: {},
globalReset: function () {
this.charts = {};
},
add: function (host, id, data) {
if (typeof this.charts[host] === 'undefined') {
this.charts[host] = {};
}
//console.log('added ' + host + '/' + id);
this.charts[host][id] = data;
},
get: function (host, id) {
if (typeof this.charts[host] === 'undefined') {
return null;
}
if (typeof this.charts[host][id] === 'undefined') {
return null;
}
//console.log('cached ' + host + '/' + id);
return this.charts[host][id];
},
downloadAll: function (host, callback) {
host = NETDATA.fixHost(host);
let self = this;
function got_data(h, data, callback) {
if (data !== null) {
self.charts[h] = data.charts;
// update the server timezone in our options
if (typeof data.timezone === 'string') {
NETDATA.options.server_timezone = data.timezone;
}
} else {
NETDATA.error(406, h + '/api/v1/charts');
}
if (typeof callback === 'function') {
callback(data);
}
}
if (netdataSnapshotData !== null) {
got_data(host, netdataSnapshotData.charts, callback);
} else {
$.ajax({
url: host + '/api/v1/charts',
async: true,
cache: false,
xhrFields: {withCredentials: true} // required for the cookie
})
.done(function (data) {
data = NETDATA.xss.checkOptional('/api/v1/charts', data);
got_data(host, data, callback);
})
.fail(function () {
NETDATA.error(405, host + '/api/v1/charts');
if (typeof callback === 'function') {
callback(null);
}
});
}
}
};

View File

@ -875,7 +875,7 @@ NETDATA.dygraphChartCreate = function (state, data) {
// if it didn't move, it is a selection
if (state.dygraph_last_touch_move === 0 && state.dygraph_last_touch_page_x !== 0) {
NETDATA.globalSelectionSync.dont_sync_before = 0;
NETDATA.globalSelectionSync.dontSyncBefore = 0;
NETDATA.globalSelectionSync.setMaster(state);
// internal api of dygraph

View File

@ -0,0 +1,249 @@
// Compute common (joint) values over multiple charts.
// commonMin & commonMax
NETDATA.commonMin = {
keys: {},
latest: {},
globalReset: function () {
this.keys = {};
this.latest = {};
},
get: function (state) {
if (typeof state.tmp.__commonMin === 'undefined') {
// get the commonMin setting
state.tmp.__commonMin = NETDATA.dataAttribute(state.element, 'common-min', null);
}
let min = state.data.min;
let name = state.tmp.__commonMin;
if (name === null) {
// we don't need commonMin
//state.log('no need for commonMin');
return min;
}
let t = this.keys[name];
if (typeof t === 'undefined') {
// add our commonMin
this.keys[name] = {};
t = this.keys[name];
}
let uuid = state.uuid;
if (typeof t[uuid] !== 'undefined') {
if (t[uuid] === min) {
//state.log('commonMin ' + state.tmp.__commonMin + ' not changed: ' + this.latest[name]);
return this.latest[name];
} else if (min < this.latest[name]) {
//state.log('commonMin ' + state.tmp.__commonMin + ' increased: ' + min);
t[uuid] = min;
this.latest[name] = min;
return min;
}
}
// add our min
t[uuid] = min;
// find the common min
let m = min;
// for (let i in t) {
// if (t.hasOwnProperty(i) && t[i] < m) m = t[i];
// }
for (const ti of Object.values(t)) {
if (ti < m) {
m = ti;
}
}
//state.log('commonMin ' + state.tmp.__commonMin + ' updated: ' + m);
this.latest[name] = m;
return m;
}
};
NETDATA.commonMax = {
keys: {},
latest: {},
globalReset: function () {
this.keys = {};
this.latest = {};
},
get: function (state) {
if (typeof state.tmp.__commonMax === 'undefined') {
// get the commonMax setting
state.tmp.__commonMax = NETDATA.dataAttribute(state.element, 'common-max', null);
}
let max = state.data.max;
let name = state.tmp.__commonMax;
if (name === null) {
// we don't need commonMax
//state.log('no need for commonMax');
return max;
}
let t = this.keys[name];
if (typeof t === 'undefined') {
// add our commonMax
this.keys[name] = {};
t = this.keys[name];
}
let uuid = state.uuid;
if (typeof t[uuid] !== 'undefined') {
if (t[uuid] === max) {
//state.log('commonMax ' + state.tmp.__commonMax + ' not changed: ' + this.latest[name]);
return this.latest[name];
} else if (max > this.latest[name]) {
//state.log('commonMax ' + state.tmp.__commonMax + ' increased: ' + max);
t[uuid] = max;
this.latest[name] = max;
return max;
}
}
// add our max
t[uuid] = max;
// find the common max
let m = max;
// for (let i in t) {
// if (t.hasOwnProperty(i) && t[i] > m) m = t[i];
// }
for (const ti of Object.values(t)) {
if (ti > m) {
m = ti;
}
}
//state.log('commonMax ' + state.tmp.__commonMax + ' updated: ' + m);
this.latest[name] = m;
return m;
}
};
NETDATA.commonColors = {
keys: {},
globalReset: function () {
this.keys = {};
},
get: function (state, label) {
let ret = this.refill(state);
if (typeof ret.assigned[label] === 'undefined') {
ret.assigned[label] = ret.available.shift();
}
return ret.assigned[label];
},
refill: function (state) {
let ret, len;
if (typeof state.tmp.__commonColors === 'undefined') {
ret = this.prepare(state);
} else {
ret = this.keys[state.tmp.__commonColors];
if (typeof ret === 'undefined') {
ret = this.prepare(state);
}
}
if (ret.available.length === 0) {
if (ret.copy_theme || ret.custom.length === 0) {
// copy the theme colors
len = NETDATA.themes.current.colors.length;
while (len--) {
ret.available.unshift(NETDATA.themes.current.colors[len]);
}
}
// copy the custom colors
len = ret.custom.length;
while (len--) {
ret.available.unshift(ret.custom[len]);
}
}
state.colors_assigned = ret.assigned;
state.colors_available = ret.available;
state.colors_custom = ret.custom;
return ret;
},
__read_custom_colors: function (state, ret) {
// add the user supplied colors
let c = NETDATA.dataAttribute(state.element, 'colors', undefined);
if (typeof c === 'string' && c.length > 0) {
c = c.split(' ');
let len = c.length;
if (len > 0 && c[len - 1] === 'ONLY') {
len--;
ret.copy_theme = false;
}
while (len--) {
ret.custom.unshift(c[len]);
}
}
},
prepare: function (state) {
let has_custom_colors = false;
if (typeof state.tmp.__commonColors === 'undefined') {
let defname = state.chart.context;
// if this chart has data-colors=""
// we should use the chart uuid as the default key (private palette)
// (data-common-colors="NAME" will be used anyways)
let c = NETDATA.dataAttribute(state.element, 'colors', undefined);
if (typeof c === 'string' && c.length > 0) {
defname = state.uuid;
has_custom_colors = true;
}
// get the commonColors setting
state.tmp.__commonColors = NETDATA.dataAttribute(state.element, 'common-colors', defname);
}
let name = state.tmp.__commonColors;
let ret = this.keys[name];
if (typeof ret === 'undefined') {
// add our commonMax
this.keys[name] = {
assigned: {}, // name-value of dimensions and their colors
available: [], // an array of colors available to be used
custom: [], // the array of colors defined by the user
charts: {}, // the charts linked to this
copy_theme: true
};
ret = this.keys[name];
}
if (typeof ret.charts[state.uuid] === 'undefined') {
ret.charts[state.uuid] = state;
if (has_custom_colors) {
this.__read_custom_colors(state, ret);
}
}
return ret;
}
};

View File

@ -0,0 +1,21 @@
// *** src/dashboard.js/dependencies.js
// default URLs for all the external files we need
// make them RELATIVE so that the whole thing can also be
// installed under a web server
NETDATA.jQuery = NETDATA.serverStatic + 'lib/jquery-2.2.4.min.js';
NETDATA.peity_js = NETDATA.serverStatic + 'lib/jquery.peity-3.2.0.min.js';
NETDATA.sparkline_js = NETDATA.serverStatic + 'lib/jquery.sparkline-2.1.2.min.js';
NETDATA.easypiechart_js = NETDATA.serverStatic + 'lib/jquery.easypiechart-97b5824.min.js';
NETDATA.gauge_js = NETDATA.serverStatic + 'lib/gauge-1.3.2.min.js';
NETDATA.dygraph_js = NETDATA.serverStatic + 'lib/dygraph-c91c859.min.js';
NETDATA.dygraph_smooth_js = NETDATA.serverStatic + 'lib/dygraph-smooth-plotter-c91c859.js';
// NETDATA.raphael_js = NETDATA.serverStatic + 'lib/raphael-2.2.4-min.js';
// NETDATA.c3_js = NETDATA.serverStatic + 'lib/c3-0.4.18.min.js';
// NETDATA.c3_css = NETDATA.serverStatic + 'css/c3-0.4.18.min.css';
NETDATA.d3pie_js = NETDATA.serverStatic + 'lib/d3pie-0.2.1-netdata-3.js';
NETDATA.d3_js = NETDATA.serverStatic + 'lib/d3-4.12.2.min.js';
// NETDATA.morris_js = NETDATA.serverStatic + 'lib/morris-0.5.1.min.js';
// NETDATA.morris_css = NETDATA.serverStatic + 'css/morris-0.5.1.css';
NETDATA.google_js = 'https://www.google.com/jsapi';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
// *** src/dashboard.js/server-detection.js
if (typeof netdataServer !== 'undefined') {
NETDATA.serverDefault = netdataServer;
} else {
let s = NETDATA._scriptSource();
if (s) {
NETDATA.serverDefault = s.replace(/\/dashboard.js(\?.*)?$/g, "");
} else {
console.log('WARNING: Cannot detect the URL of the netdata server.');
NETDATA.serverDefault = null;
}
}
if (NETDATA.serverDefault === null) {
NETDATA.serverDefault = '';
} else if (NETDATA.serverDefault.slice(-1) !== '/') {
NETDATA.serverDefault += '/';
}
if (typeof netdataServerStatic !== 'undefined' && netdataServerStatic !== null && netdataServerStatic !== '') {
NETDATA.serverStatic = netdataServerStatic;
if (NETDATA.serverStatic.slice(-1) !== '/') {
NETDATA.serverStatic += '/';
}
} else {
NETDATA.serverStatic = NETDATA.serverDefault;
}

View File

@ -0,0 +1,90 @@
NETDATA.themes = {
white: {
bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-3.3.7.css',
dashboard_css: NETDATA.serverStatic + 'dashboard.css?v20180210-1',
background: '#FFFFFF',
foreground: '#000000',
grid: '#F0F0F0',
axis: '#F0F0F0',
highlight: '#F5F5F5',
colors: ['#3366CC', '#DC3912', '#109618', '#FF9900', '#990099', '#DD4477',
'#3B3EAC', '#66AA00', '#0099C6', '#B82E2E', '#AAAA11', '#5574A6',
'#994499', '#22AA99', '#6633CC', '#E67300', '#316395', '#8B0707',
'#329262', '#3B3EAC'],
easypiechart_track: '#f0f0f0',
easypiechart_scale: '#dfe0e0',
gauge_pointer: '#C0C0C0',
gauge_stroke: '#F0F0F0',
gauge_gradient: false,
d3pie: {
title: '#333333',
subtitle: '#666666',
footer: '#888888',
other: '#aaaaaa',
mainlabel: '#333333',
percentage: '#dddddd',
value: '#aaaa22',
tooltip_bg: '#000000',
tooltip_fg: '#efefef',
segment_stroke: "#ffffff",
gradient_color: '#000000'
}
},
slate: {
bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1',
dashboard_css: NETDATA.serverStatic + 'dashboard.slate.css?v20180210-1',
background: '#272b30',
foreground: '#C8C8C8',
grid: '#283236',
axis: '#283236',
highlight: '#383838',
/* colors: [ '#55bb33', '#ff2222', '#0099C6', '#faa11b', '#adbce0', '#DDDD00',
'#4178ba', '#f58122', '#a5cc39', '#f58667', '#f5ef89', '#cf93c0',
'#a5d18a', '#b8539d', '#3954a3', '#c8a9cf', '#c7de8a', '#fad20a',
'#a6a479', '#a66da8' ],
*/
colors: ['#66AA00', '#FE3912', '#3366CC', '#D66300', '#0099C6', '#DDDD00',
'#5054e6', '#EE9911', '#BB44CC', '#e45757', '#ef0aef', '#CC7700',
'#22AA99', '#109618', '#905bfd', '#f54882', '#4381bf', '#ff3737',
'#329262', '#3B3EFF'],
easypiechart_track: '#373b40',
easypiechart_scale: '#373b40',
gauge_pointer: '#474b50',
gauge_stroke: '#373b40',
gauge_gradient: false,
d3pie: {
title: '#C8C8C8',
subtitle: '#283236',
footer: '#283236',
other: '#283236',
mainlabel: '#C8C8C8',
percentage: '#dddddd',
value: '#cccc44',
tooltip_bg: '#272b30',
tooltip_fg: '#C8C8C8',
segment_stroke: "#283236",
gradient_color: '#000000'
}
}
};
if (typeof netdataTheme !== 'undefined' && typeof NETDATA.themes[netdataTheme] !== 'undefined') {
NETDATA.themes.current = NETDATA.themes[netdataTheme];
} else {
NETDATA.themes.current = NETDATA.themes.white;
}
NETDATA.colors = NETDATA.themes.current.colors;
// these are the colors Google Charts are using
// we have them here to attempt emulate their look and feel on the other chart libraries
// http://there4.io/2012/05/02/google-chart-color-list/
//NETDATA.colors = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6',
// '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11',
// '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6', '#3B3EAC' ];
// an alternative set
// http://www.mulinblog.com/a-color-palette-optimized-for-data-visualization/
// (blue) (red) (orange) (green) (pink) (brown) (purple) (yellow) (gray)
//NETDATA.colors = [ '#5DA5DA', '#F15854', '#FAA43A', '#60BD68', '#F17CB0', '#B2912F', '#B276B2', '#DECF3F', '#4D4D4D' ];

View File

@ -0,0 +1,100 @@
// *** src/dashboard.js/timeout.js
// TODO: Better name needed
NETDATA.timeout = {
// by default, these are just wrappers to setTimeout() / clearTimeout()
step: function (callback) {
return window.setTimeout(callback, 1000 / 60);
},
set: function (callback, delay) {
return window.setTimeout(callback, delay);
},
clear: function (id) {
return window.clearTimeout(id);
},
init: function () {
let custom = true;
if (window.requestAnimationFrame) {
this.step = function (callback) {
return window.requestAnimationFrame(callback);
};
this.clear = function (handle) {
return window.cancelAnimationFrame(handle.value);
};
// } else if (window.webkitRequestAnimationFrame) {
// this.step = function (callback) {
// return window.webkitRequestAnimationFrame(callback);
// };
// if (window.webkitCancelAnimationFrame) {
// this.clear = function (handle) {
// return window.webkitCancelAnimationFrame(handle.value);
// };
// } else if (window.webkitCancelRequestAnimationFrame) {
// this.clear = function (handle) {
// return window.webkitCancelRequestAnimationFrame(handle.value);
// };
// }
// } else if (window.mozRequestAnimationFrame) {
// this.step = function (callback) {
// return window.mozRequestAnimationFrame(callback);
// };
// this.clear = function (handle) {
// return window.mozCancelRequestAnimationFrame(handle.value);
// };
// } else if (window.oRequestAnimationFrame) {
// this.step = function (callback) {
// return window.oRequestAnimationFrame(callback);
// };
// this.clear = function (handle) {
// return window.oCancelRequestAnimationFrame(handle.value);
// };
// } else if (window.msRequestAnimationFrame) {
// this.step = function (callback) {
// return window.msRequestAnimationFrame(callback);
// };
// this.clear = function (handle) {
// return window.msCancelRequestAnimationFrame(handle.value);
// };
} else {
custom = false;
}
if (custom) {
// we have installed custom .step() / .clear() functions
// overwrite the .set() too
this.set = function (callback, delay) {
let start = Date.now(),
handle = new Object();
const loop = () => {
let current = Date.now(),
delta = current - start;
if (delta >= delay) {
callback.call();
} else {
handle.value = this.step(loop);
}
}
handle.value = this.step(loop);
return handle;
};
}
}
};
NETDATA.timeout.init();

View File

@ -45,7 +45,7 @@ NETDATA.zeropad = function (x) {
};
NETDATA.seconds4human = function (seconds, options) {
let default_options = {
let defaultOptions = {
now: 'now',
space: ' ',
negative_suffix: 'ago',
@ -61,11 +61,11 @@ NETDATA.seconds4human = function (seconds, options) {
};
if (typeof options !== 'object') {
options = default_options;
options = defaultOptions;
} else {
for (const x in default_options) {
for (const x in defaultOptions) {
if (typeof options[x] !== 'string') {
options[x] = default_options[x];
options[x] = defaultOptions[x];
}
}
}
@ -193,15 +193,15 @@ NETDATA.dataAttributeBoolean = function (element, attribute, def) {
// fast numbers formatting
NETDATA.fastNumberFormat = {
formatters_fixed: [],
formatters_zero_based: [],
formattersFixed: [],
formattersZeroBased: [],
// this is the fastest and the preferred
getIntlNumberFormat: function (min, max) {
let key = max;
if (min === max) {
if (typeof this.formatters_fixed[key] === 'undefined') {
this.formatters_fixed[key] = new Intl.NumberFormat(undefined, {
if (typeof this.formattersFixed[key] === 'undefined') {
this.formattersFixed[key] = new Intl.NumberFormat(undefined, {
// style: 'decimal',
// minimumIntegerDigits: 1,
// minimumSignificantDigits: 1,
@ -212,10 +212,10 @@ NETDATA.fastNumberFormat = {
});
}
return this.formatters_fixed[key];
return this.formattersFixed[key];
} else if (min === 0) {
if (typeof this.formatters_zero_based[key] === 'undefined') {
this.formatters_zero_based[key] = new Intl.NumberFormat(undefined, {
if (typeof this.formattersZeroBased[key] === 'undefined') {
this.formattersZeroBased[key] = new Intl.NumberFormat(undefined, {
// style: 'decimal',
// minimumIntegerDigits: 1,
// minimumSignificantDigits: 1,
@ -226,7 +226,7 @@ NETDATA.fastNumberFormat = {
});
}
return this.formatters_zero_based[key];
return this.formattersZeroBased[key];
} else {
// this is never used
// it is added just for completeness
@ -246,8 +246,8 @@ NETDATA.fastNumberFormat = {
getLocaleString: function (min, max) {
let key = max;
if (min === max) {
if (typeof this.formatters_fixed[key] === 'undefined') {
this.formatters_fixed[key] = {
if (typeof this.formattersFixed[key] === 'undefined') {
this.formattersFixed[key] = {
format: function (value) {
return value.toLocaleString(undefined, {
// style: 'decimal',
@ -262,10 +262,10 @@ NETDATA.fastNumberFormat = {
};
}
return this.formatters_fixed[key];
return this.formattersFixed[key];
} else if (min === 0) {
if (typeof this.formatters_zero_based[key] === 'undefined') {
this.formatters_zero_based[key] = {
if (typeof this.formattersZeroBased[key] === 'undefined') {
this.formattersZeroBased[key] = {
format: function (value) {
return value.toLocaleString(undefined, {
// style: 'decimal',
@ -280,7 +280,7 @@ NETDATA.fastNumberFormat = {
};
}
return this.formatters_zero_based[key];
return this.formattersZeroBased[key];
} else {
return {
format: function (value) {
@ -302,8 +302,8 @@ NETDATA.fastNumberFormat = {
getFixed: function (min, max) {
let key = max;
if (min === max) {
if (typeof this.formatters_fixed[key] === 'undefined') {
this.formatters_fixed[key] = {
if (typeof this.formattersFixed[key] === 'undefined') {
this.formattersFixed[key] = {
format: function (value) {
if (value === 0) {
return "0";
@ -313,10 +313,10 @@ NETDATA.fastNumberFormat = {
};
}
return this.formatters_fixed[key];
return this.formattersFixed[key];
} else if (min === 0) {
if (typeof this.formatters_zero_based[key] === 'undefined') {
this.formatters_zero_based[key] = {
if (typeof this.formattersZeroBased[key] === 'undefined') {
this.formattersZeroBased[key] = {
format: function (value) {
if (value === 0) {
return "0";
@ -326,7 +326,7 @@ NETDATA.fastNumberFormat = {
};
}
return this.formatters_zero_based[key];
return this.formattersZeroBased[key];
} else {
return {
format: function (value) {
@ -394,3 +394,27 @@ NETDATA.fastNumberFormat = {
return this.get(min, max);
}
};
// ----------------------------------------------------------------------------------------------------------------
// Detect the netdata server
// http://stackoverflow.com/questions/984510/what-is-my-script-src-url
// http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
NETDATA._scriptSource = function () {
let script = null;
if (typeof document.currentScript !== 'undefined') {
script = document.currentScript;
} else {
const all_scripts = document.getElementsByTagName('script');
script = all_scripts[all_scripts.length - 1];
}
if (typeof script.getAttribute.length !== 'undefined') {
script = script.src;
} else {
script = script.getAttribute('src', -1);
}
return script;
};