Skip to content

Commit

Permalink
[Lens] Pass used histogram interval to chart (#91370)
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 committed Feb 19, 2021
1 parent 494d1de commit bf7fdfc
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ search: {
boundLabel: string;
intervalLabel: string;
})[];
getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined;
};
getRequestInspectorStats: typeof getRequestInspectorStats;
getResponseInspectorStats: typeof getResponseInspectorStats;
Expand Down
22 changes: 22 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/histogram.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AggTypesDependencies } from '../agg_types';
import { BUCKET_TYPES } from './bucket_agg_types';
import { IBucketHistogramAggConfig, getHistogramBucketAgg, AutoBounds } from './histogram';
import { BucketAggType } from './bucket_agg_type';
import { SerializableState } from 'src/plugins/expressions/common';

describe('Histogram Agg', () => {
let aggTypesDependencies: AggTypesDependencies;
Expand Down Expand Up @@ -230,6 +231,27 @@ describe('Histogram Agg', () => {
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', () => {
const getInterval = (
maxBars: number,
Expand Down
42 changes: 32 additions & 10 deletions src/plugins/data/common/search/aggs/buckets/histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { IUiSettingsClient } from 'kibana/public';

import { KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common';
import { AggTypesDependencies } from '../agg_types';
Expand Down Expand Up @@ -39,6 +40,7 @@ export interface IBucketHistogramAggConfig extends IBucketAggConfig {
export interface AggParamsHistogram extends BaseAggParams {
field: string;
interval: number | string;
used_interval?: number | string;
maxBars?: number;
intervalBase?: number;
min_doc_count?: boolean;
Expand Down Expand Up @@ -141,17 +143,22 @@ export const getHistogramBucketAgg = ({
});
},
write(aggConfig, output) {
const values = aggConfig.getAutoBounds();

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 || [],
});
output.params.interval = calculateInterval(aggConfig, getConfig);
},
},
{
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',
Expand Down Expand Up @@ -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 || [],
});
}
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
@@ -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;
};
1 change: 1 addition & 0 deletions src/plugins/data/common/search/aggs/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

export * from './calculate_auto_time_expression';
export { getNumberHistogramIntervalByDatatableColumn } from './get_number_histogram_interval';
export * from './date_interval_utils';
export * from './get_format_with_aggs';
export * from './ipv4_address';
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ import {
parseInterval,
toAbsoluteDates,
boundsDescendingRaw,
getNumberHistogramIntervalByDatatableColumn,
// expressions utils
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down Expand Up @@ -417,6 +418,7 @@ export const search = {
termsAggFilter,
toAbsoluteDates,
boundsDescendingRaw,
getNumberHistogramIntervalByDatatableColumn,
},
getRequestInspectorStats,
getResponseInspectorStats,
Expand Down
31 changes: 16 additions & 15 deletions src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2238,6 +2238,7 @@ export const search: {
boundLabel: string;
intervalLabel: string;
})[];
getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined;
};
getRequestInspectorStats: typeof getRequestInspectorStats;
getResponseInspectorStats: typeof getResponseInspectorStats;
Expand Down Expand Up @@ -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 "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: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: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: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: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: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 "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 "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 "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 "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 "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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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/search/session/session_service.ts:42:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts

Expand Down
Loading

0 comments on commit bf7fdfc

Please sign in to comment.