From d30c5d306352e0b8ae2ea585538091786d1de799 Mon Sep 17 00:00:00 2001 From: "James Allison (sf-jda)" Date: Thu, 14 Jun 2018 16:04:16 +0100 Subject: [PATCH 1/3] Added support for buckets post aggregation --- dist/datasource.js | 85 ++++++++++++++++++++++++++++++++- dist/partials/query.editor.html | 15 ++++++ dist/query_ctrl.d.ts | 2 + dist/query_ctrl.js | 13 ++++- dist/query_ctrl.js.map | 2 +- dist/query_ctrl.ts | 13 ++++- dist/test/query_ctrl.d.ts | 2 + dist/test/query_ctrl.js | 13 ++++- dist/test/query_ctrl.js.map | 2 +- src/datasource.js | 85 ++++++++++++++++++++++++++++++++- src/partials/query.editor.html | 15 ++++++ src/query_ctrl.ts | 13 ++++- 12 files changed, 252 insertions(+), 8 deletions(-) diff --git a/dist/datasource.js b/dist/datasource.js index 391064e6..1ec21a6d 100644 --- a/dist/datasource.js +++ b/dist/datasource.js @@ -151,6 +151,7 @@ function (angular, _, dateMath, moment) { var filters = target.filters; var aggregators = target.aggregators; var postAggregators = target.postAggregators; + var bucketAggregators = getBucketAggregators(target.postAggregators); var groupBy = _.map(target.groupBy, (e) => { return templateSrv.replace(e) }); var limitSpec = null; var metricNames = getMetricNames(aggregators, postAggregators); @@ -189,7 +190,13 @@ function (angular, _, dateMath, moment) { else { promise = this._timeSeriesQuery(datasource, intervals, granularity, filters, aggregators, postAggregators) .then(function(response) { - return convertTimeSeriesData(response.data, metricNames); + if (_.isEmpty(bucketAggregators)) { + return convertTimeSeriesData(response.data, metricNames); + } + else { + return convertBucketsData(response.data, bucketAggregators); + } + }); } /* @@ -352,6 +359,12 @@ function (angular, _, dateMath, moment) { return _.union(_.map(displayAggs, 'name'), _.map(postAggregators, 'name')); } + function getBucketAggregators(postAggregators) { + return _.filter(postAggregators, function (agg) { + return agg.type === 'buckets'; + }); + } + function formatTimestamp(ts) { return moment(ts).format('X')*1000; } @@ -370,6 +383,76 @@ function (angular, _, dateMath, moment) { }); } + function convertBucketsData(md, bucketAggs) { + + /* + The response data is of the form: + [ + { + timestamp: "xxx", + result: + : + breaks: [...], + counts: [...] + }, + ... + ] + + We need to transform the data so that each breakpoint has a series: + [ + { + target: , + datapoints: [ + [, ], + ] + }, + ... + ] + + */ + + if (! md.length) { + console.log("Cannot calculate buckets because query data is empty"); + return []; + } + + /* + The original data will not have values for all breakpoints. + We first need to work out which breakpoints to use. + */ + var bucket = _.map(bucketAggs, 'name')[0]; + var bucketSize = Number(_.map(bucketAggs, 'bucketSize')[0]); + var topbreaks = _.map(md, function (item) { + return item.result[bucket].breaks.slice(-1)[0]; + }); + var breaks = _.range(0, _.nax(topbreaks), bucketSize); + + if (! breaks.length) { + console.log("Cannot calculate buckets because there are no breakpoints"); + return []; + } + + return breaks.map(function (metric) { + return { + target: String(metric), + datapoints: md.map(function (item) { + var index = item.result[bucket].breaks.indexOf(metric); + if (index == -1) { + return [ + null, + formatTimestamp(item.timestamp) + ]; + } else { + return [ + item.result[bucket].counts[index], + formatTimestamp(item.timestamp) + ]; + } + }) + }; + }); + } + function getGroupName(groupBy, metric) { return groupBy.map(function (dim) { return metric.event[dim]; diff --git a/dist/partials/query.editor.html b/dist/partials/query.editor.html index ef84a3eb..f2611e52 100644 --- a/dist/partials/query.editor.html +++ b/dist/partials/query.editor.html @@ -431,6 +431,14 @@ +
+ +
@@ -469,6 +477,13 @@ + +
+ + + +
+
+
+ +
@@ -469,6 +477,13 @@ + +
+ + + +
+