mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
cumulative sum, moving avg and serial diff pipeline aggregation metric (#10033)
* extracting to parent agg helper * adding comulative sum agg * adding serial diff and moving avg * adding tests
This commit is contained in:
parent
c3c8e55e4d
commit
723c7c15c9
8 changed files with 265 additions and 176 deletions
|
@ -1,128 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import DerivativeProvider from 'ui/agg_types/metrics/derivative';
|
||||
import VisProvider from 'ui/vis';
|
||||
import StubbedIndexPattern from 'fixtures/stubbed_logstash_index_pattern';
|
||||
|
||||
describe('Derivative metric', function () {
|
||||
let aggDsl;
|
||||
let derivativeMetric;
|
||||
let aggConfig;
|
||||
|
||||
function init(settings) {
|
||||
ngMock.module('kibana');
|
||||
ngMock.inject(function (Private) {
|
||||
const Vis = Private(VisProvider);
|
||||
const indexPattern = Private(StubbedIndexPattern);
|
||||
derivativeMetric = Private(DerivativeProvider);
|
||||
|
||||
const params = settings || {
|
||||
metricAgg: '1',
|
||||
customMetric: null
|
||||
};
|
||||
|
||||
const vis = new Vis(indexPattern, {
|
||||
title: 'New Visualization',
|
||||
type: 'metric',
|
||||
params: {
|
||||
fontSize: 60,
|
||||
handleNoResults: true
|
||||
},
|
||||
aggs: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'count',
|
||||
schema: 'metric'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'derivative',
|
||||
schema: 'metric',
|
||||
params
|
||||
}
|
||||
],
|
||||
listeners: {}
|
||||
});
|
||||
|
||||
// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
|
||||
aggConfig = vis.aggs[1];
|
||||
aggDsl = aggConfig.toDsl();
|
||||
});
|
||||
}
|
||||
|
||||
it('should return a label prefixed with Derivative of', function () {
|
||||
init();
|
||||
expect(derivativeMetric.makeLabel(aggConfig)).to.eql('Derivative of Count');
|
||||
});
|
||||
|
||||
it('should return a label Derivative of max bytes', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'1-orderAgg',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(derivativeMetric.makeLabel(aggConfig)).to.eql('Derivative of Max bytes');
|
||||
});
|
||||
|
||||
it('should return a label prefixed with number of derivative', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-orderAgg',
|
||||
type: 'derivative',
|
||||
params: {
|
||||
buckets_path: 'custom',
|
||||
customMetric: {
|
||||
id:'2-orderAgg-orderAgg',
|
||||
type: 'count',
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
},
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(derivativeMetric.makeLabel(aggConfig)).to.eql('2. derivative of Count');
|
||||
});
|
||||
|
||||
it('should set parent aggs', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(aggDsl.derivative.buckets_path).to.be('2-metric');
|
||||
expect(aggDsl.parentAggs['2-metric'].max.field).to.be('bytes');
|
||||
});
|
||||
|
||||
it('should set nested parent aggs', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric',
|
||||
type: 'derivative',
|
||||
params: {
|
||||
buckets_path: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric-metric',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
},
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(aggDsl.derivative.buckets_path).to.be('2-metric');
|
||||
expect(aggDsl.parentAggs['2-metric'].derivative.buckets_path).to.be('2-metric-metric');
|
||||
});
|
||||
|
||||
});
|
144
src/ui/public/agg_types/__tests__/metrics/parent_pipeline.js
Normal file
144
src/ui/public/agg_types/__tests__/metrics/parent_pipeline.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
import _ from 'lodash';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import DerivativeProvider from 'ui/agg_types/metrics/derivative';
|
||||
import CumulativeSumProvider from 'ui/agg_types/metrics/cumulative_sum';
|
||||
import MovingAvgProvider from 'ui/agg_types/metrics/moving_avg';
|
||||
import SerialDiffProvider from 'ui/agg_types/metrics/serial_diff';
|
||||
import VisProvider from 'ui/vis';
|
||||
import StubbedIndexPattern from 'fixtures/stubbed_logstash_index_pattern';
|
||||
|
||||
const metrics = [
|
||||
{ name: 'derivative', title: 'Derivative', provider: DerivativeProvider },
|
||||
{ name: 'cumulative_sum', title: 'Cumulative Sum', provider: CumulativeSumProvider },
|
||||
{ name: 'moving_avg', title: 'Moving Avg', provider: MovingAvgProvider },
|
||||
{ name: 'serial_diff', title: 'Serial Diff', provider: SerialDiffProvider },
|
||||
];
|
||||
|
||||
describe('parent pipeline aggs', function () {
|
||||
metrics.forEach(metric => {
|
||||
describe(`${metric.title} metric`, function () {
|
||||
|
||||
let aggDsl;
|
||||
let metricAgg;
|
||||
let aggConfig;
|
||||
|
||||
function init(settings) {
|
||||
ngMock.module('kibana');
|
||||
ngMock.inject(function (Private) {
|
||||
const Vis = Private(VisProvider);
|
||||
const indexPattern = Private(StubbedIndexPattern);
|
||||
metricAgg = Private(metric.provider);
|
||||
|
||||
const params = settings || {
|
||||
metricAgg: '1',
|
||||
customMetric: null
|
||||
};
|
||||
|
||||
const vis = new Vis(indexPattern, {
|
||||
title: 'New Visualization',
|
||||
type: 'metric',
|
||||
params: {
|
||||
fontSize: 60,
|
||||
handleNoResults: true
|
||||
},
|
||||
aggs: [
|
||||
{
|
||||
id: '1',
|
||||
type: 'count',
|
||||
schema: 'metric'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: metric.name,
|
||||
schema: 'metric',
|
||||
params
|
||||
}
|
||||
],
|
||||
listeners: {}
|
||||
});
|
||||
|
||||
// Grab the aggConfig off the vis (we don't actually use the vis for anything else)
|
||||
aggConfig = vis.aggs[1];
|
||||
aggDsl = aggConfig.toDsl();
|
||||
});
|
||||
}
|
||||
|
||||
it(`should return a label prefixed with ${metric.title} of`, function () {
|
||||
init();
|
||||
expect(metricAgg.makeLabel(aggConfig)).to.eql(`${metric.title} of Count`);
|
||||
});
|
||||
|
||||
it(`should return a label ${metric.title} of max bytes`, function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'1-orderAgg',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(metricAgg.makeLabel(aggConfig)).to.eql(`${metric.title} of Max bytes`);
|
||||
});
|
||||
|
||||
it(`should return a label prefixed with number of ${metric.title.toLowerCase()}`, function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-orderAgg',
|
||||
type: metric.name,
|
||||
params: {
|
||||
buckets_path: 'custom',
|
||||
customMetric: {
|
||||
id:'2-orderAgg-orderAgg',
|
||||
type: 'count',
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
},
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(metricAgg.makeLabel(aggConfig)).to.eql(`2. ${metric.title.toLowerCase()} of Count`);
|
||||
});
|
||||
|
||||
it('should set parent aggs', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(aggDsl[metric.name].buckets_path).to.be('2-metric');
|
||||
expect(aggDsl.parentAggs['2-metric'].max.field).to.be('bytes');
|
||||
});
|
||||
|
||||
it('should set nested parent aggs', function () {
|
||||
init({
|
||||
metricAgg: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric',
|
||||
type: metric.name,
|
||||
params: {
|
||||
buckets_path: 'custom',
|
||||
customMetric: {
|
||||
id:'2-metric-metric',
|
||||
type: 'max',
|
||||
params: { field: 'bytes' },
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
},
|
||||
schema: 'orderAgg'
|
||||
}
|
||||
});
|
||||
expect(aggDsl[metric.name].buckets_path).to.be('2-metric');
|
||||
expect(aggDsl.parentAggs['2-metric'][metric.name].buckets_path).to.be('2-metric-metric');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -12,6 +12,9 @@ import AggTypesMetricsCardinalityProvider from 'ui/agg_types/metrics/cardinality
|
|||
import AggTypesMetricsPercentilesProvider from 'ui/agg_types/metrics/percentiles';
|
||||
import AggTypesMetricsPercentileRanksProvider from 'ui/agg_types/metrics/percentile_ranks';
|
||||
import AggTypesMetricsDerivativeProvider from 'ui/agg_types/metrics/derivative';
|
||||
import AggTypesMetricsCumulativeSumProvider from 'ui/agg_types/metrics/cumulative_sum';
|
||||
import AggTypesMetricsMovingAvgProvider from 'ui/agg_types/metrics/moving_avg';
|
||||
import AggTypesMetricsSerialDiffProvider from 'ui/agg_types/metrics/serial_diff';
|
||||
import AggTypesBucketsDateHistogramProvider from 'ui/agg_types/buckets/date_histogram';
|
||||
import AggTypesBucketsHistogramProvider from 'ui/agg_types/buckets/histogram';
|
||||
import AggTypesBucketsRangeProvider from 'ui/agg_types/buckets/range';
|
||||
|
@ -37,6 +40,9 @@ export default function AggTypeService(Private) {
|
|||
Private(AggTypesMetricsPercentileRanksProvider),
|
||||
Private(AggTypesMetricsTopHitProvider),
|
||||
Private(AggTypesMetricsDerivativeProvider),
|
||||
Private(AggTypesMetricsCumulativeSumProvider),
|
||||
Private(AggTypesMetricsMovingAvgProvider),
|
||||
Private(AggTypesMetricsSerialDiffProvider)
|
||||
],
|
||||
buckets: [
|
||||
Private(AggTypesBucketsDateHistogramProvider),
|
||||
|
|
17
src/ui/public/agg_types/metrics/cumulative_sum.js
Normal file
17
src/ui/public/agg_types/metrics/cumulative_sum.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
|
||||
import ParentPipelineAggHelperProvider from './lib/parent_pipeline_agg_helper';
|
||||
import { makeNestedLabel } from './lib/make_nested_label';
|
||||
|
||||
export default function AggTypeMetricComulativeSumProvider(Private) {
|
||||
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
|
||||
const parentPipelineAggHelper = Private(ParentPipelineAggHelperProvider);
|
||||
|
||||
return new MetricAggType({
|
||||
name: 'cumulative_sum',
|
||||
title: 'Cumulative Sum',
|
||||
makeLabel: agg => makeNestedLabel(agg, 'cumulative sum'),
|
||||
params: [
|
||||
...parentPipelineAggHelper.params()
|
||||
]
|
||||
});
|
||||
}
|
|
@ -1,62 +1,17 @@
|
|||
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
|
||||
import metricAggTemplate from 'ui/agg_types/controls/sub_agg.html';
|
||||
import _ from 'lodash';
|
||||
import VisAggConfigProvider from 'ui/vis/agg_config';
|
||||
import VisSchemasProvider from 'ui/vis/schemas';
|
||||
import ParentPipelineAggHelperProvider from './lib/parent_pipeline_agg_helper';
|
||||
import { makeNestedLabel } from './lib/make_nested_label';
|
||||
import { parentPipelineAggController } from './lib/parent_pipeline_agg_controller';
|
||||
import { parentPipelineAggWritter } from './lib/parent_pipeline_agg_writter';
|
||||
|
||||
export default function AggTypeMetricDerivativeProvider(Private) {
|
||||
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
|
||||
const AggConfig = Private(VisAggConfigProvider);
|
||||
const Schemas = Private(VisSchemasProvider);
|
||||
|
||||
const aggFilter = ['!top_hits', '!percentiles', '!percentile_ranks', '!median', '!std_dev'];
|
||||
const orderAggSchema = (new Schemas([
|
||||
{
|
||||
group: 'none',
|
||||
name: 'orderAgg',
|
||||
title: 'Order Agg',
|
||||
aggFilter: aggFilter
|
||||
}
|
||||
])).all[0];
|
||||
const parentPipelineAggHelper = Private(ParentPipelineAggHelperProvider);
|
||||
|
||||
return new MetricAggType({
|
||||
name: 'derivative',
|
||||
title: 'Derivative',
|
||||
makeLabel: agg => makeNestedLabel(agg, 'derivative'),
|
||||
params: [
|
||||
{
|
||||
name: 'customMetric',
|
||||
type: AggConfig,
|
||||
default: null,
|
||||
serialize: function (customMetric) {
|
||||
return customMetric.toJSON();
|
||||
},
|
||||
deserialize: function (state, agg) {
|
||||
return this.makeAgg(agg, state);
|
||||
},
|
||||
makeAgg: function (termsAgg, state) {
|
||||
state = state || { type: 'count' };
|
||||
state.schema = orderAggSchema;
|
||||
const metricAgg = new AggConfig(termsAgg.vis, state);
|
||||
metricAgg.id = termsAgg.id + '-metric';
|
||||
return metricAgg;
|
||||
},
|
||||
write: _.noop
|
||||
},
|
||||
{
|
||||
name: 'buckets_path',
|
||||
write: _.noop
|
||||
},
|
||||
{
|
||||
name: 'metricAgg',
|
||||
editor: metricAggTemplate,
|
||||
default: 'custom',
|
||||
controller: parentPipelineAggController,
|
||||
write: parentPipelineAggWritter
|
||||
}
|
||||
...parentPipelineAggHelper.params()
|
||||
]
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import metricAggTemplate from 'ui/agg_types/controls/sub_agg.html';
|
||||
import _ from 'lodash';
|
||||
import VisAggConfigProvider from 'ui/vis/agg_config';
|
||||
import VisSchemasProvider from 'ui/vis/schemas';
|
||||
import { parentPipelineAggController } from './parent_pipeline_agg_controller';
|
||||
import { parentPipelineAggWritter } from './parent_pipeline_agg_writter';
|
||||
|
||||
const ParentPipelineAggHelperProvider = function (Private) {
|
||||
|
||||
const AggConfig = Private(VisAggConfigProvider);
|
||||
const Schemas = Private(VisSchemasProvider);
|
||||
|
||||
const metricAggFilter = ['!top_hits', '!percentiles', '!percentile_ranks', '!median', '!std_dev'];
|
||||
const metricAggSchema = (new Schemas([
|
||||
{
|
||||
group: 'none',
|
||||
name: 'metricAgg',
|
||||
title: 'Metric Agg',
|
||||
aggFilter: metricAggFilter
|
||||
}
|
||||
])).all[0];
|
||||
|
||||
return {
|
||||
params: function () {
|
||||
return [
|
||||
{
|
||||
name: 'customMetric',
|
||||
type: AggConfig,
|
||||
default: null,
|
||||
serialize: function (customMetric) {
|
||||
return customMetric.toJSON();
|
||||
},
|
||||
deserialize: function (state, agg) {
|
||||
return this.makeAgg(agg, state);
|
||||
},
|
||||
makeAgg: function (termsAgg, state) {
|
||||
state = state || { type: 'count' };
|
||||
state.schema = metricAggSchema;
|
||||
const metricAgg = new AggConfig(termsAgg.vis, state);
|
||||
metricAgg.id = termsAgg.id + '-metric';
|
||||
return metricAgg;
|
||||
},
|
||||
write: _.noop
|
||||
},
|
||||
{
|
||||
name: 'buckets_path',
|
||||
write: _.noop
|
||||
},
|
||||
{
|
||||
name: 'metricAgg',
|
||||
editor: metricAggTemplate,
|
||||
default: 'custom',
|
||||
controller: parentPipelineAggController,
|
||||
write: parentPipelineAggWritter
|
||||
}
|
||||
];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default ParentPipelineAggHelperProvider;
|
17
src/ui/public/agg_types/metrics/moving_avg.js
Normal file
17
src/ui/public/agg_types/metrics/moving_avg.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
|
||||
import ParentPipelineAggHelperProvider from './lib/parent_pipeline_agg_helper';
|
||||
import { makeNestedLabel } from './lib/make_nested_label';
|
||||
|
||||
export default function AggTypeMetricMovingAvgProvider(Private) {
|
||||
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
|
||||
const parentPipelineAggHelper = Private(ParentPipelineAggHelperProvider);
|
||||
|
||||
return new MetricAggType({
|
||||
name: 'moving_avg',
|
||||
title: 'Moving Avg',
|
||||
makeLabel: agg => makeNestedLabel(agg, 'moving avg'),
|
||||
params: [
|
||||
...parentPipelineAggHelper.params()
|
||||
]
|
||||
});
|
||||
}
|
17
src/ui/public/agg_types/metrics/serial_diff.js
Normal file
17
src/ui/public/agg_types/metrics/serial_diff.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import AggTypesMetricsMetricAggTypeProvider from 'ui/agg_types/metrics/metric_agg_type';
|
||||
import ParentPipelineAggHelperProvider from './lib/parent_pipeline_agg_helper';
|
||||
import { makeNestedLabel } from './lib/make_nested_label';
|
||||
|
||||
export default function AggTypeMetricSerialDiffProvider(Private) {
|
||||
const MetricAggType = Private(AggTypesMetricsMetricAggTypeProvider);
|
||||
const parentPipelineAggHelper = Private(ParentPipelineAggHelperProvider);
|
||||
|
||||
return new MetricAggType({
|
||||
name: 'serial_diff',
|
||||
title: 'Serial Diff',
|
||||
makeLabel: agg => makeNestedLabel(agg, 'serial diff'),
|
||||
params: [
|
||||
...parentPipelineAggHelper.params()
|
||||
]
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue