Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Pass used histogram interval to chart #91370

Merged
merged 10 commits into from
Feb 19, 2021
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 @@ -2647,21 +2648,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