Skip to content

Commit

Permalink
Add new autoExtendBounds setting to histogram agg config (#118855)
Browse files Browse the repository at this point in the history
* add new autoExtendBounds setting to histogram agg config

* show empty rows

* fix tests

* Remove debug

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
flash1293 and kibanamachine authored Mar 17, 2022
1 parent b53dfe7 commit adc17b5
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ export const HeatmapComponent: FC<HeatmapRenderProps> = memo(
return null;
}

let chartData = table.rows.filter((v) => typeof v[valueAccessor!] === 'number');
let chartData = table.rows.filter(
(v) => v[valueAccessor!] === null || typeof v[valueAccessor!] === 'number'
);
if (!chartData || !chartData.length) {
return <EmptyPlaceholder icon={HeatmapIcon} />;
}
Expand Down
17 changes: 17 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 @@ -74,6 +74,9 @@ describe('Histogram Agg', () => {
"chain": Array [
Object {
"arguments": Object {
"autoExtendBounds": Array [
false,
],
"enabled": Array [
true,
],
Expand Down Expand Up @@ -399,6 +402,20 @@ describe('Histogram Agg', () => {
expect(output.extended_bounds).toHaveProperty('max', 100);
});

test('writes when auto bounds and autoExtendBounds are set', () => {
const aggConfigs = getAggConfigs({
autoExtendBounds: true,
field: {
name: 'field',
},
});
(aggConfigs.aggs[0] as IBucketHistogramAggConfig).setAutoBounds({ min: 0, max: 1000 });
const output = aggConfigs.aggs[0].toDsl()[BUCKET_TYPES.HISTOGRAM];

expect(output.extended_bounds).toHaveProperty('min', 0);
expect(output.extended_bounds).toHaveProperty('max', 1000);
});

test('does not write when nothing is set', () => {
const output = getParams({
has_extended_bounds: true,
Expand Down
11 changes: 11 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/histogram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface AggParamsHistogram extends BaseAggParams {
min_doc_count?: boolean;
has_extended_bounds?: boolean;
extended_bounds?: ExtendedBounds;
autoExtendBounds?: boolean;
}

export const getHistogramBucketAgg = ({
Expand Down Expand Up @@ -97,6 +98,14 @@ export const getHistogramBucketAgg = ({
default: null,
write: () => {},
},
{
/*
* Set to true to extend bounds to the domain of the data. This makes sure each interval bucket within these bounds will create a separate table row
*/
name: 'autoExtendBounds',
default: false,
write: () => {},
},
{
name: 'interval',
default: autoInterval,
Expand Down Expand Up @@ -202,6 +211,8 @@ export const getHistogramBucketAgg = ({

if (aggConfig.params.has_extended_bounds && (min || min === 0) && (max || max === 0)) {
output.params.extended_bounds = { min, max };
} else if (aggConfig.params.autoExtendBounds && aggConfig.getAutoBounds()) {
output.params.extended_bounds = aggConfig.getAutoBounds();
}
},
shouldShow: (aggConfig: IBucketAggConfig) => aggConfig.params.has_extended_bounds,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('agg_expression_functions', () => {
"enabled": true,
"id": undefined,
"params": Object {
"autoExtendBounds": undefined,
"customLabel": undefined,
"extended_bounds": undefined,
"field": "field",
Expand All @@ -50,6 +51,7 @@ describe('agg_expression_functions', () => {
maxBars: 25,
min_doc_count: false,
has_extended_bounds: false,
autoExtendBounds: true,
extended_bounds: {
type: 'extended_bounds',
min: 1,
Expand All @@ -62,6 +64,7 @@ describe('agg_expression_functions', () => {
"enabled": true,
"id": undefined,
"params": Object {
"autoExtendBounds": true,
"customLabel": undefined,
"extended_bounds": Object {
"max": 2,
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/data/common/search/aggs/buckets/histogram_fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ export const aggHistogram = (): FunctionDefinition => ({
defaultMessage: 'Calculate interval to get approximately this many bars',
}),
},
autoExtendBounds: {
types: ['boolean'],
help: i18n.translate('data.search.aggs.buckets.histogram.autoExtendBounds.help', {
defaultMessage:
'Set to true to extend bounds to the domain of the data. This makes sure each interval bucket within these bounds will create a separate table row',
}),
},
has_extended_bounds: {
types: ['boolean'],
help: i18n.translate('data.search.aggs.buckets.histogram.hasExtendedBounds.help', {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 expect from '@kbn/expect';
import { ExpectExpression, expectExpressionProvider } from './helpers';
import { FtrProviderContext } from '../../../functional/ftr_provider_context';

export default function ({
getService,
updateBaselines,
}: FtrProviderContext & { updateBaselines: boolean }) {
let expectExpression: ExpectExpression;

describe('esaggs number histogram tests', () => {
before(() => {
expectExpression = expectExpressionProvider({ getService, updateBaselines });
});

const timeRange = {
from: '2015-09-21T00:00:00Z',
to: '2015-09-22T00:00:00Z',
};

it('auto-extends bounds to total range', async () => {
const expression = `
kibana_context timeRange={timerange from='${timeRange.from}' to='${timeRange.to}'}
| esaggs index={indexPatternLoad id='logstash-*'}
aggs={aggTerms id="0" enabled=true schema="bucket" field="extension.raw" size=3}
aggs={aggHistogram id="1" enabled=true schema="bucket" field="bytes" interval=5000 autoExtendBounds=true min_doc_count=true}
aggs={aggCount id="2" enabled=true schema="metric"}
`;
const result = await expectExpression(
'esaggs_histogram_auto_extend',
expression
).getResponse();
expect(result.rows).to.eql([
{ 'col-0-0': 'jpg', 'col-1-1': 0, 'col-2-2': 1251 },
{ 'col-0-0': 'jpg', 'col-1-1': 5000, 'col-2-2': 1759 },
// filling in empty buckets even though the histogram wouldn't extend to those
{ 'col-0-0': 'jpg', 'col-1-1': 10000, 'col-2-2': 0 },
{ 'col-0-0': 'jpg', 'col-1-1': 15000, 'col-2-2': 0 },
{ 'col-0-0': 'css', 'col-1-1': 0, 'col-2-2': 294 },
{ 'col-0-0': 'css', 'col-1-1': 5000, 'col-2-2': 402 },
// filling in empty buckets even though the histogram wouldn't extend to those
{ 'col-0-0': 'css', 'col-1-1': 10000, 'col-2-2': 0 },
{ 'col-0-0': 'css', 'col-1-1': 15000, 'col-2-2': 0 },
{ 'col-0-0': 'png', 'col-1-1': 0, 'col-2-2': 90 },
{ 'col-0-0': 'png', 'col-1-1': 5000, 'col-2-2': 128 },
{ 'col-0-0': 'png', 'col-1-1': 10000, 'col-2-2': 126 },
{ 'col-0-0': 'png', 'col-1-1': 15000, 'col-2-2': 112 },
]);
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid
loadTestFile(require.resolve('./esaggs_significanttext'));
loadTestFile(require.resolve('./esaggs_rareterms'));
loadTestFile(require.resolve('./esaggs_topmetrics'));
loadTestFile(require.resolve('./esaggs_histogram'));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
EuiFormRow,
EuiRange,
EuiToolTip,
EuiSwitch,
EuiSpacer,
} from '@elastic/eui';
import type { IFieldFormat } from 'src/plugins/field_formats/common';
import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/public';
Expand Down Expand Up @@ -83,12 +85,16 @@ const BaseRangeEditor = ({
maxHistogramBars,
onToggleEditor,
onMaxBarsChange,
includeEmptyRows,
onChangeIncludeEmptyRows,
}: {
maxBars: number;
step: number;
maxHistogramBars: number;
onToggleEditor: () => void;
onMaxBarsChange: (newMaxBars: number) => void;
onChangeIncludeEmptyRows: (includeEmptyRows: boolean) => void;
includeEmptyRows?: boolean;
}) => {
const [maxBarsValue, setMaxBarsValue] = useState(String(maxBars));

Expand Down Expand Up @@ -170,6 +176,19 @@ const BaseRangeEditor = ({
defaultMessage: 'Create custom ranges',
})}
</EuiButtonEmpty>
<EuiSpacer size="s" />
<EuiFormRow display="rowCompressed" hasChildLabel={false}>
<EuiSwitch
label={i18n.translate('xpack.lens.indexPattern.ranges.includeEmptyRows', {
defaultMessage: 'Include empty rows',
})}
checked={Boolean(includeEmptyRows)}
onChange={() => {
onChangeIncludeEmptyRows(!includeEmptyRows);
}}
compressed
/>
</EuiFormRow>
</>
);
};
Expand Down Expand Up @@ -211,12 +230,16 @@ export const RangeEditor = ({

return (
<BaseRangeEditor
includeEmptyRows={params.includeEmptyRows}
maxBars={maxBars}
step={granularityStep}
maxHistogramBars={maxHistogramBars}
onMaxBarsChange={(newMaxBars: number) => {
setParam('maxBars', newMaxBars);
}}
onChangeIncludeEmptyRows={(includeEmptyRows: boolean) => {
setParam('includeEmptyRows', includeEmptyRows);
}}
onToggleEditor={() => {
onChangeMode(MODES.Range);
toggleAdvancedEditor(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ describe('ranges', () => {
expect(esAggsFn).toMatchInlineSnapshot(`
Object {
"arguments": Object {
"autoExtendBounds": Array [
false,
],
"enabled": Array [
true,
],
Expand Down Expand Up @@ -254,6 +257,30 @@ describe('ranges', () => {
);
});

it('should reflect show empty rows correctly', () => {
(layer.columns.col1 as RangeIndexPatternColumn).params.maxBars = 10;
(layer.columns.col1 as RangeIndexPatternColumn).params.includeEmptyRows = true;

const esAggsFn = rangeOperation.toEsAggsFn(
layer.columns.col1 as RangeIndexPatternColumn,
'col1',
{} as IndexPattern,
layer,
uiSettingsMock,
[]
);

expect(esAggsFn).toEqual(
expect.objectContaining({
function: 'aggHistogram',
arguments: expect.objectContaining({
autoExtendBounds: [true],
min_doc_count: [true],
}),
})
);
});

it('should reflect the type correctly', () => {
setToRangeMode();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface RangeIndexPatternColumn extends FieldBasedIndexPatternColumn {
maxBars: typeof AUTO_BARS | number;
ranges: RangeTypeLens[];
format?: { id: string; params?: { decimals: number } };
includeEmptyRows?: boolean;
parentFormat?: {
id: string;
params?: { id?: string; template?: string; replaceInfinity?: boolean };
Expand Down Expand Up @@ -112,6 +113,7 @@ export const rangeOperation: OperationDefinition<RangeIndexPatternColumn, 'field
isBucketed: true,
scale: 'interval', // ordinal for Range
params: {
includeEmptyRows: true,
type: MODES.Histogram,
ranges: [{ from: 0, to: DEFAULT_INTERVAL, label: '' }],
maxBars: AUTO_BARS,
Expand Down Expand Up @@ -175,7 +177,8 @@ export const rangeOperation: OperationDefinition<RangeIndexPatternColumn, 'field
maxBars: params.maxBars === AUTO_BARS ? maxBarsDefaultValue : params.maxBars,
interval: 'auto',
has_extended_bounds: false,
min_doc_count: false,
min_doc_count: Boolean(params.includeEmptyRows),
autoExtendBounds: Boolean(params.includeEmptyRows),
extended_bounds: extendedBoundsToAst({}),
}).toAst();
},
Expand Down

0 comments on commit adc17b5

Please sign in to comment.