mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Lens] Pass used histogram interval to chart (#91370)
This commit is contained in:
parent
494d1decf5
commit
bf7fdfc87c
11 changed files with 308 additions and 38 deletions
|
@ -46,6 +46,7 @@ search: {
|
||||||
boundLabel: string;
|
boundLabel: string;
|
||||||
intervalLabel: string;
|
intervalLabel: string;
|
||||||
})[];
|
})[];
|
||||||
|
getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined;
|
||||||
};
|
};
|
||||||
getRequestInspectorStats: typeof getRequestInspectorStats;
|
getRequestInspectorStats: typeof getRequestInspectorStats;
|
||||||
getResponseInspectorStats: typeof getResponseInspectorStats;
|
getResponseInspectorStats: typeof getResponseInspectorStats;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { AggTypesDependencies } from '../agg_types';
|
||||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||||
import { IBucketHistogramAggConfig, getHistogramBucketAgg, AutoBounds } from './histogram';
|
import { IBucketHistogramAggConfig, getHistogramBucketAgg, AutoBounds } from './histogram';
|
||||||
import { BucketAggType } from './bucket_agg_type';
|
import { BucketAggType } from './bucket_agg_type';
|
||||||
|
import { SerializableState } from 'src/plugins/expressions/common';
|
||||||
|
|
||||||
describe('Histogram Agg', () => {
|
describe('Histogram Agg', () => {
|
||||||
let aggTypesDependencies: AggTypesDependencies;
|
let aggTypesDependencies: AggTypesDependencies;
|
||||||
|
@ -230,6 +231,27 @@ describe('Histogram Agg', () => {
|
||||||
expect(params.interval).toBeNaN();
|
expect(params.interval).toBeNaN();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('will serialize the auto interval along with the actually chosen interval and deserialize correctly', () => {
|
||||||
|
const aggConfigs = getAggConfigs({
|
||||||
|
interval: 'auto',
|
||||||
|
field: {
|
||||||
|
name: 'field',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
(aggConfigs.aggs[0] as IBucketHistogramAggConfig).setAutoBounds({ min: 0, max: 1000 });
|
||||||
|
const serializedAgg = aggConfigs.aggs[0].serialize();
|
||||||
|
const serializedIntervalParam = (serializedAgg.params as SerializableState).used_interval;
|
||||||
|
expect(serializedIntervalParam).toBe(500);
|
||||||
|
const freshHistogramAggConfig = getAggConfigs({
|
||||||
|
interval: 100,
|
||||||
|
field: {
|
||||||
|
name: 'field',
|
||||||
|
},
|
||||||
|
}).aggs[0];
|
||||||
|
freshHistogramAggConfig.setParams(serializedAgg.params);
|
||||||
|
expect(freshHistogramAggConfig.getParam('interval')).toEqual('auto');
|
||||||
|
});
|
||||||
|
|
||||||
describe('interval scaling', () => {
|
describe('interval scaling', () => {
|
||||||
const getInterval = (
|
const getInterval = (
|
||||||
maxBars: number,
|
maxBars: number,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
|
import { IUiSettingsClient } from 'kibana/public';
|
||||||
|
|
||||||
import { KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common';
|
import { KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common';
|
||||||
import { AggTypesDependencies } from '../agg_types';
|
import { AggTypesDependencies } from '../agg_types';
|
||||||
|
@ -39,6 +40,7 @@ export interface IBucketHistogramAggConfig extends IBucketAggConfig {
|
||||||
export interface AggParamsHistogram extends BaseAggParams {
|
export interface AggParamsHistogram extends BaseAggParams {
|
||||||
field: string;
|
field: string;
|
||||||
interval: number | string;
|
interval: number | string;
|
||||||
|
used_interval?: number | string;
|
||||||
maxBars?: number;
|
maxBars?: number;
|
||||||
intervalBase?: number;
|
intervalBase?: number;
|
||||||
min_doc_count?: boolean;
|
min_doc_count?: boolean;
|
||||||
|
@ -141,18 +143,23 @@ export const getHistogramBucketAgg = ({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
write(aggConfig, output) {
|
write(aggConfig, output) {
|
||||||
const values = aggConfig.getAutoBounds();
|
output.params.interval = calculateInterval(aggConfig, getConfig);
|
||||||
|
|
||||||
output.params.interval = calculateHistogramInterval({
|
|
||||||
values,
|
|
||||||
interval: aggConfig.params.interval,
|
|
||||||
maxBucketsUiSettings: getConfig(UI_SETTINGS.HISTOGRAM_MAX_BARS),
|
|
||||||
maxBucketsUserInput: aggConfig.params.maxBars,
|
|
||||||
intervalBase: aggConfig.params.intervalBase,
|
|
||||||
esTypes: aggConfig.params.field?.spec?.esTypes || [],
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'used_interval',
|
||||||
|
default: autoInterval,
|
||||||
|
shouldShow() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
write: () => {},
|
||||||
|
serialize(val, aggConfig) {
|
||||||
|
if (!aggConfig) return undefined;
|
||||||
|
// store actually used auto interval in serialized agg config to be able to read it from the result data table meta information
|
||||||
|
return calculateInterval(aggConfig, getConfig);
|
||||||
|
},
|
||||||
|
toExpressionAst: () => undefined,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'maxBars',
|
name: 'maxBars',
|
||||||
shouldShow(agg) {
|
shouldShow(agg) {
|
||||||
|
@ -193,3 +200,18 @@ export const getHistogramBucketAgg = ({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function calculateInterval(
|
||||||
|
aggConfig: IBucketHistogramAggConfig,
|
||||||
|
getConfig: IUiSettingsClient['get']
|
||||||
|
): any {
|
||||||
|
const values = aggConfig.getAutoBounds();
|
||||||
|
return calculateHistogramInterval({
|
||||||
|
values,
|
||||||
|
interval: aggConfig.params.interval,
|
||||||
|
maxBucketsUiSettings: getConfig(UI_SETTINGS.HISTOGRAM_MAX_BARS),
|
||||||
|
maxBucketsUserInput: aggConfig.params.maxBars,
|
||||||
|
intervalBase: aggConfig.params.intervalBase,
|
||||||
|
esTypes: aggConfig.params.field?.spec?.esTypes || [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getNumberHistogramIntervalByDatatableColumn } from '.';
|
||||||
|
import { BUCKET_TYPES } from '../buckets';
|
||||||
|
|
||||||
|
describe('getNumberHistogramIntervalByDatatableColumn', () => {
|
||||||
|
it('returns nothing on column from other data source', () => {
|
||||||
|
expect(
|
||||||
|
getNumberHistogramIntervalByDatatableColumn({
|
||||||
|
id: 'test',
|
||||||
|
name: 'test',
|
||||||
|
meta: {
|
||||||
|
type: 'date',
|
||||||
|
source: 'essql',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns nothing on non histogram column', () => {
|
||||||
|
expect(
|
||||||
|
getNumberHistogramIntervalByDatatableColumn({
|
||||||
|
id: 'test',
|
||||||
|
name: 'test',
|
||||||
|
meta: {
|
||||||
|
type: 'date',
|
||||||
|
source: 'esaggs',
|
||||||
|
sourceParams: {
|
||||||
|
type: BUCKET_TYPES.TERMS,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns interval on resolved auto interval', () => {
|
||||||
|
expect(
|
||||||
|
getNumberHistogramIntervalByDatatableColumn({
|
||||||
|
id: 'test',
|
||||||
|
name: 'test',
|
||||||
|
meta: {
|
||||||
|
type: 'date',
|
||||||
|
source: 'esaggs',
|
||||||
|
sourceParams: {
|
||||||
|
type: BUCKET_TYPES.HISTOGRAM,
|
||||||
|
params: {
|
||||||
|
interval: 'auto',
|
||||||
|
used_interval: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns interval on fixed interval', () => {
|
||||||
|
expect(
|
||||||
|
getNumberHistogramIntervalByDatatableColumn({
|
||||||
|
id: 'test',
|
||||||
|
name: 'test',
|
||||||
|
meta: {
|
||||||
|
type: 'date',
|
||||||
|
source: 'esaggs',
|
||||||
|
sourceParams: {
|
||||||
|
type: BUCKET_TYPES.HISTOGRAM,
|
||||||
|
params: {
|
||||||
|
interval: 7,
|
||||||
|
used_interval: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns undefined if information is not available', () => {
|
||||||
|
expect(
|
||||||
|
getNumberHistogramIntervalByDatatableColumn({
|
||||||
|
id: 'test',
|
||||||
|
name: 'test',
|
||||||
|
meta: {
|
||||||
|
type: 'date',
|
||||||
|
source: 'esaggs',
|
||||||
|
sourceParams: {
|
||||||
|
type: BUCKET_TYPES.HISTOGRAM,
|
||||||
|
params: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toEqual(undefined);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { DatatableColumn } from 'src/plugins/expressions/common';
|
||||||
|
import type { AggParamsHistogram } from '../buckets';
|
||||||
|
import { BUCKET_TYPES } from '../buckets/bucket_agg_types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function returning the used interval for data table column created by the histogramm agg type.
|
||||||
|
* "auto" will get expanded to the actually used interval.
|
||||||
|
* If the column is not a column created by a histogram aggregation of the esaggs data source,
|
||||||
|
* this function will return undefined.
|
||||||
|
*/
|
||||||
|
export const getNumberHistogramIntervalByDatatableColumn = (column: DatatableColumn) => {
|
||||||
|
if (column.meta.source !== 'esaggs') return;
|
||||||
|
if (column.meta.sourceParams?.type !== BUCKET_TYPES.HISTOGRAM) return;
|
||||||
|
const params = (column.meta.sourceParams.params as unknown) as AggParamsHistogram;
|
||||||
|
|
||||||
|
if (!params.used_interval || typeof params.used_interval === 'string') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return params.used_interval;
|
||||||
|
};
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export * from './calculate_auto_time_expression';
|
export * from './calculate_auto_time_expression';
|
||||||
|
export { getNumberHistogramIntervalByDatatableColumn } from './get_number_histogram_interval';
|
||||||
export * from './date_interval_utils';
|
export * from './date_interval_utils';
|
||||||
export * from './get_format_with_aggs';
|
export * from './get_format_with_aggs';
|
||||||
export * from './ipv4_address';
|
export * from './ipv4_address';
|
||||||
|
|
|
@ -308,6 +308,7 @@ import {
|
||||||
parseInterval,
|
parseInterval,
|
||||||
toAbsoluteDates,
|
toAbsoluteDates,
|
||||||
boundsDescendingRaw,
|
boundsDescendingRaw,
|
||||||
|
getNumberHistogramIntervalByDatatableColumn,
|
||||||
// expressions utils
|
// expressions utils
|
||||||
getRequestInspectorStats,
|
getRequestInspectorStats,
|
||||||
getResponseInspectorStats,
|
getResponseInspectorStats,
|
||||||
|
@ -417,6 +418,7 @@ export const search = {
|
||||||
termsAggFilter,
|
termsAggFilter,
|
||||||
toAbsoluteDates,
|
toAbsoluteDates,
|
||||||
boundsDescendingRaw,
|
boundsDescendingRaw,
|
||||||
|
getNumberHistogramIntervalByDatatableColumn,
|
||||||
},
|
},
|
||||||
getRequestInspectorStats,
|
getRequestInspectorStats,
|
||||||
getResponseInspectorStats,
|
getResponseInspectorStats,
|
||||||
|
|
|
@ -2238,6 +2238,7 @@ export const search: {
|
||||||
boundLabel: string;
|
boundLabel: string;
|
||||||
intervalLabel: string;
|
intervalLabel: string;
|
||||||
})[];
|
})[];
|
||||||
|
getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined;
|
||||||
};
|
};
|
||||||
getRequestInspectorStats: typeof getRequestInspectorStats;
|
getRequestInspectorStats: typeof getRequestInspectorStats;
|
||||||
getResponseInspectorStats: typeof getResponseInspectorStats;
|
getResponseInspectorStats: typeof getResponseInspectorStats;
|
||||||
|
@ -2649,21 +2650,21 @@ export const UI_SETTINGS: {
|
||||||
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:398:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:399:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "Ipv4Address" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:414:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:417:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:418:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:418:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:419:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:421:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:422:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:423:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/index.ts:425:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/index.ts:426:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:34:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:34:5 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
|
||||||
// src/plugins/data/public/search/session/session_service.ts:42:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts
|
// src/plugins/data/public/search/session/session_service.ts:42:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,13 @@ exports[`xy_expression XYChart component it renders area 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -222,6 +229,13 @@ exports[`xy_expression XYChart component it renders bar 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -426,6 +440,13 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -630,6 +651,13 @@ exports[`xy_expression XYChart component it renders line 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -826,6 +854,13 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -1030,6 +1065,13 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = `
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
@ -1242,6 +1284,13 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] =
|
||||||
"headerFormatter": [Function],
|
"headerFormatter": [Function],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xDomain={
|
||||||
|
Object {
|
||||||
|
"max": undefined,
|
||||||
|
"min": undefined,
|
||||||
|
"minInterval": 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Connect(SpecInstance)
|
<Connect(SpecInstance)
|
||||||
gridLine={
|
gridLine={
|
||||||
|
|
|
@ -570,7 +570,30 @@ describe('xy_expression', () => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
expect(component.find(Settings).prop('xDomain')).toBeUndefined();
|
const xDomain = component.find(Settings).prop('xDomain');
|
||||||
|
expect(xDomain).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
min: undefined,
|
||||||
|
max: undefined,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it uses min interval if passed in', () => {
|
||||||
|
const { data, args } = sampleArgs();
|
||||||
|
|
||||||
|
const component = shallow(
|
||||||
|
<XYChart
|
||||||
|
{...defaultProps}
|
||||||
|
minInterval={101}
|
||||||
|
data={data}
|
||||||
|
args={{
|
||||||
|
...args,
|
||||||
|
layers: [{ ...args.layers[0], seriesType: 'line', xScaleType: 'linear' }],
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(component.find(Settings).prop('xDomain')).toEqual({ minInterval: 101 });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it renders bar', () => {
|
test('it renders bar', () => {
|
||||||
|
@ -1881,6 +1904,24 @@ describe('xy_expression', () => {
|
||||||
expect(result).toEqual(5 * 60 * 1000);
|
expect(result).toEqual(5 * 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return interval of number histogram if available on first x axis columns', async () => {
|
||||||
|
xyProps.args.layers[0].xScaleType = 'linear';
|
||||||
|
xyProps.data.tables.first.columns[2].meta = {
|
||||||
|
source: 'esaggs',
|
||||||
|
type: 'number',
|
||||||
|
field: 'someField',
|
||||||
|
sourceParams: {
|
||||||
|
type: 'histogram',
|
||||||
|
params: {
|
||||||
|
interval: 'auto',
|
||||||
|
used_interval: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = await calculateMinInterval(xyProps, jest.fn().mockResolvedValue(undefined));
|
||||||
|
expect(result).toEqual(5);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return undefined if data table is empty', async () => {
|
it('should return undefined if data table is empty', async () => {
|
||||||
xyProps.data.tables.first.rows = [];
|
xyProps.data.tables.first.rows = [];
|
||||||
const result = await calculateMinInterval(
|
const result = await calculateMinInterval(
|
||||||
|
|
|
@ -199,13 +199,20 @@ export async function calculateMinInterval(
|
||||||
const filteredLayers = getFilteredLayers(layers, data);
|
const filteredLayers = getFilteredLayers(layers, data);
|
||||||
if (filteredLayers.length === 0) return;
|
if (filteredLayers.length === 0) return;
|
||||||
const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time');
|
const isTimeViz = data.dateRange && filteredLayers.every((l) => l.xScaleType === 'time');
|
||||||
|
const xColumn = data.tables[filteredLayers[0].layerId].columns.find(
|
||||||
if (!isTimeViz) return;
|
|
||||||
const dateColumn = data.tables[filteredLayers[0].layerId].columns.find(
|
|
||||||
(column) => column.id === filteredLayers[0].xAccessor
|
(column) => column.id === filteredLayers[0].xAccessor
|
||||||
);
|
);
|
||||||
if (!dateColumn) return;
|
|
||||||
const dateMetaData = await getIntervalByColumn(dateColumn);
|
if (!xColumn) return;
|
||||||
|
if (!isTimeViz) {
|
||||||
|
const histogramInterval = search.aggs.getNumberHistogramIntervalByDatatableColumn(xColumn);
|
||||||
|
if (typeof histogramInterval === 'number') {
|
||||||
|
return histogramInterval;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dateMetaData = await getIntervalByColumn(xColumn);
|
||||||
if (!dateMetaData) return;
|
if (!dateMetaData) return;
|
||||||
const intervalDuration = search.aggs.parseInterval(dateMetaData.interval);
|
const intervalDuration = search.aggs.parseInterval(dateMetaData.interval);
|
||||||
if (!intervalDuration) return;
|
if (!intervalDuration) return;
|
||||||
|
@ -381,13 +388,11 @@ export function XYChart({
|
||||||
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);
|
||||||
|
|
||||||
const xDomain = isTimeViz
|
const xDomain = {
|
||||||
? {
|
min: isTimeViz ? data.dateRange?.fromDate.getTime() : undefined,
|
||||||
min: data.dateRange?.fromDate.getTime(),
|
max: isTimeViz ? data.dateRange?.toDate.getTime() : undefined,
|
||||||
max: data.dateRange?.toDate.getTime(),
|
minInterval,
|
||||||
minInterval,
|
};
|
||||||
}
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const getYAxesTitles = (
|
const getYAxesTitles = (
|
||||||
axisSeries: Array<{ layer: string; accessor: string }>,
|
axisSeries: Array<{ layer: string; accessor: string }>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue