diff --git a/src/ui/public/time_buckets/calc_auto_interval.test.ts b/src/ui/public/time_buckets/calc_auto_interval.test.ts index 4adcc01e7e7ee4..e9723c6f483ed3 100644 --- a/src/ui/public/time_buckets/calc_auto_interval.test.ts +++ b/src/ui/public/time_buckets/calc_auto_interval.test.ts @@ -22,6 +22,16 @@ import moment from 'moment'; import { calcAutoIntervalLessThan, calcAutoIntervalNear } from './calc_auto_interval'; describe('calcAutoIntervalNear', () => { + test('0 buckets/1h = 0ms buckets', () => { + const interval = calcAutoIntervalNear(0, moment.duration(1, 'h')); + expect(interval.asMilliseconds()).toBe(0); + }); + + test('100 buckets/undefined = 0ms buckets', () => { + const interval = calcAutoIntervalNear(0, undefined as any); + expect(interval.asMilliseconds()).toBe(0); + }); + test('100 buckets/1ms = 1ms buckets', () => { const interval = calcAutoIntervalNear(100, moment.duration(1, 'ms')); expect(interval.asMilliseconds()).toBe(1); @@ -69,6 +79,16 @@ describe('calcAutoIntervalNear', () => { }); describe('calcAutoIntervalLessThan', () => { + test('0 buckets/1h = 0ms buckets', () => { + const interval = calcAutoIntervalLessThan(0, moment.duration(1, 'h')); + expect(interval.asMilliseconds()).toBe(0); + }); + + test('100 buckets/undefined = 0ms buckets', () => { + const interval = calcAutoIntervalLessThan(0, undefined as any); + expect(interval.asMilliseconds()).toBe(0); + }); + test('100 buckets/1ms = 1ms buckets', () => { const interval = calcAutoIntervalLessThan(100, moment.duration(1, 'ms')); expect(interval.asMilliseconds()).toBe(1); diff --git a/src/ui/public/time_buckets/calc_auto_interval.ts b/src/ui/public/time_buckets/calc_auto_interval.ts index a36948313f8412..61f6b1e1d06b43 100644 --- a/src/ui/public/time_buckets/calc_auto_interval.ts +++ b/src/ui/public/time_buckets/calc_auto_interval.ts @@ -86,8 +86,13 @@ const rules = [ }, ]; +function estimateBucketMs(count: number, duration: Duration) { + const ms = Number(duration) / count; + return isFinite(ms) ? ms : NaN; +} + function defaultInterval(targetMs: number) { - return moment.duration(Math.max(Math.floor(targetMs), 1), 'ms'); + return moment.duration(isNaN(targetMs) ? 0 : Math.max(Math.floor(targetMs), 1), 'ms'); } /** @@ -98,7 +103,7 @@ function defaultInterval(targetMs: number) { * @param duration time range the agg covers */ export function calcAutoIntervalNear(targetBucketCount: number, duration: Duration) { - const targetMs = Number(duration) / targetBucketCount; + const targetMs = estimateBucketMs(targetBucketCount, duration); for (let i = 0; i < rules.length - 1; i++) { if (Number(rules[i + 1].bound) <= targetMs) { @@ -117,7 +122,7 @@ export function calcAutoIntervalNear(targetBucketCount: number, duration: Durati * @param duration amount of time covered by the agg */ export function calcAutoIntervalLessThan(maxBucketCount: number, duration: Duration) { - const maxMs = Number(duration) / maxBucketCount; + const maxMs = estimateBucketMs(maxBucketCount, duration); for (const { interval } of rules) { if (Number(interval) <= maxMs) {