// netdata server already.
// var netdataServer = "http://yourhost:19999"; // set your NetData server
-//(function(window, document, undefined) {
+// global namespace
+var NETDATA = window.NETDATA || {};
+(function(window, document) {
// ------------------------------------------------------------------------
// compatibility fixes
};
}
- // global namespace
- var NETDATA = window.NETDATA || {};
-
NETDATA.name2id = function(s) {
return s
.replace(/ /g, '_')
NETDATA.themes = {
white: {
bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-3.3.7.css',
- dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20161002-1',
+ dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20161229-2',
background: '#FFFFFF',
foreground: '#000000',
grid: '#F0F0F0',
gauge_gradient: false
},
slate: {
- bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-slate-flat-3.3.7.css?v20161218-2',
- dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20161218-1',
+ bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1',
+ dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20161229-2',
background: '#272b30',
foreground: '#C8C8C8',
grid: '#283236',
if(typeof netdataRegistry === 'undefined') {
// backward compatibility
- if(typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry === false)
- netdataRegistry = true;
- else
- netdataRegistry = false;
+ netdataRegistry = (typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry === false);
}
if(netdataRegistry === false && typeof netdataRegistryCallback === 'function')
netdataRegistry = true;
async_on_scroll: false, // sync/async onscroll handler
onscroll_worker_duration_threshold: 30, // time in ms, to consider slow the onscroll handler
- setOptionCallback: function() { ; }
+ retries_on_data_failures: 3, // how many retries to make if we can't fetch chart data from the server
+
+ setOptionCallback: function() { }
},
debug: {
focus: false,
visibility: false,
chart_data_url: false,
- chart_errors: false, // FIXME
+ chart_errors: false, // FIXME: remember to set it to false before merging
chart_timing: false,
chart_calls: false,
libraries: false,
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;
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());
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));
};
NETDATA.localStorageGetRecursive = function(obj, prefix, callback) {
- for(var i in obj) {
+ var keys = Object.keys(obj);
+ var len = keys.length;
+ while(len--) {
+ var i = keys[len];
+
if(typeof obj[i] === 'object') {
//console.log('object ' + prefix + '.' + i.toString());
NETDATA.localStorageGetRecursive(obj[i], prefix + '.' + i.toString(), callback);
NETDATA.setOption('stop_updates_when_focus_is_lost', true);
NETDATA.resetOptions = function() {
- for(var i in NETDATA.localStorage.default) {
+ var keys = Object.keys(NETDATA.localStorage.default);
+ var len = keys.length;
+ while(len--) {
+ var i = keys[len];
var a = i.split('.');
if(a[0] === 'options') {
}
}
}
- }
+ };
// ----------------------------------------------------------------------------------------------------------------
if(NETDATA.options.debug.main_loop === true)
console.log('welcome to NETDATA');
+ NETDATA.onresizeCallback = null;
NETDATA.onresize = function() {
NETDATA.options.last_resized = Date.now();
NETDATA.onscroll();
+
+ if(typeof NETDATA.onresizeCallback === 'function')
+ NETDATA.onresizeCallback();
};
NETDATA.onscroll_updater_count = 0;
// 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: {},
},
downloadAll: function(host, callback) {
- while(host.slice(-1) === '/')
- host = host.substring(0, host.length - 1);
+ host = NETDATA.fixHost(host);
var self = this;
else NETDATA.error(406, host + '/api/v1/charts');
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(405, host + '/api/v1/charts');
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
}
};
dimensionStatus.prototype.setOptions = function(name_div, value_div, color) {
this.color = color;
- if(this.name_div != name_div) {
+ if(this.name_div !== name_div) {
this.name_div = name_div;
this.name_div.title = this.label;
this.name_div.style.color = this.color;
this.name_div.className = 'netdata-legend-name selected';
}
- if(this.value_div != value_div) {
+ if(this.value_div !== value_div) {
this.value_div = value_div;
this.value_div.title = this.label;
this.value_div.style.color = this.color;
};
dimensionsVisibility.prototype.invalidateAll = function() {
- for(var d in this.dimensions)
- this.dimensions[d].invalidate();
+ var keys = Object.keys(this.dimensions);
+ var len = keys.length;
+ while(len--)
+ this.dimensions[keys[len]].invalidate();
};
dimensionsVisibility.prototype.selectAll = function() {
- for(var d in this.dimensions)
- this.dimensions[d].select();
+ var keys = Object.keys(this.dimensions);
+ var len = keys.length;
+ while(len--)
+ this.dimensions[keys[len]].select();
};
dimensionsVisibility.prototype.countSelected = function() {
- var i = 0;
- for(var d in this.dimensions)
- if(this.dimensions[d].isSelected()) i++;
+ var selected = 0;
+ var keys = Object.keys(this.dimensions);
+ var len = keys.length;
+ while(len--)
+ if(this.dimensions[keys[len]].isSelected()) selected++;
- return i;
+ return selected;
};
dimensionsVisibility.prototype.selectNone = function() {
- for(var d in this.dimensions)
- this.dimensions[d].unselect();
+ var keys = Object.keys(this.dimensions);
+ var len = keys.length;
+ while(len--)
+ this.dimensions[keys[len]].unselect();
};
dimensionsVisibility.prototype.selected2BooleanArray = function(array) {
// the user given dimensions of the element
this.width = self.data('width') || NETDATA.chartDefaults.width;
this.height = self.data('height') || NETDATA.chartDefaults.height;
+ this.height_original = this.height;
if(this.settings_id !== null) {
this.height = NETDATA.localStorageGet('chart_heights.' + this.settings_id, this.height, function(height) {
// the chart library requested by the user
this.library_name = self.data('chart-library') || NETDATA.chartDefaults.library;
+ // how many retries we have made to load chart data from the server
+ this.retries_on_data_failures = 0;
+
// object - the chart library used
this.library = null;
title_date: null,
title_time: null,
title_units: null,
- nano: null,
- nano_options: null,
+ perfect_scroller: null, // the container to apply perfect scroller to
series: null
};
this.view_before = 0;
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;
- }
+ var d = self.data('decimal-digits');
+ if(typeof d === 'number') {
+ this.value_decimal_detail = 1;
+ while(d-- > 0)
+ this.value_decimal_detail *= 10;
}
this.auto = {
that.element.innerHTML = '';
that.element_message = document.createElement('div');
- that.element_message.className = ' netdata-message hidden';
+ that.element_message.className = 'netdata-message icon hidden';
that.element.appendChild(that.element_message);
that.element_chart = document.createElement('div');
if(typeof(that.library.aspect_ratio) === 'undefined') {
if(typeof(that.height) === 'string')
- $(that.element).css('height', that.height);
+ that.element.style.height = that.height;
else if(typeof(that.height) === 'number')
- $(that.element).css('height', that.height + 'px');
+ that.element.style.height = that.height.toString() + 'px';
}
else {
var w = that.element.offsetWidth;
that.tm.last_resized = 0;
}
else
- $(that.element).css('height', (that.element.offsetWidth * that.library.aspect_ratio / 100).toString() + 'px');
+ that.element.style.height = (w * that.library.aspect_ratio / 100).toString() + 'px';
}
if(NETDATA.chartDefaults.min_width !== null)
};
var maxMessageFontSize = function() {
+ var screenHeight = screen.height;
+ var el = that.element;
+
// normally we want a font size, as tall as the element
- var h = that.element_message.clientHeight;
+ var h = el.clientHeight;
// but give it some air, 20% let's say, or 5 pixels min
var lost = Math.max(h * 0.2, 5);
// but check the width too
// it should fit 10 characters in it
- var w = that.element_message.clientWidth / 10;
+ var w = el.clientWidth / 10;
if(h > w) {
paddingTop += (h - w) / 2;
h = w;
// and don't make it too huge
// 5% of the screen size is good
- if(h > screen.height / 20) {
- paddingTop += (h - (screen.height / 20)) / 2;
- h = screen.height / 20;
+ if(h > screenHeight / 20) {
+ paddingTop += (h - (screenHeight / 20)) / 2;
+ h = screenHeight / 20;
}
// set it
that.element_message.style.paddingTop = paddingTop.toString() + 'px';
};
- var showMessage = function(msg) {
- that.element_message.className = 'netdata-message';
- that.element_message.innerHTML = msg;
- that.element_message.style.fontSize = 'x-small';
- that.element_message.style.paddingTop = '0px';
- that.___messageHidden___ = undefined;
- };
-
var showMessageIcon = function(icon) {
that.element_message.innerHTML = icon;
- that.element_message.className = 'netdata-message icon';
maxMessageFontSize();
+ $(that.element_message).removeClass('hidden');
that.___messageHidden___ = undefined;
};
var hideMessage = function() {
if(typeof that.___messageHidden___ === 'undefined') {
that.___messageHidden___ = true;
- that.element_message.className = 'netdata-message hidden';
+ $(that.element_message).addClass('hidden');
}
};
else if(typeof that.library.resize === 'function') {
that.library.resize(that);
- if(that.element_legend_childs.nano !== null && that.element_legend_childs.nano_options !== null)
- $(that.element_legend_childs.nano).nanoScroller();
+ if(that.element_legend_childs.perfect_scroller !== null)
+ Ps.update(that.element_legend_childs.perfect_scroller);
maxMessageFontSize();
}
this.event_resize.chart_last_h = this.element.clientHeight;
var now = Date.now();
- if(now - this.event_resize.last <= NETDATA.options.current.double_click_speed) {
+ if(now - this.event_resize.last <= NETDATA.options.current.double_click_speed && this.element_legend_childs.perfect_scroller !== null) {
// double click / double tap event
+ // console.dir(this.element_legend_childs.content);
+ // console.dir(this.element_legend_childs.perfect_scroller);
+
// the optimal height of the chart
// showing the entire legend
var optimal = this.event_resize.chart_last_h
- + this.element_legend_childs.content.scrollHeight
- - this.element_legend_childs.content.clientHeight;
+ + this.element_legend_childs.perfect_scroller.scrollHeight
+ - this.element_legend_childs.perfect_scroller.clientHeight;
// if we are not optimal, be optimal
- if(this.event_resize.chart_last_h != optimal)
+ if(this.event_resize.chart_last_h !== optimal) {
+ // this.log('resize to optimal, current = ' + this.event_resize.chart_last_h.toString() + 'px, original = ' + this.event_resize.chart_original_h.toString() + 'px, optimal = ' + optimal.toString() + 'px, internal = ' + this.height_original.toString());
resizeChartToHeight(optimal.toString() + 'px');
+ }
- // else if we do not have the original height
- // reset to the original height
- else if(this.event_resize.chart_last_h != this.event_resize.chart_original_h)
+ // else if the current height is not the original/saved height
+ // reset to the original/saved height
+ else if(this.event_resize.chart_last_h !== this.event_resize.chart_original_h) {
+ // this.log('resize to original, current = ' + this.event_resize.chart_last_h.toString() + 'px, original = ' + this.event_resize.chart_original_h.toString() + 'px, optimal = ' + optimal.toString() + 'px, internal = ' + this.height_original.toString());
resizeChartToHeight(this.event_resize.chart_original_h.toString() + 'px');
+ }
+
+ // else if the current height is not the internal default height
+ // reset to the internal default height
+ else if((this.event_resize.chart_last_h.toString() + 'px') !== this.height_original) {
+ // this.log('resize to internal default, current = ' + this.event_resize.chart_last_h.toString() + 'px, original = ' + this.event_resize.chart_original_h.toString() + 'px, optimal = ' + optimal.toString() + 'px, internal = ' + this.height_original.toString());
+ resizeChartToHeight(this.height_original.toString());
+ }
+
+ // else if the current height is not the firstchild's clientheight
+ // resize to it
+ else if(typeof this.element_legend_childs.perfect_scroller.firstChild !== 'undefined') {
+ var parent_rect = this.element.getBoundingClientRect();
+ var content_rect = this.element_legend_childs.perfect_scroller.firstElementChild.getBoundingClientRect();
+ var wanted = content_rect.top - parent_rect.top + this.element_legend_childs.perfect_scroller.firstChild.clientHeight + 18; // 15 = toolbox + 3 space
+
+ // console.log(parent_rect);
+ // console.log(content_rect);
+ // console.log(wanted);
+
+ // this.log('resize to firstChild, current = ' + this.event_resize.chart_last_h.toString() + 'px, original = ' + this.event_resize.chart_original_h.toString() + 'px, optimal = ' + optimal.toString() + 'px, internal = ' + this.height_original.toString() + 'px, firstChild = ' + wanted.toString() + 'px' );
+ if(this.event_resize.chart_last_h !== wanted)
+ resizeChartToHeight(wanted.toString() + 'px');
+ }
}
else {
this.event_resize.last = now;
};
this.globalSelectionSyncIsMaster = function() {
- if(NETDATA.globalSelectionSync.state === this)
- return true;
- else
- return false;
+ return (NETDATA.globalSelectionSync.state === this);
};
// this chart is the master of the global selection sync
// sync all the visible charts to the given time
// this is to be called from the chart libraries
this.globalSelectionSync = function(t) {
- if(this.globalSelectionSyncAbility() === false) {
- if(this.debug === true)
- this.log('sync: cannot sync (yet?).');
-
+ if(this.globalSelectionSyncAbility() === false)
return;
- }
if(this.globalSelectionSyncIsMaster() === false) {
if(this.debug === true)
this.globalSelectionSyncBeMaster();
- if(this.globalSelectionSyncAbility() === false) {
- if(this.debug === true)
- this.log('sync: cannot sync (yet?).');
-
+ if(this.globalSelectionSyncAbility() === false)
return;
- }
}
NETDATA.globalSelectionSync.last_t = t;
if(typeof series === 'undefined') return;
if(series.value === null && series.user === null) return;
+ /*
+ // this slows down firefox and edge significantly
+ // since it requires to use innerHTML(), instead of innerText()
+
// if the value has not changed, skip DOM update
//if(series.last === value) return;
else s += '<i class="fa fa-angle-left" style="width: 8px; text-align: center; overflow: hidden; vertical-align: middle;"></i>';
}
else s += '<i class="fa fa-angle-right" style="width: 8px; text-align: center; overflow: hidden; vertical-align: middle;"></i>';
+
series.last = v;
}
else {
- s = r = value;
+ if(value === null)
+ s = r = '';
+ else
+ s = r = value;
+
series.last = value;
}
+ */
- if(series.value !== null) series.value.innerHTML = s;
- if(series.user !== null) series.user.innerHTML = r;
+ var s = this.legendFormatValue(value);
+
+ // caching: do not update the update to show the same value again
+ if(s === series.last_shown_value) return;
+ series.last_shown_value = s;
+
+ if(series.value !== null) series.value.innerText = s;
+ if(series.user !== null) series.user.innerText = s;
+ };
+
+ this.__legendSetDateString = function(date) {
+ if(date !== this.__last_shown_legend_date) {
+ this.element_legend_childs.title_date.innerText = date;
+ this.__last_shown_legend_date = date;
+ }
+ };
+
+ this.__legendSetTimeString = function(time) {
+ if(time !== this.__last_shown_legend_time) {
+ this.element_legend_childs.title_time.innerText = time;
+ this.__last_shown_legend_time = time;
+ }
+ };
+
+ this.__legendSetUnitsString = function(units) {
+ if(units !== this.__last_shown_legend_units) {
+ this.element_legend_childs.title_units.innerText = units;
+ this.__last_shown_legend_units = units;
+ }
};
this.legendSetDate = function(ms) {
var d = new Date(ms);
if(this.element_legend_childs.title_date)
- this.element_legend_childs.title_date.innerHTML = d.toLocaleDateString();
+ this.__legendSetDateString(d.toLocaleDateString());
if(this.element_legend_childs.title_time)
- this.element_legend_childs.title_time.innerHTML = d.toLocaleTimeString();
+ this.__legendSetTimeString(d.toLocaleTimeString());
if(this.element_legend_childs.title_units)
- this.element_legend_childs.title_units.innerHTML = this.units;
+ this.__legendSetUnitsString(this.units)
};
this.legendShowUndefined = function() {
if(this.element_legend_childs.title_date)
- this.element_legend_childs.title_date.innerHTML = ' ';
+ this.__legendSetDateString(' ');
if(this.element_legend_childs.title_time)
- this.element_legend_childs.title_time.innerHTML = this.chart.name;
+ this.__legendSetTimeString(this.chart.name);
if(this.element_legend_childs.title_units)
- this.element_legend_childs.title_units.innerHTML = ' ';
+ this.__legendSetUnitsString(' ')
if(this.data && this.element_legend_childs.series !== null) {
var labels = this.data.dimension_names;
};
this.legendUpdateDOM = function() {
- var needed = false;
+ var needed = false, dim, keys, len, i;
// check that the legend DOM is up to date for the downloaded dimensions
if(typeof this.element_legend_childs.series !== 'object' || this.element_legend_childs.series === null) {
if(this.colors === null) {
// this is the first time we update the chart
// let's assign colors to all dimensions
- if(this.library.track_colors() === true)
- for(var dim in this.chart.dimensions)
- this._chartDimensionColor(this.chart.dimensions[dim].name);
+ if(this.library.track_colors() === true) {
+ keys = Object.keys(this.chart.dimensions);
+ len = keys.length;
+ for(i = 0; i < len ;i++)
+ this._chartDimensionColor(this.chart.dimensions[keys[i]].name);
+ }
}
// we will re-generate the colors for the chart
// based on the selected dimensions
name: document.createElement('span'),
value: document.createElement('span'),
user: user_element,
- last: null
+ last: null,
+ last_shown_value: null
};
var label = state.element_legend_childs.series[name];
title_date: document.createElement('span'),
title_time: document.createElement('span'),
title_units: document.createElement('span'),
- nano: document.createElement('div'),
- nano_options: {
- paneClass: 'netdata-legend-series-pane',
- sliderClass: 'netdata-legend-series-slider',
- contentClass: 'netdata-legend-series-content',
- enabledClass: '__enabled',
- flashedClass: '__flashed',
- activeClass: '__active',
- tabIndex: -1,
- alwaysVisible: true,
- sliderMinHeight: 10
- },
+ perfect_scroller: document.createElement('div'),
series: {}
};
if(this.library.toolboxPanAndZoom !== null) {
- function get_pan_and_zoom_step(event) {
+ var get_pan_and_zoom_step = function(event) {
if (event.ctrlKey)
return NETDATA.options.current.pan_and_zoom_factor * NETDATA.options.current.pan_and_zoom_factor_multiplier_control;
else
return NETDATA.options.current.pan_and_zoom_factor;
- }
+ };
this.element_legend_childs.toolbox.className += ' netdata-legend-toolbox';
this.element.appendChild(this.element_legend_childs.toolbox);
this.element_legend.appendChild(document.createElement('br'));
- this.element_legend_childs.nano.className = 'netdata-legend-series';
- this.element_legend.appendChild(this.element_legend_childs.nano);
+ this.element_legend_childs.perfect_scroller.className = 'netdata-legend-series';
+ this.element_legend.appendChild(this.element_legend_childs.perfect_scroller);
content.className = 'netdata-legend-series-content';
- this.element_legend_childs.nano.appendChild(content);
+ this.element_legend_childs.perfect_scroller.appendChild(content);
if(NETDATA.options.current.show_help === true)
$(content).popover({
title_date: null,
title_time: null,
title_units: null,
- nano: null,
- nano_options: null,
+ perfect_scroller: null,
series: {}
};
}
if(this.debug === true)
this.log('labels from data: "' + this.element_legend_childs.series.labels_key + '"');
- for(var i = 0, len = this.data.dimension_names.length; i < len ;i++) {
+ for(i = 0, len = this.data.dimension_names.length; i < len ;i++) {
genLabel(this, content, this.data.dimension_ids[i], this.data.dimension_names[i], i);
}
}
else {
var tmp = new Array();
- for(var dim in this.chart.dimensions) {
+ keys = Object.keys(this.chart.dimensions);
+ for(i = 0, len = keys.length; i < len ;i++) {
+ dim = keys[i];
tmp.push(this.chart.dimensions[dim].name);
genLabel(this, content, dim, this.chart.dimensions[dim].name, i);
}
this.element_legend_childs.hidden = document.createElement('div');
el.appendChild(this.element_legend_childs.hidden);
- if(this.element_legend_childs.nano !== null && this.element_legend_childs.nano_options !== null)
- $(this.element_legend_childs.nano).nanoScroller(this.element_legend_childs.nano_options);
+ if(this.element_legend_childs.perfect_scroller !== null) {
+ Ps.initialize(this.element_legend_childs.perfect_scroller, {
+ wheelSpeed: 0.2,
+ wheelPropagation: true,
+ swipePropagation: true,
+ minScrollbarLength: null,
+ maxScrollbarLength: null,
+ useBothWheelAxes: false,
+ suppressScrollX: true,
+ suppressScrollY: false,
+ scrollXMarginOffset: 0,
+ scrollYMarginOffset: 0,
+ theme: 'default'
+ });
+ Ps.update(this.element_legend_childs.perfect_scroller);
+ }
this.legendShowLatestValues();
};
NETDATA.options.auto_refresher_fast_weight += this.refresh_dt_ms;
if(this.refresh_dt_element !== null)
- this.refresh_dt_element.innerHTML = this.refresh_dt_ms.toString();
+ this.refresh_dt_element.innerText = this.refresh_dt_ms.toString();
};
this.updateChart = function(callback) {
if(this.debug === true)
this.log('I am already updating...');
- if(typeof callback === 'function') callback();
- return false;
+ if(typeof callback === 'function')
+ return callback();
+
+ return;
}
// due to late initialization of charts and libraries
if(this.debug === true)
this.log('I am not enabled');
- if(typeof callback === 'function') callback();
- return false;
+ if(typeof callback === 'function')
+ return callback();
+
+ return;
}
if(canBeRendered() === false) {
- if(typeof callback === 'function') callback();
- return false;
- }
+ if(typeof callback === 'function')
+ return callback();
- if(this.chart === null) {
- this.getChart(function() { that.updateChart(callback); });
- return false;
+ return;
}
+ if(this.chart === null)
+ return this.getChart(function() {
+ return that.updateChart(callback);
+ });
+
if(this.library.initialized === false) {
if(this.library.enabled === true) {
- this.library.initialize(function() { that.updateChart(callback); });
- return false;
+ return this.library.initialize(function () {
+ return that.updateChart(callback);
+ });
}
else {
error('chart library "' + this.library_name + '" is not available.');
- if(typeof callback === 'function') callback();
- return false;
+
+ if(typeof callback === 'function')
+ return callback();
+
+ return;
}
}
})
.done(function(data) {
that.xhr = undefined;
+ that.retries_on_data_failures = 0;
if(that.debug === true)
that.log('data received. updating chart.');
.fail(function(msg) {
that.xhr = undefined;
- if(msg.statusText !== 'abort')
- error('data download failed for url: ' + that.data_url);
+ if(msg.statusText !== 'abort') {
+ that.retries_on_data_failures++;
+ if(that.retries_on_data_failures > NETDATA.options.current.retries_on_data_failures) {
+ // that.log('failed ' + that.retries_on_data_failures.toString() + ' times - giving up');
+ that.retries_on_data_failures = 0;
+ error('data download failed for url: ' + that.data_url);
+ }
+ else {
+ that.tm.last_autorefreshed = Date.now();
+ // that.log('failed ' + that.retries_on_data_failures.toString() + ' times, but I will retry');
+ }
+ }
})
.always(function() {
that.xhr = undefined;
NETDATA.statistics.refreshes_active--;
that._updating = false;
- if(typeof callback === 'function') callback();
- });
- return true;
+ if(typeof callback === 'function')
+ return callback();
+ });
};
this.isVisible = function(nocache) {
state.running = false;
if(typeof callback !== 'undefined')
- callback();
+ return callback();
});
}
else {
if(typeof callback !== 'undefined')
- callback();
+ return callback();
}
};
this.chart = NETDATA.chartRegistry.get(this.host, this.id);
if(this.chart) {
this._defaultsFromDownloadedChart(this.chart);
- if(typeof callback === 'function') callback();
+
+ if(typeof callback === 'function')
+ return callback();
}
else {
this.chart_url = "/api/v1/chart?chart=" + this.id;
error('chart not found on url "' + that.chart_url + '"');
})
.always(function() {
- if(typeof callback === 'function') callback();
+ if(typeof callback === 'function')
+ return callback();
});
}
};
script.src = NETDATA.jQuery;
// script.onabort = onError;
- script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
+ script.onerror = function() { NETDATA.error(101, NETDATA.jQuery); };
if(typeof callback === "function")
script.onload = callback;
s.parentNode.insertBefore(script, s);
}
else if(typeof callback === "function")
- callback();
+ return callback();
};
NETDATA._loadCSS = function(filename) {
};
NETDATA.pause = function(callback) {
- if(NETDATA.options.pause === true)
- callback();
- else
- NETDATA.options.pauseCallback = callback;
+ if(typeof callback === 'function') {
+ if (NETDATA.options.pause === true)
+ return callback();
+ else
+ NETDATA.options.pauseCallback = callback;
+ }
};
NETDATA.unpause = function() {
NETDATA.options.targets.push(NETDATA.chartState(targets[len]));
}
- if(typeof callback === 'function') callback();
+ if(typeof callback === 'function')
+ return callback();
};
// this is the main function - where everything starts
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.peity.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.sparkline.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
var self = $(state.element);
var type = self.data('sparkline-type') || 'line';
var lineColor = self.data('sparkline-linecolor') || state.chartColors()[0];
- var fillColor = self.data('sparkline-fillcolor') || (state.chart.chart_type === 'line')?NETDATA.themes.current.background:NETDATA.colorLuminance(lineColor, NETDATA.chartDefaults.fill_luminance);
+ var fillColor = self.data('sparkline-fillcolor') || ((state.chart.chart_type === 'line')?NETDATA.themes.current.background:NETDATA.colorLuminance(lineColor, NETDATA.chartDefaults.fill_luminance));
var chartRangeMin = self.data('sparkline-chartrangemin') || undefined;
var chartRangeMax = self.data('sparkline-chartrangemax') || undefined;
var composite = self.data('sparkline-composite') || undefined;
if(minSpotColor === 'disable') minSpotColor='';
if(maxSpotColor === 'disable') maxSpotColor='';
+ // state.log('sparkline type ' + type + ', lineColor: ' + lineColor + ', fillColor: ' + fillColor);
+
state.sparkline_options = {
type: type,
lineColor: lineColor,
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
};
if(NETDATA.chartLibraries.dygraph.enabled === true && NETDATA.options.current.smooth_plot === true)
NETDATA.dygraphSmoothInitialize(callback);
else if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.dygraph.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
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,
+ 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,
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();
- // return NETDATA.zeropad(d.getHours()) + ":" + NETDATA.zeropad(d.getMinutes()) + ":" + NETDATA.zeropad(d.getSeconds());
+ //var d = new Date(ms);
+ //return d.toLocaleDateString() + ' ' + d.toLocaleTimeString();
+
+ // no need to return anything here
+ return ' ';
+
}
},
y: {
var i = data.series.length;
while(i--) {
var series = data.series[i];
- if(!series.isVisible) continue;
- state.legendSetLabelValue(series.label, series.y);
+ if(series.isVisible === true)
+ state.legendSetLabelValue(series.label, series.y);
+ else
+ state.legendSetLabelValue(series.label, null);
}
}
// http://dygraphs.com/gallery/interaction-api.js
var normal_def;
- if(typeof event.wheelDelta === 'number' && event.wheelDelta != NaN)
+ if(typeof event.wheelDelta === 'number' && !isNaN(event.wheelDelta))
// chrome
normal_def = event.wheelDelta / 40;
else
else {
NETDATA.chartLibraries.morris.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
}
else {
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
}
else {
NETDATA.chartLibraries.morris.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.raphael.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
else {
NETDATA.chartLibraries.c3.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
}
else {
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
}
else {
NETDATA.chartLibraries.c3.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.d3.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
NETDATA.chartLibraries.google.enabled = false;
NETDATA.error(100, NETDATA.google_js);
if(typeof callback === "function")
- callback();
+ return callback();
});
}
else {
NETDATA.chartLibraries.google.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
// ----------------------------------------------------------------------------------------------------------------
- NETDATA.percentFromValueMinMax = function(value, min, max) {
+ NETDATA.easypiechartPercentFromValueMinMax = function(value, min, max) {
if(typeof value !== 'number') value = 0;
if(typeof min !== 'number') min = 0;
if(typeof max !== 'number') max = 0;
+ if(min > value) min = value;
+ if(max < value) max = value;
+
+ // make sure it is zero based
+ if(min > 0) min = 0;
+ if(max < 0) max = 0;
+
var pcent = 0;
if(value >= 0) {
- if(max < value) max = value;
- if(max !== 0) {
+ if(max !== 0)
pcent = Math.round(value * 100 / max);
- if(pcent === 0 && value > 0) pcent = 1;
- }
+ if(pcent === 0) pcent = 0.1;
}
else {
- if(min > value) min = value;
- if(min !== 0) {
+ if(min !== 0)
pcent = Math.round(-value * 100 / min);
- if(pcent === 0 && value < 0) pcent = -1;
- }
+ if(pcent === 0) pcent = -0.1;
}
return pcent;
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
})
}
else {
NETDATA.chartLibraries.easypiechart.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
NETDATA.easypiechartChartUpdate(state, state.data);
}
else {
- state.easyPieChartLabel.innerHTML = state.legendFormatValue(null);
+ state.easyPieChartLabel.innerText = state.legendFormatValue(null);
state.easyPieChart_instance.update(0);
}
state.easyPieChart_instance.enableAnimation();
var value = state.data.result[state.data.result.length - 1 - slot];
var min = (state.easyPieChartMin === null)?NETDATA.commonMin.get(state):state.easyPieChartMin;
var max = (state.easyPieChartMax === null)?NETDATA.commonMax.get(state):state.easyPieChartMax;
- var pcent = NETDATA.percentFromValueMinMax(value, min, max);
+ var pcent = NETDATA.easypiechartPercentFromValueMinMax(value, min, max);
state.easyPieChartEvent.value = value;
state.easyPieChartEvent.pcent = pcent;
- state.easyPieChartLabel.innerHTML = state.legendFormatValue(value);
+ state.easyPieChartLabel.innerText = state.legendFormatValue(value);
if(state.easyPieChartEvent.timer === null) {
state.easyPieChart_instance.disableAnimation();
value = data.result[0];
min = (state.easyPieChartMin === null)?NETDATA.commonMin.get(state):state.easyPieChartMin;
max = (state.easyPieChartMax === null)?NETDATA.commonMax.get(state):state.easyPieChartMax;
- pcent = NETDATA.percentFromValueMinMax(value, min, max);
+ pcent = NETDATA.easypiechartPercentFromValueMinMax(value, min, max);
}
- state.easyPieChartLabel.innerHTML = state.legendFormatValue(value);
+ state.easyPieChartLabel.innerText = state.legendFormatValue(value);
state.easyPieChart_instance.update(pcent);
return true;
};
else
state.easyPieChartMax = max;
- var pcent = NETDATA.percentFromValueMinMax(value, min, max);
+ var pcent = NETDATA.easypiechartPercentFromValueMinMax(value, min, max);
chart.data('data-percent', pcent);
var valuetop = Math.round((size - valuefontsize - (size / 40)) / 2);
state.easyPieChartLabel = document.createElement('span');
state.easyPieChartLabel.className = 'easyPieChartLabel';
- state.easyPieChartLabel.innerHTML = state.legendFormatValue(value);
+ state.easyPieChartLabel.innerText = state.legendFormatValue(value);
state.easyPieChartLabel.style.fontSize = valuefontsize + 'px';
state.easyPieChartLabel.style.top = valuetop.toString() + 'px';
state.element_chart.appendChild(state.easyPieChartLabel);
var titletop = Math.round(valuetop - (titlefontsize * 2) - (size / 40));
state.easyPieChartTitle = document.createElement('span');
state.easyPieChartTitle.className = 'easyPieChartTitle';
- state.easyPieChartTitle.innerHTML = state.title;
+ state.easyPieChartTitle.innerText = state.title;
state.easyPieChartTitle.style.fontSize = titlefontsize + 'px';
state.easyPieChartTitle.style.lineHeight = titlefontsize + 'px';
state.easyPieChartTitle.style.top = titletop.toString() + 'px';
var unittop = Math.round(valuetop + (valuefontsize + unitfontsize) + (size / 40));
state.easyPieChartUnits = document.createElement('span');
state.easyPieChartUnits.className = 'easyPieChartUnits';
- state.easyPieChartUnits.innerHTML = state.units;
+ state.easyPieChartUnits.innerText = state.units;
state.easyPieChartUnits.style.fontSize = unitfontsize + 'px';
state.easyPieChartUnits.style.top = unittop.toString() + 'px';
state.element_chart.appendChild(state.easyPieChartUnits);
})
.always(function() {
if(typeof callback === "function")
- callback();
+ return callback();
})
}
else {
NETDATA.chartLibraries.gauge.enabled = false;
if(typeof callback === "function")
- callback();
+ return callback();
}
};
min = max;
max = t;
}
- else if(min == max)
+ else if(min === max)
max = min + 1;
// gauge.js has an issue if the needle
NETDATA.gaugeSetLabels = function(state, value, min, max) {
if(state.___gaugeOld__.valueLabel !== value) {
state.___gaugeOld__.valueLabel = value;
- state.gaugeChartLabel.innerHTML = state.legendFormatValue(value);
+ state.gaugeChartLabel.innerText = state.legendFormatValue(value);
}
if(state.___gaugeOld__.minLabel !== min) {
state.___gaugeOld__.minLabel = min;
- state.gaugeChartMin.innerHTML = state.legendFormatValue(min);
+ state.gaugeChartMin.innerText = state.legendFormatValue(min);
}
if(state.___gaugeOld__.maxLabel !== max) {
state.___gaugeOld__.maxLabel = max;
- state.gaugeChartMax.innerHTML = state.legendFormatValue(max);
+ state.gaugeChartMax.innerText = state.legendFormatValue(max);
}
};
var min = (state.gaugeMin === null)?NETDATA.commonMin.get(state):state.gaugeMin;
var max = (state.gaugeMax === null)?NETDATA.commonMax.get(state):state.gaugeMax;
+ // make sure it is zero based
+ if(min > 0) min = 0;
+ if(max < 0) max = 0;
+
state.gaugeEvent.value = value;
state.gaugeEvent.min = min;
state.gaugeEvent.max = max;
max = (state.gaugeMax === null)?NETDATA.commonMax.get(state):state.gaugeMax;
if(value < min) min = value;
if(value > max) max = value;
+
+ // make sure it is zero based
+ if(min > 0) min = 0;
+ if(max < 0) max = 0;
+
NETDATA.gaugeSetLabels(state, value, min, max);
}
else
state.gaugeMax = max;
+ // make sure it is zero based
+ if(min > 0) min = 0;
+ if(max < 0) max = 0;
+
var width = state.chartWidth(), height = state.chartHeight(); //, ratio = 1.5;
//switch(adjust) {
// case 'width': width = height * ratio; break;
var titletop = 0;
state.gaugeChartTitle = document.createElement('span');
state.gaugeChartTitle.className = 'gaugeChartTitle';
- state.gaugeChartTitle.innerHTML = state.title;
+ state.gaugeChartTitle.innerText = state.title;
state.gaugeChartTitle.style.fontSize = titlefontsize + 'px';
state.gaugeChartTitle.style.lineHeight = titlefontsize + 'px';
state.gaugeChartTitle.style.top = titletop.toString() + 'px';
var unitfontsize = Math.round(titlefontsize * 0.9);
state.gaugeChartUnits = document.createElement('span');
state.gaugeChartUnits.className = 'gaugeChartUnits';
- state.gaugeChartUnits.innerHTML = state.units;
+ state.gaugeChartUnits.innerText = state.units;
state.gaugeChartUnits.style.fontSize = unitfontsize + 'px';
state.element_chart.appendChild(state.gaugeChartUnits);
async: false,
isAlreadyLoaded: function() {
// check if bootstrap is loaded
- if(typeof $().emulateTransitionEnd == 'function')
+ if(typeof $().emulateTransitionEnd === 'function')
return true;
else {
if(typeof netdataNoBootstrap !== 'undefined' && netdataNoBootstrap)
}
},
{
- url: NETDATA.serverDefault + 'lib/jquery.nanoscroller-0.8.7.min.js',
+ url: NETDATA.serverDefault + 'lib/perfect-scrollbar-0.6.15.min.js',
isAlreadyLoaded: function() { return false; }
}
];
NETDATA.loadRequiredJs = function(index, callback) {
if(index >= NETDATA.requiredJs.length) {
if(typeof callback === 'function')
- callback();
+ return callback();
return;
}
var value = entry.value;
if(NETDATA.alarms.current !== null) {
var t = NETDATA.alarms.current.alarms[entry.chart + '.' + entry.name];
- if(typeof t !== 'undefined' && entry.status == t.status)
+ if(typeof t !== 'undefined' && entry.status === t.status)
value = t.value;
}
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 + ' = ' + entry.value_string.toString();
var tag = entry.alarm_id;
var icon = 'images/seo-performance-128.png';
var interaction = false;
// console.log('alarm' + entry.unique_id + ' switch to CLEAR from ' + entry.old_status);
return;
}
- title = name + ' back to normal';
+ 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 (' + entry.value_string.toString() + ')';
icon = 'images/check-mark-2-128-green.png'
interaction = false;
break;
NETDATA.alarms.first_notification_id = data.latest_alarm_log_unique_id;
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(415, NETDATA.alarms.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
})
.done(function(data) {
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(416, NETDATA.alarms.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
init: function() {
- var host = NETDATA.serverDefault;
- while(host.slice(-1) === '/')
- host = host.substring(0, host.length - 1);
- NETDATA.alarms.server = host;
+ NETDATA.alarms.server = NETDATA.fixHost(NETDATA.serverDefault);
- NETDATA.alarms.last_notification_id = NETDATA.localStorageGet('last_notification_id', NETDATA.alarms.last_notification_id, null);
+ NETDATA.alarms.last_notification_id =
+ NETDATA.localStorageGet('last_notification_id', NETDATA.alarms.last_notification_id, null);
if(NETDATA.alarms.onclick === null)
NETDATA.alarms.onclick = NETDATA.alarms.scrollToAlarm;
},
hello: function(host, callback) {
- while(host.slice(-1) === '/')
- host = host.substring(0, host.length - 1);
+ host = NETDATA.fixHost(host);
// send HELLO to a netdata server:
// 1. verifies the server is reachable
}
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(407, host);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
}
else {
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
}
}
else {
NETDATA.registry.person_guid = data.person_guid;
if(typeof callback === 'function')
- callback(data.urls);
+ return callback(data.urls);
}
})
.fail(function() {
NETDATA.error(410, NETDATA.registry.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
}
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(412, NETDATA.registry.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
}
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(418, NETDATA.registry.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
},
}
if(typeof callback === 'function')
- callback(data);
+ return callback(data);
})
.fail(function() {
NETDATA.error(414, NETDATA.registry.server);
if(typeof callback === 'function')
- callback(null);
+ return callback(null);
});
}
};
}
});
});
-
- // window.NETDATA = NETDATA;
-// })(window, document);
+})(window, document);