From bd2d05eda4e7f306eea0b7e65c2d6e4fce730d50 Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Sun, 13 Dec 2015 20:19:56 +0200 Subject: [PATCH] more optimizations; a working example of a full dashboard --- web/Makefile.am | 1 + web/dashboard.css | 4 + web/dashboard.js | 256 ++++++++++++++++++----------- web/dashboard_full.html | 352 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 516 insertions(+), 97 deletions(-) create mode 100755 web/dashboard_full.html diff --git a/web/Makefile.am b/web/Makefile.am index d963e8c1..c25dec13 100644 --- a/web/Makefile.am +++ b/web/Makefile.am @@ -10,6 +10,7 @@ dist_web_DATA = \ netdata.js \ robots.txt \ theme.css \ + dashboard_full.html \ dashboard.html \ dashboard.js \ dashboard.css \ diff --git a/web/dashboard.css b/web/dashboard.css index 5c95f75a..d7a4ccd1 100755 --- a/web/dashboard.css +++ b/web/dashboard.css @@ -2,6 +2,10 @@ html { font-family: sans-serif; } +.netdata-chart-alignment { + margin-left: 55px; +} + .netdata-container { display: -webkit-flex; /* Safari */ -webkit-flex-wrap: wrap; /* Safari 6.1+ */ diff --git a/web/dashboard.js b/web/dashboard.js index 8e4d037d..58becde4 100755 --- a/web/dashboard.js +++ b/web/dashboard.js @@ -122,8 +122,8 @@ pause: false, // when enabled we don't auto-refresh the charts - targets: null, // an array of all the DOM elements that are - // currently visible (independently of their + targets: null, // an array of all the state objects that are + // currently active (independently of their // viewport visibility) updated_dom: true, // when true, the DOM has been updated with @@ -217,11 +217,13 @@ }; window.onscroll = function(event) { - // FIXME targets should be states not DOM elements - for(i = 0; i < NETDATA.options.targets.length ;i++) { - var state = NETDATA.chartState(NETDATA.options.targets[i]) - state.isVisible(); - } + // when the user scrolls he sees that we have + // hidden all the not-visible charts + // using this little function we try to switch + // the charts back to visible quickly + var targets = NETDATA.options.targets; + var len = targets.length; + while(len--) targets[len].isVisible(); } // ---------------------------------------------------------------------------------------------------------------- @@ -443,6 +445,8 @@ library_name: self.data('chart-library') || NETDATA.chartDefaults.library, library: null, // object - the chart library used + colors: null, + element: element, // the element already created by the user element_message: null, element_loading: null, @@ -554,9 +558,12 @@ }; // prevent to global selection sync for some time - chartState.prototype.globalSelectionSyncDelay = function() { + chartState.prototype.globalSelectionSyncDelay = function(ms) { if(!NETDATA.options.current.sync_selection) return; - NETDATA.globalSelectionSync.dont_sync_before = new Date().getTime() + NETDATA.options.current.sync_selection_delay; + if(typeof ms === 'number') + NETDATA.globalSelectionSync.dont_sync_before = new Date().getTime() + ms; + else + NETDATA.globalSelectionSync.dont_sync_before = new Date().getTime() + NETDATA.options.current.sync_selection_delay; } // can we globally apply selection sync? @@ -566,10 +573,17 @@ return true; } + chartState.prototype.globalSelectionSyncIsMaster = function() { + if(NETDATA.globalSelectionSync.state === this) + return true; + else + return false; + } + // this chart is the master of the global selection sync chartState.prototype.globalSelectionSyncBeMaster = function() { // am I the master? - if(NETDATA.globalSelectionSync.state === this) { + if(this.globalSelectionSyncIsMaster()) { if(this.debug) this.log('sync: I am the master already.'); return; } @@ -585,18 +599,21 @@ NETDATA.globalSelectionSync.state = this; // find the all slaves - var self = this; - // FIXME targets should be states not DOM elements - $.each(NETDATA.options.targets, function(i, target) { - var st = NETDATA.chartState(target); - if(st === self) { - if(self.debug) st.log('sync: not adding me to sync'); + var targets = NETDATA.options.targets; + var len = targets.length; + while(len--) { + st = targets[len]; + + if(st === this) { + if(this.debug) st.log('sync: not adding me to sync'); } else if(st.globalSelectionSyncIsEligible()) { - if(self.debug) st.log('sync: adding to sync as slave'); + if(this.debug) st.log('sync: adding to sync as slave'); st.globalSelectionSyncBeSlave(); } - }); + } + + this.globalSelectionSyncDelay(100); } // can the chart participate to the global selection sync as a slave? @@ -620,21 +637,26 @@ return; } - if(this.debug) this.log('sync: trying to be sync master.'); - this.globalSelectionSyncBeMaster(); + if(!this.globalSelectionSyncIsMaster()) { + if(this.debug) this.log('sync: trying to be sync master.'); + this.globalSelectionSyncBeMaster(); - var self = this; - $.each(NETDATA.globalSelectionSync.slaves, function(i, st) { - if(st === self) { - // since we are the sync master, we should not call state.setSelection() - // the chart library is taking care of visualizing our selection. - if(self.debug) st.log('sync: ignoring me from set selection'); - } - else { - if(self.debug) st.log('sync: showing master selection'); - st.setSelection(t); + if(!this.globalSelectionSyncAbility()) { + if(this.debug) this.log('sync: cannot sync (yet?).'); + return; } + } + + // FIXME + // var start = new Date().getTime(); + + $.each(NETDATA.globalSelectionSync.slaves, function(i, st) { + st.setSelection(t); }); + + // FIXME + // var end = new Date().getTime(); + // console.log(end - start); } // stop syncing all charts to the given time @@ -848,7 +870,11 @@ } chartState.prototype.legendFormatValue = function(value) { - if(typeof value !== 'number' || value === null) return ''; + // FIXME + // return ''; + // return value; + if(value === null) return ''; + if(typeof value !== 'number') return value; var abs = Math.abs(value); if(abs >= 1) return (Math.round(value * 100) / 100).toLocaleString(); @@ -856,15 +882,17 @@ return (Math.round(value * 10000) / 10000).toLocaleString(); } - chartState.prototype.legendSetLabelValue = function(label, string) { - if(typeof this.element_legend_childs.series[label] === 'undefined') + chartState.prototype.legendSetLabelValue = function(label, value) { + var series = this.element_legend_childs.series[label]; + + if(typeof series === 'undefined' || series.last === value) return; - if(this.element_legend_childs.series[label].value !== null) - this.element_legend_childs.series[label].value.innerHTML = string; + series.last = value; + value = this.legendFormatValue(value); - if(this.element_legend_childs.series[label].user !== null) - this.element_legend_childs.series[label].user.innerHTML = string; + if(series.value !== null) series.value.innerHTML = value; + if(series.user !== null) series.user.innerHTML = value; } chartState.prototype.legendSetDate = function(ms) { @@ -910,17 +938,18 @@ else this.legendUndefined(); - for(var i = 0; i < this.current.data.dimension_names.length; i++) { - if(typeof this.current.data.dimension_names[i] === 'undefined') - continue; + var labels = this.current.data.dimension_names; + var i = labels.length; + while(i--) { + var label = labels[i]; - if(typeof this.element_legend_childs.series[this.current.data.dimension_names[i]] === 'undefined') - continue; + if(typeof label === 'undefined') continue; + if(typeof this.element_legend_childs.series[label] === 'undefined') continue; if(Math.abs(this.current.data.last_entry_t - this.current.data.before) <= this.current.data.view_update_every) - this.legendSetLabelValue(this.current.data.dimension_names[i], this.legendFormatValue(this.current.data.result_latest_values[i])); + this.legendSetLabelValue(label, this.current.data.result_latest_values[i]); else - this.legendSetLabelValue(this.current.data.dimension_names[i], ''); + this.legendSetLabelValue(label, null); } } @@ -928,6 +957,33 @@ this.legendShowLatestValues(); } + chartState.prototype.chartColors = function() { + if(this.colors !== null) return this.colors; + + this.colors = $(this.element).data('colors'); + if(typeof this.colors === 'undefined' || this.colors === null) + this.colors = NETDATA.colors; + else { + // console.log(this.colors); + var s = this.colors; + if(typeof s === 'string') s = s.split(' '); + + this.colors = new Array(); + var self = this; + $.each(s, function(i, c) { + self.colors.push(c); + }); + + // push the default colors too + var self = this; + $.each(NETDATA.colors, function(i, c) { + self.colors.push(c); + }); + } + + return this.colors; + } + chartState.prototype.legendUpdateDOM = function() { if(!this.hasLegend()) return; @@ -944,15 +1000,18 @@ } else { // this.log('checking existing legend'); - for(var i = 0; i < this.current.data.dimension_names.length; i++) { - if(typeof this.element_legend_childs.series[this.current.data.dimension_names[i]] === 'undefined') { - // this.log('legend is incosistent - missing dimension:' + this.current.data.dimension_names[i]); + var labels = this.current.data.dimension_names; + var i = labels.length; + while(i--) { + var name = labels[i]; + if(typeof this.element_legend_childs.series[name] === 'undefined') { + // this.log('legend is incosistent - missing dimension:' + name); needed = true; break; } else if(Math.abs(this.current.data.last_entry_t - this.current.data.before) <= this.current.data.view_update_every) { - // this.log('setting legend of ' + this.current.data.dimension_names[i] + ' to ' + this.current.data.latest_values[i]); - this.legendSetLabelValue(this.current.data.dimension_names[i], this.legendFormatValue(this.current.data.latest_values[i])); + // this.log('setting legend of ' + name + ' to ' + this.current.data.latest_values[i]); + this.legendSetLabelValue(name, this.current.data.latest_values[i]); } } } @@ -995,7 +1054,7 @@ self = $(this); var genLabel = function(state, parent, name, count) { - var c = count % NETDATA.colors.length; + var c = count % state.chartColors().length; var user_element = null; var user_id = self.data('show-value-of-' + name + '-at') || null; @@ -1004,7 +1063,8 @@ state.element_legend_childs.series[name] = { name: document.createElement('span'), value: document.createElement('span'), - user: user_element + user: user_element, + last: null }; var label = state.element_legend_childs.series[name]; @@ -1014,7 +1074,7 @@ label.name.title = name; label.value.title = name; - var rgb = NETDATA.colorHex2Rgb(NETDATA.colors[c]); + var rgb = NETDATA.colorHex2Rgb(state.chartColors()[c]); label.name.innerHTML = ' + + + NetData Dashboard + + + + + + + + + + + +
+
+
+ + + + + + + + + + + -- 2.39.2