diff --git a/src/app/directives/grafanaGraph.js b/src/app/directives/grafanaGraph.js index cd842c6c2b2..65ff8cba28a 100644 --- a/src/app/directives/grafanaGraph.js +++ b/src/app/directives/grafanaGraph.js @@ -82,7 +82,7 @@ function (angular, $, kbn, moment, _) { }); // Set barwidth based on specified interval - var barwidth = kbn.interval_to_ms(scope.panel.interval); + var barwidth = kbn.interval_to_ms(scope.interval); var stack = scope.panel.stack ? true : null; @@ -121,7 +121,7 @@ function (angular, $, kbn, moment, _) { mode: "time", min: _.isUndefined(scope.range.from) ? null : scope.range.from.getTime(), max: _.isUndefined(scope.range.to) ? null : scope.range.to.getTime(), - timeformat: time_format(scope.panel.interval), + timeformat: time_format(scope.interval), label: "Datetime", ticks: elem.width()/100 }, @@ -139,21 +139,8 @@ function (angular, $, kbn, moment, _) { addAnnotations(options); - // when rendering stacked bars, we need to ensure each point that has data is zero-filled - // so that the stacking happens in the proper order - var required_times = []; - if (data.length > 1) { - required_times = Array.prototype.concat.apply([], _.map(data, function (query) { - return query.time_series.getOrderedTimes(); - })); - required_times = _.uniq(required_times.sort(function (a, b) { - // decending numeric sort - return a-b; - }), true); - } - for (var i = 0; i < data.length; i++) { - var _d = data[i].time_series.getFlotPairs(required_times, scope.panel.nullPointMode); + var _d = data[i].time_series.getFlotPairs(scope.panel.nullPointMode); data[i].yaxis = data[i].info.yaxis; data[i].data = _d; data[i].info.y_format = data[i].yaxis === 1 ? scope.panel.y_format : scope.panel.y2_format; diff --git a/src/app/panels/graphite/axisEditor.html b/src/app/panels/graphite/axisEditor.html index 06e6418352d..3bf31cf4fb4 100644 --- a/src/app/panels/graphite/axisEditor.html +++ b/src/app/panels/graphite/axisEditor.html @@ -8,10 +8,6 @@
-
- - -
diff --git a/src/app/panels/graphite/module.js b/src/app/panels/graphite/module.js index 5a7f454a0d4..8298e57d04c 100644 --- a/src/app/panels/graphite/module.js +++ b/src/app/panels/graphite/module.js @@ -101,8 +101,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) { /** @scratch /panels/histogram/3 * y_format:: 'none','bytes','short ' */ - y_format : 'none', - y2_format : 'none', + y_format : 'short', + y2_format : 'short', /** @scratch /panels/histogram/5 * grid object:: Min and max y-axis values * grid.min::: Minimum y-axis value @@ -129,23 +129,11 @@ function (angular, app, $, _, kbn, moment, timeSeries) { field : '_type', sort : ['_score','desc'] }, - /** @scratch /panels/histogram/3 - * ==== Interval options - * auto_int:: Automatically scale intervals? - */ - auto_int : true, /** @scratch /panels/histogram/3 * resolution:: If auto_int is true, shoot for this many bars. */ resolution : 100, - /** @scratch /panels/histogram/3 - * interval:: If auto_int is set to false, use this as the interval. - */ - interval : '5m', - /** @scratch /panels/histogram/3 - * interval:: Array of possible intervals in the *View* selector. Example [`auto',`1s',`5m',`3h'] - */ - intervals : ['auto','1s','1m','5m','10m','30m','1h','3h','12h','1d','1w','1y'], + /** @scratch /panels/histogram/3 * ==== Drawing options * lines:: Show line chart @@ -227,15 +215,6 @@ function (angular, app, $, _, kbn, moment, timeSeries) { }; - $scope.set_interval = function(interval) { - if(interval !== 'auto') { - $scope.panel.auto_int = false; - $scope.panel.interval = interval; - } else { - $scope.panel.auto_int = true; - } - }; - $scope.remove_panel_from_row = function(row, panel) { if ($scope.fullscreen) { $rootScope.$emit('panel-fullscreen-exit'); @@ -250,24 +229,15 @@ function (angular, app, $, _, kbn, moment, timeSeries) { $scope.get_data(); }; - $scope.interval_label = function(interval) { - return $scope.panel.auto_int && interval === $scope.panel.interval ? interval+" (auto)" : interval; - }; - $scope.updateTimeRange = function () { - var range = filterSrv.timeRange(); - var interval = filterSrv.timeRange(); + $scope.range = filterSrv.timeRange(); + $scope.interval = '10m'; - if ($scope.panel.auto_int) { - if (range) { - interval = kbn.secondsToHms( - kbn.calculate_interval(range.from, range.to, $scope.panel.resolution, 0) / 1000 - ); - } + if ($scope.range) { + $scope.interval = kbn.secondsToHms( + kbn.calculate_interval($scope.range.from, $scope.range.to, $scope.panel.resolution, 0) / 1000 + ); } - - $scope.interval = $scope.panel.interval = interval || '10m'; - $scope.range = range; }; $scope.colors = [ @@ -327,18 +297,10 @@ function (angular, app, $, _, kbn, moment, timeSeries) { var color = $scope.panel.aliasColors[alias] || $scope.colors[data.length]; var yaxis = $scope.panel.aliasYAxis[alias] || 1; - var tsOpts = { - interval: $scope.interval, + var time_series = new timeSeries.ZeroFilled({ start_date: $scope.range && $scope.range.from, end_date: $scope.range && $scope.range.to, - }; - - var time_series = new timeSeries.ZeroFilled(tsOpts); - - _.each(targetData.datapoints, function(valueArray) { - if (valueArray[0] !== null) { - time_series.addValue(valueArray[1] * 1000, valueArray[0]); - } + datapoints: targetData.datapoints }); var seriesInfo = { diff --git a/src/app/panels/graphite/styleEditor.html b/src/app/panels/graphite/styleEditor.html index e6d1f63b972..ec18121cba7 100644 --- a/src/app/panels/graphite/styleEditor.html +++ b/src/app/panels/graphite/styleEditor.html @@ -24,6 +24,10 @@
+
+ + +
diff --git a/src/app/panels/graphite/timeSeries.js b/src/app/panels/graphite/timeSeries.js index 0b325c5f13c..93c9eb87842 100644 --- a/src/app/panels/graphite/timeSeries.js +++ b/src/app/panels/graphite/timeSeries.js @@ -33,197 +33,41 @@ function (_, Interval) { */ ts.ZeroFilled = function (opts) { opts = _.defaults(opts, { - interval: '10m', start_date: null, end_date: null, + datapoints: [] }); - // the expected differenece between readings. - this.interval = new Interval(opts.interval); - - // will keep all values here, keyed by their time - this._data = {}; this.start_time = opts.start_date && getDatesTime(opts.start_date); this.end_time = opts.end_date && getDatesTime(opts.end_date); this.opts = opts; + this.datapoints = opts.datapoints; }; - /** - * Add a row - * @param {int} time The time for the value, in - * @param {any} value The value at this time - */ - ts.ZeroFilled.prototype.addValue = function (time, value) { - if (time instanceof Date) { - time = getDatesTime(time); - } else { - time = base10Int(time); - } - if (!isNaN(time)) { - this._data[time] = (_.isUndefined(value) ? 0 : value); - } - this._cached_times = null; - }; + ts.ZeroFilled.prototype.getFlotPairs = function (fillStyle) { + var result = []; - /** - * Get an array of the times that have been explicitly set in the series - * @param {array} include (optional) list of timestamps to include in the response - * @return {array} An array of integer times. - */ - ts.ZeroFilled.prototype.getOrderedTimes = function (include) { - var times = _.map(_.keys(this._data), base10Int); - if (_.isArray(include)) { - times = times.concat(include); - } - return _.uniq(times.sort(function (a, b) { - // decending numeric sort - return a - b; - }), true); - }; - - /** - * return the rows in the format: - * [ [time, value], [time, value], ... ] - * - * Heavy lifting is done by _get(Min|Default|All)FlotPairs() - * @param {array} required_times An array of timestamps that must be in the resulting pairs - * @return {array} - */ - ts.ZeroFilled.prototype.getFlotPairs = function (required_times, fillStyle) { - var times = this.getOrderedTimes(required_times), - strategy, - pairs; - - if(fillStyle === 'null as zero') { - strategy = this._getAllFlotPairs; - } else if(fillStyle === 'null') { - strategy = this._getNullFlotPairs; - } else if(fillStyle === 'connected') { - strategy = this._getNoZeroFlotPairs; - } else { - strategy = this._getMinFlotPairs; - } - - pairs = _.reduce( - times, // what - strategy, // how - [], // where - this // context - ); - - // if the first or last pair is inside either the start or end time, - // add those times to the series with null values so the graph will stretch to contain them. - // Removing, flot 0.8.1's max/min params satisfy this - /* - if (this.start_time && (pairs.length === 0 || pairs[0][0] > this.start_time)) { - pairs.unshift([this.start_time, null]); - } - if (this.end_time && (pairs.length === 0 || pairs[pairs.length - 1][0] < this.end_time)) { - pairs.push([this.end_time, null]); - } - */ - - return pairs; - }; - - /** - * ** called as a reduce stragegy in getFlotPairs() ** - * Fill zero's on either side of the current time, unless there is already a measurement there or - * we are looking at an edge. - * @return {array} An array of points to plot with flot - */ - ts.ZeroFilled.prototype._getMinFlotPairs = function (result, time, i, times) { - var next, expected_next, prev, expected_prev; - - // check for previous measurement - if (i > 0) { - prev = times[i - 1]; - expected_prev = this.interval.before(time); - if (prev < expected_prev) { - result.push([expected_prev, 0]); + _.each(this.datapoints, function(valueArray) { + var currentTime = valueArray[1]; + var currentValue = valueArray[0]; + if (currentValue === null) { + if (fillStyle === 'connected') { + return; + } + if (fillStyle === 'null as zero') { + currentValue = 0; + } + if (fillStyle === 'null') { + // do nothing + } } - } - // add the current time - result.push([ time, this._data[time] || 0]); - - // check for next measurement - if (times.length > i) { - next = times[i + 1]; - expected_next = this.interval.after(time); - if (next > expected_next) { - result.push([expected_next, 0]); - } - } + result.push([currentTime * 1000, currentValue]); + }); return result; }; - /** - * ** called as a reduce stragegy in getFlotPairs() ** - * Fill zero's to the right of each time, until the next measurement is reached or we are at the - * last measurement - * @return {array} An array of points to plot with flot - */ - ts.ZeroFilled.prototype._getAllFlotPairs = function (result, time, i, times) { - var next, expected_next; - - result.push([ times[i], this._data[times[i]] || 0 ]); - next = times[i + 1]; - expected_next = this.interval.after(time); - for(; times.length > i && next > expected_next; expected_next = this.interval.after(expected_next)) { - result.push([expected_next, 0]); - } - - return result; - }; - - /** - * ** called as a reduce stragegy in getFlotPairs() ** - * Same as min, but fills with nulls - * @return {array} An array of points to plot with flot - */ - ts.ZeroFilled.prototype._getNullFlotPairs = function (result, time, i, times) { - var next, expected_next, prev, expected_prev; - - // check for previous measurement - if (i > 0) { - prev = times[i - 1]; - expected_prev = this.interval.before(time); - if (prev < expected_prev) { - result.push([expected_prev, null]); - } - } - - // add the current time - result.push([ time, this._data[time] || null]); - - // check for next measurement - if (times.length > i) { - next = times[i + 1]; - expected_next = this.interval.after(time); - if (next > expected_next) { - result.push([expected_next, null]); - } - } - - return result; - }; - - /** - * ** called as a reduce stragegy in getFlotPairs() ** - * Not fill zero's on either side of the current time, only the current time - * @return {array} An array of points to plot with flot - */ - ts.ZeroFilled.prototype._getNoZeroFlotPairs = function (result, time) { - - // add the current time - if(this._data[time] !== null){ - result.push([ time, this._data[time]]); - } - - return result; - }; return ts; }); \ No newline at end of file