summaryrefslogtreecommitdiffstats
path: root/web/gui/src/dashboard.js/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/gui/src/dashboard.js/utils.js')
-rw-r--r--web/gui/src/dashboard.js/utils.js432
1 files changed, 432 insertions, 0 deletions
diff --git a/web/gui/src/dashboard.js/utils.js b/web/gui/src/dashboard.js/utils.js
new file mode 100644
index 000000000..2d658dcc2
--- /dev/null
+++ b/web/gui/src/dashboard.js/utils.js
@@ -0,0 +1,432 @@
+// *** src/dashboard.js/utils.js
+
+NETDATA.name2id = function (s) {
+ return s
+ .replace(/ /g, '_')
+ .replace(/:/g, '_')
+ .replace(/\(/g, '_')
+ .replace(/\)/g, '_')
+ .replace(/\./g, '_')
+ .replace(/\//g, '_');
+};
+
+NETDATA.encodeURIComponent = function (s) {
+ if (typeof(s) === 'string') {
+ return encodeURIComponent(s);
+ }
+
+ return s;
+};
+
+/// A heuristic for detecting slow devices.
+let isSlowDeviceResult = undefined;
+const isSlowDevice = function () {
+ if (!isSlowDeviceResult) {
+ return isSlowDeviceResult;
+ }
+
+ try {
+ let ua = navigator.userAgent.toLowerCase();
+
+ let iOS = /ipad|iphone|ipod/.test(ua) && !window.MSStream;
+ let android = /android/.test(ua) && !window.MSStream;
+ isSlowDeviceResult = (iOS || android);
+ } catch (e) {
+ isSlowDeviceResult = false;
+ }
+
+ return isSlowDeviceResult;
+};
+
+NETDATA.guid = function () {
+ function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000)
+ .toString(16)
+ .substring(1);
+ }
+
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
+};
+
+NETDATA.zeropad = function (x) {
+ if (x > -10 && x < 10) {
+ return '0' + x.toString();
+ } else {
+ return x.toString();
+ }
+};
+
+NETDATA.seconds4human = function (seconds, options) {
+ let defaultOptions = {
+ now: 'now',
+ space: ' ',
+ negative_suffix: 'ago',
+ day: 'day',
+ days: 'days',
+ hour: 'hour',
+ hours: 'hours',
+ minute: 'min',
+ minutes: 'mins',
+ second: 'sec',
+ seconds: 'secs',
+ and: 'and'
+ };
+
+ if (typeof options !== 'object') {
+ options = defaultOptions;
+ } else {
+ for (const x in defaultOptions) {
+ if (typeof options[x] !== 'string') {
+ options[x] = defaultOptions[x];
+ }
+ }
+ }
+
+ if (typeof seconds === 'string') {
+ seconds = parseInt(seconds, 10);
+ }
+
+ if (seconds === 0) {
+ return options.now;
+ }
+
+ let suffix = '';
+ if (seconds < 0) {
+ seconds = -seconds;
+ if (options.negative_suffix !== '') {
+ suffix = options.space + options.negative_suffix;
+ }
+ }
+
+ let days = Math.floor(seconds / 86400);
+ seconds -= (days * 86400);
+
+ let hours = Math.floor(seconds / 3600);
+ seconds -= (hours * 3600);
+
+ let minutes = Math.floor(seconds / 60);
+ seconds -= (minutes * 60);
+
+ let strings = [];
+
+ if (days > 1) {
+ strings.push(days.toString() + options.space + options.days);
+ } else if (days === 1) {
+ strings.push(days.toString() + options.space + options.day);
+ }
+
+ if (hours > 1) {
+ strings.push(hours.toString() + options.space + options.hours);
+ } else if (hours === 1) {
+ strings.push(hours.toString() + options.space + options.hour);
+ }
+
+ if (minutes > 1) {
+ strings.push(minutes.toString() + options.space + options.minutes);
+ } else if (minutes === 1) {
+ strings.push(minutes.toString() + options.space + options.minute);
+ }
+
+ if (seconds > 1) {
+ strings.push(Math.floor(seconds).toString() + options.space + options.seconds);
+ } else if (seconds === 1) {
+ strings.push(Math.floor(seconds).toString() + options.space + options.second);
+ }
+
+ if (strings.length === 1) {
+ return strings.pop() + suffix;
+ }
+
+ let last = strings.pop();
+ return strings.join(", ") + " " + options.and + " " + last + suffix;
+};
+
+// ----------------------------------------------------------------------------------------------------------------
+// element data attributes
+
+NETDATA.dataAttribute = function (element, attribute, def) {
+ let key = 'data-' + attribute.toString();
+ if (element.hasAttribute(key)) {
+ let data = element.getAttribute(key);
+
+ if (data === 'true') {
+ return true;
+ }
+ if (data === 'false') {
+ return false;
+ }
+ if (data === 'null') {
+ return null;
+ }
+
+ // Only convert to a number if it doesn't change the string
+ if (data === +data + '') {
+ return +data;
+ }
+
+ if (/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/.test(data)) {
+ return JSON.parse(data);
+ }
+
+ return data;
+ } else {
+ return def;
+ }
+};
+
+NETDATA.dataAttributeBoolean = function (element, attribute, def) {
+ let value = NETDATA.dataAttribute(element, attribute, def);
+
+ if (value === true || value === false) // gmosx: Love this :)
+ {
+ return value;
+ }
+
+ if (typeof(value) === 'string') {
+ if (value === 'yes' || value === 'on') {
+ return true;
+ }
+
+ if (value === '' || value === 'no' || value === 'off' || value === 'null') {
+ return false;
+ }
+
+ return def;
+ }
+
+ if (typeof(value) === 'number') {
+ return value !== 0;
+ }
+
+ return def;
+};
+
+// ----------------------------------------------------------------------------------------------------------------
+// fast numbers formatting
+
+NETDATA.fastNumberFormat = {
+ formattersFixed: [],
+ formattersZeroBased: [],
+
+ // this is the fastest and the preferred
+ getIntlNumberFormat: function (min, max) {
+ let key = max;
+ if (min === max) {
+ if (typeof this.formattersFixed[key] === 'undefined') {
+ this.formattersFixed[key] = new Intl.NumberFormat(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+
+ return this.formattersFixed[key];
+ } else if (min === 0) {
+ if (typeof this.formattersZeroBased[key] === 'undefined') {
+ this.formattersZeroBased[key] = new Intl.NumberFormat(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+
+ return this.formattersZeroBased[key];
+ } else {
+ // this is never used
+ // it is added just for completeness
+ return new Intl.NumberFormat(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+ },
+
+ // this respects locale
+ getLocaleString: function (min, max) {
+ let key = max;
+ if (min === max) {
+ if (typeof this.formattersFixed[key] === 'undefined') {
+ this.formattersFixed[key] = {
+ format: function (value) {
+ return value.toLocaleString(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+ };
+ }
+
+ return this.formattersFixed[key];
+ } else if (min === 0) {
+ if (typeof this.formattersZeroBased[key] === 'undefined') {
+ this.formattersZeroBased[key] = {
+ format: function (value) {
+ return value.toLocaleString(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+ };
+ }
+
+ return this.formattersZeroBased[key];
+ } else {
+ return {
+ format: function (value) {
+ return value.toLocaleString(undefined, {
+ // style: 'decimal',
+ // minimumIntegerDigits: 1,
+ // minimumSignificantDigits: 1,
+ // maximumSignificantDigits: 1,
+ useGrouping: true,
+ minimumFractionDigits: min,
+ maximumFractionDigits: max
+ });
+ }
+ };
+ }
+ },
+
+ // the fallback
+ getFixed: function (min, max) {
+ let key = max;
+ if (min === max) {
+ if (typeof this.formattersFixed[key] === 'undefined') {
+ this.formattersFixed[key] = {
+ format: function (value) {
+ if (value === 0) {
+ return "0";
+ }
+ return value.toFixed(max);
+ }
+ };
+ }
+
+ return this.formattersFixed[key];
+ } else if (min === 0) {
+ if (typeof this.formattersZeroBased[key] === 'undefined') {
+ this.formattersZeroBased[key] = {
+ format: function (value) {
+ if (value === 0) {
+ return "0";
+ }
+ return value.toFixed(max);
+ }
+ };
+ }
+
+ return this.formattersZeroBased[key];
+ } else {
+ return {
+ format: function (value) {
+ if (value === 0) {
+ return "0";
+ }
+ return value.toFixed(max);
+ }
+ };
+ }
+ },
+
+ testIntlNumberFormat: function () {
+ let value = 1.12345;
+ let e1 = "1.12", e2 = "1,12";
+ let s = "";
+
+ try {
+ let x = new Intl.NumberFormat(undefined, {
+ useGrouping: true,
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2
+ });
+
+ s = x.format(value);
+ } catch (e) {
+ s = "";
+ }
+
+ // console.log('NumberFormat: ', s);
+ return (s === e1 || s === e2);
+ },
+
+ testLocaleString: function () {
+ let value = 1.12345;
+ let e1 = "1.12", e2 = "1,12";
+ let s = "";
+
+ try {
+ s = value.toLocaleString(undefined, {
+ useGrouping: true,
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2
+ });
+ } catch (e) {
+ s = "";
+ }
+
+ // console.log('localeString: ', s);
+ return (s === e1 || s === e2);
+ },
+
+ // on first run we decide which formatter to use
+ get: function (min, max) {
+ if (this.testIntlNumberFormat()) {
+ // console.log('numberformat');
+ this.get = this.getIntlNumberFormat;
+ } else if (this.testLocaleString()) {
+ // console.log('localestring');
+ this.get = this.getLocaleString;
+ } else {
+ // console.log('fixed');
+ this.get = this.getFixed;
+ }
+ 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;
+};