From 8adb16b6628506a78c9d734ec60589a6030dbe39 Mon Sep 17 00:00:00 2001 From: hugofqt <12221094+hugo082@users.noreply.github.com> Date: Tue, 20 Dec 2022 21:25:55 +0100 Subject: [PATCH] Transformations: Grouping to matrix empty value option (#55591) * feat: grouping matrix transformer empty value Allow grouping matrix data transformer to define the value used when the matrix entry is not defined * fix: grouping to matrix empty value test * remove balel width for empty value text Co-authored-by: bohandley --- .../transformers/groupingToMatrix.test.ts | 45 ++++++++++++++++++- .../transformers/groupingToMatrix.ts | 21 ++++++++- .../grafana-data/src/types/transformations.ts | 10 +++++ .../GroupingToMatrixTransformerEditor.tsx | 21 +++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts index b8b10dae669..781d2401095 100644 --- a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts +++ b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.test.ts @@ -1,5 +1,5 @@ import { toDataFrame } from '../../dataframe'; -import { DataTransformerConfig, FieldType, Field } from '../../types'; +import { DataTransformerConfig, FieldType, Field, SpecialValue } from '../../types'; import { mockTransformationsRegistry } from '../../utils/tests/mockTransformationsRegistry'; import { ArrayVector } from '../../vector'; import { transformDataFrame } from '../transformDataFrame'; @@ -105,6 +105,49 @@ describe('Grouping to Matrix', () => { }); }); + it('generates Matrix with empty entries', async () => { + const cfg: DataTransformerConfig = { + id: DataTransformerID.groupingToMatrix, + options: { + emptyValue: SpecialValue.Null, + }, + }; + + const seriesA = toDataFrame({ + name: 'A', + fields: [ + { name: 'Time', type: FieldType.time, values: [1000, 1001] }, + { name: 'Value', type: FieldType.number, values: [1, 2] }, + ], + }); + + await expect(transformDataFrame([cfg], [seriesA])).toEmitValuesWith((received) => { + const processed = received[0]; + const expected: Field[] = [ + { + name: 'Time\\Time', + type: FieldType.string, + values: new ArrayVector([1000, 1001]), + config: {}, + }, + { + name: '1000', + type: FieldType.number, + values: new ArrayVector([1, null]), + config: {}, + }, + { + name: '1001', + type: FieldType.number, + values: new ArrayVector([null, 2]), + config: {}, + }, + ]; + + expect(processed[0].fields).toEqual(expected); + }); + }); + it('generates Matrix with multiple fields and value type', async () => { const cfg: DataTransformerConfig = { id: DataTransformerID.groupingToMatrix, diff --git a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts index b73b6cf0520..85fa47edf15 100644 --- a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts +++ b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts @@ -2,7 +2,7 @@ import { map } from 'rxjs/operators'; import { MutableDataFrame } from '../../dataframe'; import { getFieldDisplayName } from '../../field/fieldState'; -import { DataFrame, DataTransformerInfo, Field, FieldType, Vector } from '../../types'; +import { DataFrame, DataTransformerInfo, Field, FieldType, SpecialValue, Vector } from '../../types'; import { DataTransformerID } from './ids'; @@ -10,11 +10,13 @@ export interface GroupingToMatrixTransformerOptions { columnField?: string; rowField?: string; valueField?: string; + emptyValue?: SpecialValue; } const DEFAULT_COLUMN_FIELD = 'Time'; const DEFAULT_ROW_FIELD = 'Time'; const DEFAULT_VALUE_FIELD = 'Value'; +const DEFAULT_EMPTY_VALUE = SpecialValue.Empty; export const groupingToMatrixTransformer: DataTransformerInfo = { id: DataTransformerID.groupingToMatrix, @@ -32,6 +34,7 @@ export const groupingToMatrixTransformer: DataTransformerInfo { id: string; options?: TOptions; } + +/** + * @public + */ +export enum SpecialValue { + True = 'true', + False = 'false', + Null = 'null', + Empty = 'empty', +} diff --git a/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx b/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx index 9ccd7c82b9f..0c6de4a50b0 100644 --- a/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx +++ b/public/app/features/transformers/editors/GroupingToMatrixTransformerEditor.tsx @@ -7,6 +7,7 @@ import { TransformerRegistryItem, TransformerUIProps, GroupingToMatrixTransformerOptions, + SpecialValue, } from '@grafana/data'; import { InlineField, InlineFieldRow, Select } from '@grafana/ui'; @@ -49,6 +50,23 @@ export const GroupingToMatrixTransformerEditor: React.FC> = [ + { label: 'Null', value: SpecialValue.Null, description: 'Null value' }, + { label: 'True', value: SpecialValue.True, description: 'Boolean true value' }, + { label: 'False', value: SpecialValue.False, description: 'Boolean false value' }, + { label: 'Empty', value: SpecialValue.Empty, description: 'Empty string' }, + ]; + + const onSelectEmptyValue = useCallback( + (value: SelectableValue) => { + onChange({ + ...options, + emptyValue: value?.value, + }); + }, + [onChange, options] + ); + return ( <> @@ -61,6 +79,9 @@ export const GroupingToMatrixTransformerEditor: React.FC + );