[ML] Fix Single Metric Viewer for multi week bucket spans (#19759)

* [ML] Fix Single Metric Viewer for multi week bucket spans

* [ML] Edit to comment in ML time buckets calcEsInterval
This commit is contained in:
Pete Harverson 2018-06-11 09:42:59 +01:00 committed by GitHub
parent c853072ca5
commit af5215fb9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 4 deletions

View file

@ -9,7 +9,10 @@
import ngMock from 'ng_mock';
import expect from 'expect.js';
import moment from 'moment';
import { IntervalHelperProvider, getBoundsRoundedToInterval } from '../ml_time_buckets';
import {
IntervalHelperProvider,
getBoundsRoundedToInterval,
calcEsInterval } from '../ml_time_buckets';
describe('ML - time buckets', () => {
@ -125,7 +128,7 @@ describe('ML - time buckets', () => {
});
describe('getBoundsRoundedToInterval ', () => {
describe('getBoundsRoundedToInterval', () => {
// Must include timezone when creating moments for this test to ensure
// checks are correct when running tests in different timezones.
const testBounds = { min: moment('2017-01-05T10:11:12.000+00:00'), max: moment('2017-10-26T09:08:07.000+00:00') };
@ -156,4 +159,24 @@ describe('ML - time buckets', () => {
});
describe('calcEsInterval', () => {
it('returns correct interval for various durations', () => {
expect(calcEsInterval(moment.duration(500, 'ms'))).to.eql({ value: 500, unit: 'ms', expression: '500ms' });
expect(calcEsInterval(moment.duration(1000, 'ms'))).to.eql({ value: 1, unit: 's', expression: '1s' });
expect(calcEsInterval(moment.duration(15, 's'))).to.eql({ value: 15, unit: 's', expression: '15s' });
expect(calcEsInterval(moment.duration(60, 's'))).to.eql({ value: 1, unit: 'm', expression: '1m' });
expect(calcEsInterval(moment.duration(1, 'm'))).to.eql({ value: 1, unit: 'm', expression: '1m' });
expect(calcEsInterval(moment.duration(60, 'm'))).to.eql({ value: 1, unit: 'h', expression: '1h' });
expect(calcEsInterval(moment.duration(3, 'h'))).to.eql({ value: 3, unit: 'h', expression: '3h' });
expect(calcEsInterval(moment.duration(24, 'h'))).to.eql({ value: 1, unit: 'd', expression: '1d' });
expect(calcEsInterval(moment.duration(3, 'd'))).to.eql({ value: 3, unit: 'd', expression: '3d' });
expect(calcEsInterval(moment.duration(7, 'd'))).to.eql({ value: 1, unit: 'w', expression: '1w' });
expect(calcEsInterval(moment.duration(1, 'w'))).to.eql({ value: 1, unit: 'w', expression: '1w' });
expect(calcEsInterval(moment.duration(4, 'w'))).to.eql({ value: 28, unit: 'd', expression: '28d' });
expect(calcEsInterval(moment.duration(1, 'M'))).to.eql({ value: 1, unit: 'M', expression: '1M' });
expect(calcEsInterval(moment.duration(12, 'M'))).to.eql({ value: 1, unit: 'y', expression: '1y' });
expect(calcEsInterval(moment.duration(1, 'y'))).to.eql({ value: 1, unit: 'y', expression: '1y' });
});
});
});

View file

@ -6,17 +6,20 @@
// custom TimeBuckets which inherits from the standrd kibana TimeBuckets
// custom TimeBuckets which inherits from the standard kibana TimeBuckets
// this adds the ability to override the barTarget and maxBars settings
// allowing for a more granular visualization interval without having to
// modify the global settings stored in the kibana config
import _ from 'lodash';
import moment from 'moment';
import dateMath from '@kbn/datemath';
import { TimeBucketsCalcAutoIntervalProvider } from 'plugins/ml/util/ml_calc_auto_interval';
import { inherits } from 'plugins/ml/util/inherits';
import { calcEsInterval } from 'ui/time_buckets/calc_es_interval';
const unitsDesc = dateMath.unitsDesc;
const largeMax = unitsDesc.indexOf('w'); // Multiple units of week or longer converted to days for ES intervals.
import { TimeBuckets } from 'ui/time_buckets';
export function IntervalHelperProvider(Private, timefilter, config) {
@ -147,3 +150,39 @@ export function getBoundsRoundedToInterval(bounds, interval, inclusiveEnd = fals
}
return { min: moment(adjustedMinMs), max: moment(adjustedMaxMs) };
}
export function calcEsInterval(duration) {
// Converts a moment.duration into an Elasticsearch compatible interval expression,
// and provides associated metadata.
// Note this is a copy of Kibana's ui/time_buckets/calc_es_interval,
// but with the definition of a 'large' unit changed from 'M' to 'w',
// bringing it into line with the time units supported by Elasticsearch
for (let i = 0; i < unitsDesc.length; i++) {
const unit = unitsDesc[i];
const val = duration.as(unit);
// find a unit that rounds neatly
if (val >= 1 && Math.floor(val) === val) {
// if the unit is "large", like years, but isn't set to 1, ES will throw an error.
// So keep going until we get out of the "large" units.
if (i <= largeMax && val !== 1) {
continue;
}
return {
value: val,
unit: unit,
expression: val + unit
};
}
}
const ms = duration.as('ms');
return {
value: ms,
unit: 'ms',
expression: ms + 'ms'
};
}