simplify time interval checking (#83545)

This commit is contained in:
Joe Reuter 2020-11-20 17:18:22 +01:00 committed by GitHub
parent 8ca1e93763
commit 1c5fc14d1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 141 additions and 221 deletions

View file

@ -18,7 +18,7 @@ import {
Fit, Fit,
} from '@elastic/charts'; } from '@elastic/charts';
import { PaletteOutput } from 'src/plugins/charts/public'; import { PaletteOutput } from 'src/plugins/charts/public';
import { xyChart, XYChart } from './expression'; import { calculateMinInterval, xyChart, XYChart, XYChartProps } from './expression';
import { LensMultiTable } from '../types'; import { LensMultiTable } from '../types';
import { Datatable, DatatableRow } from '../../../../../src/plugins/expressions/public'; import { Datatable, DatatableRow } from '../../../../../src/plugins/expressions/public';
import React from 'react'; import React from 'react';
@ -287,6 +287,10 @@ function sampleArgs() {
{ a: 1, b: 5, c: 'J', d: 'Bar' }, { a: 1, b: 5, c: 'J', d: 'Bar' },
]), ]),
}, },
dateRange: {
fromDate: new Date('2019-01-02T05:00:00.000Z'),
toDate: new Date('2019-01-03T05:00:00.000Z'),
},
}; };
const args: XYArgs = createArgsWithLayers(); const args: XYArgs = createArgsWithLayers();
@ -425,7 +429,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -449,7 +453,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -502,7 +506,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={undefined}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -516,7 +520,7 @@ describe('xy_expression', () => {
`); `);
}); });
test('it generates correct xDomain for a layer with single value and a layer with no data (1-0) ', () => { test('it uses passed in minInterval', () => {
const data: LensMultiTable = { const data: LensMultiTable = {
type: 'lens_multitable', type: 'lens_multitable',
tables: { tables: {
@ -539,7 +543,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -550,132 +554,10 @@ describe('xy_expression', () => {
Object { Object {
"max": 1546491600000, "max": 1546491600000,
"min": 1546405200000, "min": 1546405200000,
"minInterval": 1728000, "minInterval": 50,
} }
`); `);
}); });
test('it generates correct xDomain for two layers with single value(1-1)', () => {
const data: LensMultiTable = {
type: 'lens_multitable',
tables: {
first: createSampleDatatableWithRows([{ a: 1, b: 2, c: 'I', d: 'Foo' }]),
second: createSampleDatatableWithRows([{ a: 10, b: 5, c: 'J', d: 'Bar' }]),
},
};
const component = shallow(
<XYChart
data={{
...data,
dateRange: {
fromDate: new Date('2019-01-02T05:00:00.000Z'),
toDate: new Date('2019-01-03T05:00:00.000Z'),
},
}}
args={multiLayerArgs}
formatFactory={getFormatSpy}
timeZone="UTC"
chartsThemeService={chartsThemeService}
paletteService={paletteService}
histogramBarTarget={50}
onClickValue={onClickValue}
onSelectRange={onSelectRange}
/>
);
expect(component.find(Settings).prop('xDomain')).toMatchInlineSnapshot(`
Object {
"max": 1546491600000,
"min": 1546405200000,
"minInterval": undefined,
}
`);
});
test('it generates correct xDomain for a layer with single value and layer with multiple value data (1-n)', () => {
const data: LensMultiTable = {
type: 'lens_multitable',
tables: {
first: createSampleDatatableWithRows([{ a: 1, b: 2, c: 'I', d: 'Foo' }]),
second: createSampleDatatableWithRows([
{ a: 10, b: 5, c: 'J', d: 'Bar' },
{ a: 8, b: 5, c: 'K', d: 'Buzz' },
]),
},
};
const component = shallow(
<XYChart
data={{
...data,
dateRange: {
fromDate: new Date('2019-01-02T05:00:00.000Z'),
toDate: new Date('2019-01-03T05:00:00.000Z'),
},
}}
args={multiLayerArgs}
formatFactory={getFormatSpy}
timeZone="UTC"
chartsThemeService={chartsThemeService}
paletteService={paletteService}
histogramBarTarget={50}
onClickValue={onClickValue}
onSelectRange={onSelectRange}
/>
);
expect(component.find(Settings).prop('xDomain')).toMatchInlineSnapshot(`
Object {
"max": 1546491600000,
"min": 1546405200000,
"minInterval": undefined,
}
`);
});
test('it generates correct xDomain for 2 layers with multiple value data (n-n)', () => {
const data: LensMultiTable = {
type: 'lens_multitable',
tables: {
first: createSampleDatatableWithRows([
{ a: 1, b: 2, c: 'I', d: 'Foo' },
{ a: 8, b: 5, c: 'K', d: 'Buzz' },
{ a: 9, b: 7, c: 'L', d: 'Bar' },
{ a: 10, b: 2, c: 'G', d: 'Bear' },
]),
second: createSampleDatatableWithRows([
{ a: 10, b: 5, c: 'J', d: 'Bar' },
{ a: 8, b: 4, c: 'K', d: 'Fi' },
{ a: 1, b: 8, c: 'O', d: 'Pi' },
]),
},
};
const component = shallow(
<XYChart
data={{
...data,
dateRange: {
fromDate: new Date('2019-01-02T05:00:00.000Z'),
toDate: new Date('2019-01-03T05:00:00.000Z'),
},
}}
args={multiLayerArgs}
formatFactory={getFormatSpy}
timeZone="UTC"
chartsThemeService={chartsThemeService}
paletteService={paletteService}
histogramBarTarget={50}
onClickValue={onClickValue}
onSelectRange={onSelectRange}
/>
);
expect(component.find(Settings).prop('xDomain')).toMatchInlineSnapshot(`
Object {
"max": 1546491600000,
"min": 1546405200000,
"minInterval": undefined,
}
`);
});
}); });
test('it does not use date range if the x is not a time scale', () => { test('it does not use date range if the x is not a time scale', () => {
@ -698,7 +580,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -716,7 +598,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -737,7 +619,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -758,7 +640,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -784,7 +666,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -808,7 +690,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -893,7 +775,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -945,7 +827,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -983,7 +865,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1004,7 +886,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1028,7 +910,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1061,7 +943,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1081,7 +963,7 @@ describe('xy_expression', () => {
timeZone="CEST" timeZone="CEST"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1107,7 +989,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1127,7 +1009,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1150,7 +1032,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1178,7 +1060,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1200,7 +1082,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1601,7 +1483,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1621,7 +1503,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1641,7 +1523,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1660,7 +1542,7 @@ describe('xy_expression', () => {
formatFactory={getFormatSpy} formatFactory={getFormatSpy}
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
timeZone="UTC" timeZone="UTC"
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
@ -1683,7 +1565,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1718,7 +1600,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1751,7 +1633,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1784,7 +1666,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1817,7 +1699,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1917,7 +1799,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -1991,7 +1873,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2063,7 +1945,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2087,7 +1969,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2110,7 +1992,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2133,7 +2015,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2168,7 +2050,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2195,7 +2077,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2217,7 +2099,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2244,7 +2126,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2277,7 +2159,7 @@ describe('xy_expression', () => {
timeZone="UTC" timeZone="UTC"
chartsThemeService={chartsThemeService} chartsThemeService={chartsThemeService}
paletteService={paletteService} paletteService={paletteService}
histogramBarTarget={50} minInterval={50}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -2288,4 +2170,47 @@ describe('xy_expression', () => {
}); });
}); });
}); });
describe('calculateMinInterval', () => {
let xyProps: XYChartProps;
beforeEach(() => {
xyProps = sampleArgs();
xyProps.args.layers[0].xScaleType = 'time';
});
it('should use first valid layer and determine interval', async () => {
const result = await calculateMinInterval(
xyProps,
jest.fn().mockResolvedValue({ interval: '5m' })
);
expect(result).toEqual(5 * 60 * 1000);
});
it('should return undefined if data table is empty', async () => {
xyProps.data.tables.first.rows = [];
const result = await calculateMinInterval(
xyProps,
jest.fn().mockResolvedValue({ interval: '5m' })
);
expect(result).toEqual(undefined);
});
it('should return undefined if interval can not be checked', async () => {
const result = await calculateMinInterval(xyProps, jest.fn().mockResolvedValue(undefined));
expect(result).toEqual(undefined);
});
it('should return undefined if date column is not found', async () => {
xyProps.data.tables.first.columns.splice(2, 1);
const result = await calculateMinInterval(xyProps, jest.fn().mockResolvedValue(undefined));
expect(result).toEqual(undefined);
});
it('should return undefined if x axis is not a date', async () => {
xyProps.args.layers[0].xScaleType = 'ordinal';
xyProps.data.tables.first.columns.splice(2, 1);
const result = await calculateMinInterval(xyProps, jest.fn().mockResolvedValue(undefined));
expect(result).toEqual(undefined);
});
});
}); });

View file

@ -8,7 +8,6 @@ import './expression.scss';
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import moment from 'moment';
import { import {
Chart, Chart,
Settings, Settings,
@ -39,10 +38,14 @@ import {
LensFilterEvent, LensFilterEvent,
LensBrushEvent, LensBrushEvent,
} from '../types'; } from '../types';
import { XYArgs, SeriesType, visualizationTypes } from './types'; import { XYArgs, SeriesType, visualizationTypes, LayerArgs } from './types';
import { VisualizationContainer } from '../visualization_container'; import { VisualizationContainer } from '../visualization_container';
import { isHorizontalChart, getSeriesColor } from './state_helpers'; import { isHorizontalChart, getSeriesColor } from './state_helpers';
import { ExpressionValueSearchContext, search } from '../../../../../src/plugins/data/public'; import {
DataPublicPluginStart,
ExpressionValueSearchContext,
search,
} from '../../../../../src/plugins/data/public';
import { import {
ChartsPluginSetup, ChartsPluginSetup,
PaletteRegistry, PaletteRegistry,
@ -75,7 +78,7 @@ type XYChartRenderProps = XYChartProps & {
paletteService: PaletteRegistry; paletteService: PaletteRegistry;
formatFactory: FormatFactory; formatFactory: FormatFactory;
timeZone: string; timeZone: string;
histogramBarTarget: number; minInterval: number | undefined;
onClickValue: (data: LensFilterEvent['data']) => void; onClickValue: (data: LensFilterEvent['data']) => void;
onSelectRange: (data: LensBrushEvent['data']) => void; onSelectRange: (data: LensBrushEvent['data']) => void;
}; };
@ -174,11 +177,31 @@ export const xyChart: ExpressionFunctionDefinition<
}, },
}; };
export async function calculateMinInterval(
{ args: { layers }, data }: XYChartProps,
getIntervalByColumn: DataPublicPluginStart['search']['aggs']['getDateMetaByDatatableColumn']
) {
const filteredLayers = getFilteredLayers(layers, data);
if (filteredLayers.length === 0) return;
const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time');
if (!isTimeViz) return;
const dateColumn = data.tables[filteredLayers[0].layerId].columns.find(
(column) => column.id === filteredLayers[0].xAccessor
);
if (!dateColumn) return;
const dateMetaData = await getIntervalByColumn(dateColumn);
if (!dateMetaData) return;
const intervalDuration = search.aggs.parseInterval(dateMetaData.interval);
if (!intervalDuration) return;
return intervalDuration.as('milliseconds');
}
export const getXyChartRenderer = (dependencies: { export const getXyChartRenderer = (dependencies: {
formatFactory: Promise<FormatFactory>; formatFactory: Promise<FormatFactory>;
chartsThemeService: ChartsPluginSetup['theme']; chartsThemeService: ChartsPluginSetup['theme'];
paletteService: PaletteRegistry; paletteService: PaletteRegistry;
histogramBarTarget: number; getIntervalByColumn: DataPublicPluginStart['search']['aggs']['getDateMetaByDatatableColumn'];
timeZone: string; timeZone: string;
}): ExpressionRenderDefinition<XYChartProps> => ({ }): ExpressionRenderDefinition<XYChartProps> => ({
name: 'lens_xy_chart_renderer', name: 'lens_xy_chart_renderer',
@ -209,7 +232,7 @@ export const getXyChartRenderer = (dependencies: {
chartsThemeService={dependencies.chartsThemeService} chartsThemeService={dependencies.chartsThemeService}
paletteService={dependencies.paletteService} paletteService={dependencies.paletteService}
timeZone={dependencies.timeZone} timeZone={dependencies.timeZone}
histogramBarTarget={dependencies.histogramBarTarget} minInterval={await calculateMinInterval(config, dependencies.getIntervalByColumn)}
onClickValue={onClickValue} onClickValue={onClickValue}
onSelectRange={onSelectRange} onSelectRange={onSelectRange}
/> />
@ -277,7 +300,7 @@ export function XYChart({
timeZone, timeZone,
chartsThemeService, chartsThemeService,
paletteService, paletteService,
histogramBarTarget, minInterval,
onClickValue, onClickValue,
onSelectRange, onSelectRange,
}: XYChartRenderProps) { }: XYChartRenderProps) {
@ -285,19 +308,7 @@ export function XYChart({
const chartTheme = chartsThemeService.useChartsTheme(); const chartTheme = chartsThemeService.useChartsTheme();
const chartBaseTheme = chartsThemeService.useChartsBaseTheme(); const chartBaseTheme = chartsThemeService.useChartsBaseTheme();
const filteredLayers = layers.filter(({ layerId, xAccessor, accessors, splitAccessor }) => { const filteredLayers = getFilteredLayers(layers, data);
return !(
!accessors.length ||
!data.tables[layerId] ||
data.tables[layerId].rows.length === 0 ||
(xAccessor &&
data.tables[layerId].rows.every((row) => typeof row[xAccessor] === 'undefined')) ||
// stacked percentage bars have no xAccessors but splitAccessor with undefined values in them when empty
(!xAccessor &&
splitAccessor &&
data.tables[layerId].rows.every((row) => typeof row[splitAccessor] === 'undefined'))
);
});
if (filteredLayers.length === 0) { if (filteredLayers.length === 0) {
const icon: IconType = layers.length > 0 ? getIconForSeriesType(layers[0].seriesType) : 'bar'; const icon: IconType = layers.length > 0 ? getIconForSeriesType(layers[0].seriesType) : 'bar';
@ -348,37 +359,6 @@ export function XYChart({
filteredBarLayers.some((layer) => layer.accessors.length > 1) || filteredBarLayers.some((layer) => layer.accessors.length > 1) ||
filteredBarLayers.some((layer) => layer.splitAccessor); filteredBarLayers.some((layer) => layer.splitAccessor);
function calculateMinInterval() {
// check all the tables to see if all of the rows have the same timestamp
// that would mean that chart will draw a single bar
const isSingleTimestampInXDomain = () => {
const firstRowValue =
data.tables[filteredLayers[0].layerId].rows[0][filteredLayers[0].xAccessor!];
for (const layer of filteredLayers) {
if (
layer.xAccessor &&
data.tables[layer.layerId].rows.some((row) => row[layer.xAccessor!] !== firstRowValue)
) {
return false;
}
}
return true;
};
// add minInterval only for single point in domain
if (data.dateRange && isSingleTimestampInXDomain()) {
const params = xAxisColumn?.meta?.sourceParams?.params as Record<string, string>;
if (params?.interval !== 'auto')
return search.aggs.parseInterval(params?.interval)?.asMilliseconds();
const { fromDate, toDate } = data.dateRange;
const duration = moment(toDate).diff(moment(fromDate));
const targetMs = duration / histogramBarTarget;
return isNaN(targetMs) ? 0 : Math.max(Math.floor(targetMs), 1);
}
return undefined;
}
const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time'); const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time');
const isHistogramViz = filteredLayers.every((l) => l.isHistogram); const isHistogramViz = filteredLayers.every((l) => l.isHistogram);
@ -386,7 +366,7 @@ export function XYChart({
? { ? {
min: data.dateRange?.fromDate.getTime(), min: data.dateRange?.fromDate.getTime(),
max: data.dateRange?.toDate.getTime(), max: data.dateRange?.toDate.getTime(),
minInterval: calculateMinInterval(), minInterval,
} }
: undefined; : undefined;
@ -802,6 +782,22 @@ export function XYChart({
); );
} }
function getFilteredLayers(layers: LayerArgs[], data: LensMultiTable) {
return layers.filter(({ layerId, xAccessor, accessors, splitAccessor }) => {
return !(
!accessors.length ||
!data.tables[layerId] ||
data.tables[layerId].rows.length === 0 ||
(xAccessor &&
data.tables[layerId].rows.every((row) => typeof row[xAccessor] === 'undefined')) ||
// stacked percentage bars have no xAccessors but splitAccessor with undefined values in them when empty
(!xAccessor &&
splitAccessor &&
data.tables[layerId].rows.every((row) => typeof row[splitAccessor] === 'undefined'))
);
});
}
function assertNever(x: never): never { function assertNever(x: never): never {
throw new Error('Unexpected series type: ' + x); throw new Error('Unexpected series type: ' + x);
} }

View file

@ -7,7 +7,6 @@
import { CoreSetup, IUiSettingsClient } from 'kibana/public'; import { CoreSetup, IUiSettingsClient } from 'kibana/public';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public';
import { UI_SETTINGS } from '../../../../../src/plugins/data/public';
import { EditorFrameSetup, FormatFactory } from '../types'; import { EditorFrameSetup, FormatFactory } from '../types';
import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public';
import { LensPluginStartDependencies } from '../plugin'; import { LensPluginStartDependencies } from '../plugin';
@ -63,7 +62,7 @@ export class XyVisualization {
chartsThemeService: charts.theme, chartsThemeService: charts.theme,
paletteService: palettes, paletteService: palettes,
timeZone: getTimeZone(core.uiSettings), timeZone: getTimeZone(core.uiSettings),
histogramBarTarget: core.uiSettings.get<number>(UI_SETTINGS.HISTOGRAM_BAR_TARGET), getIntervalByColumn: data.search.aggs.getDateMetaByDatatableColumn,
}) })
); );
return getXyVisualization({ paletteService: palettes, data }); return getXyVisualization({ paletteService: palettes, data });