fix cumulative sum and value count (#138246)

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Joe Reuter 2022-08-09 10:34:41 +02:00 committed by GitHub
parent 85af901205
commit 7cc9e96cb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 6 deletions

View file

@ -19,6 +19,7 @@ import {
import { OperationDefinition } from '..';
import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers';
import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils';
import { DOCUMENT_FIELD_NAME } from '../../../../../common';
const ofName = buildLabelFunction((name?: string) => {
return i18n.translate('xpack.lens.indexPattern.cumulativeSumOf', {
@ -53,7 +54,11 @@ export const cumulativeSumOperation: OperationDefinition<
{
input: ['field', 'managedReference'],
specificOperations: ['count', 'sum'],
validateMetadata: (meta) => meta.dataType === 'number' && !meta.isBucketed,
validateMetadata: (meta, operationType, fieldName) =>
meta.dataType === 'number' &&
!meta.isBucketed &&
// exclude value counts
!(operationType === 'count' && fieldName !== DOCUMENT_FIELD_NAME),
},
],
getPossibleOperation: (indexPattern) => {

View file

@ -563,7 +563,11 @@ export interface RequiredReference {
// Limit the input types, usually used to prevent other references from being used
input: Array<GenericOperationDefinition['input']>;
// Function which is used to determine if the reference is bucketed, or if it's a number
validateMetadata: (metadata: OperationMetadata) => boolean;
validateMetadata: (
metadata: OperationMetadata,
operation?: OperationType,
field?: string
) => boolean;
// Do not use specificOperations unless you need to limit to only one or two exact
// operation types. The main use case is Cumulative Sum, where we need to only take the
// sum of Count or sum of Sum.

View file

@ -1516,6 +1516,42 @@ describe('state_helpers', () => {
);
});
it('should not wrap around the previous operation as a reference if excluded by validateMetadata (case new1)', () => {
const layer: IndexPatternLayer = {
indexPatternId: '1',
columnOrder: ['col1'],
columns: {
col1: {
label: 'Count',
customLabel: true,
dataType: 'number' as const,
isBucketed: false,
sourceField: 'bytes',
operationType: 'count' as const,
},
},
};
const result = replaceColumn({
layer,
indexPattern,
columnId: 'col1',
op: 'cumulative_sum' as OperationType,
visualizationGroups: [],
});
expect(result.columnOrder).toEqual(['col1', 'id1']);
expect(result.columns).toEqual(
expect.objectContaining({
id1: expect.objectContaining({
label: 'Sum of bytes',
sourceField: 'bytes',
operationType: 'sum' as const,
}),
col1: expect.any(Object),
})
);
});
it('should remove filter from the wrapped column if it gets wrapped (case new1)', () => {
const expectedColumn = {
label: 'Count',

View file

@ -1516,13 +1516,14 @@ export function isOperationAllowedAsReference({
let hasValidMetadata = true;
if (field && operationDefinition.input === 'field') {
const metadata = operationDefinition.getPossibleOperationForField(field);
hasValidMetadata = Boolean(metadata) && validation.validateMetadata(metadata!);
hasValidMetadata =
Boolean(metadata) && validation.validateMetadata(metadata!, operationType, field.name);
} else if (operationDefinition.input === 'none') {
const metadata = operationDefinition.getPossibleOperation();
hasValidMetadata = Boolean(metadata) && validation.validateMetadata(metadata!);
hasValidMetadata = Boolean(metadata) && validation.validateMetadata(metadata!, operationType);
} else if (operationDefinition.input === 'fullReference') {
const metadata = operationDefinition.getPossibleOperation(indexPattern);
hasValidMetadata = Boolean(metadata) && validation.validateMetadata(metadata!);
hasValidMetadata = Boolean(metadata) && validation.validateMetadata(metadata!, operationType);
} else {
// TODO: How can we validate the metadata without a specific field?
}
@ -1598,7 +1599,11 @@ export function isColumnValidAsReference({
column,
validation,
}) &&
validation.validateMetadata(column)
validation.validateMetadata(
column,
operationType,
'sourceField' in column ? column.sourceField : undefined
)
);
}