From bc5ea345e5c9ef7d837e3c1944b2b0cf26cb5364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=A4ggmark?= Date: Tue, 9 Mar 2021 06:02:38 +0100 Subject: [PATCH] ReduceTransform: Include series with numeric string names (#31763) * ReduceTransform: Include series with numeric string names * Chore: updates after PR comments --- .../transformers/reduce.test.ts | 92 +++++++++++++++++++ .../transformations/transformers/reduce.ts | 21 +++-- 2 files changed, 104 insertions(+), 9 deletions(-) diff --git a/packages/grafana-data/src/transformations/transformers/reduce.test.ts b/packages/grafana-data/src/transformations/transformers/reduce.test.ts index 57d67bfd121..b14d1d534ac 100644 --- a/packages/grafana-data/src/transformations/transformers/reduce.test.ts +++ b/packages/grafana-data/src/transformations/transformers/reduce.test.ts @@ -274,4 +274,96 @@ describe('Reducer Transformer', () => { } `); }); + + it('reduces multiple data frames with decimal display name (https://github.com/grafana/grafana/issues/31580)', async () => { + const cfg = { + id: DataTransformerID.reduce, + options: { + reducers: [ReducerID.max], + }, + }; + + const seriesA = toDataFrame({ + name: 'a', + fields: [ + { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000] }, + { name: 'value', type: FieldType.number, values: [3, 4, 5, 6], state: { displayName: 'a' } }, + ], + }); + + const seriesB = toDataFrame({ + name: '2021', + fields: [ + { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000] }, + { name: 'value', type: FieldType.number, values: [7, 8, 9, 10], state: { displayName: '2021' } }, + ], + }); + + await expect(transformDataFrame([cfg], [seriesA, seriesB])).toEmitValuesWith((received) => { + const processed = received[0]; + const expected: Field[] = [ + { + name: 'Field', + type: FieldType.string, + values: new ArrayVector(['a', '2021']), + config: {}, + }, + { + name: 'Max', + type: FieldType.number, + values: new ArrayVector([6, 10]), + config: {}, + }, + ]; + + expect(processed.length).toEqual(1); + expect(processed[0].length).toEqual(2); + expect(processed[0].fields).toEqual(expected); + }); + }); + + it('reduces multiple data frames with decimal fields name (https://github.com/grafana/grafana/issues/31580)', async () => { + const cfg = { + id: DataTransformerID.reduce, + options: { + reducers: [ReducerID.max], + }, + }; + + const seriesA = toDataFrame({ + fields: [ + { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000] }, + { name: 'a', type: FieldType.number, values: [3, 4, 5, 6] }, + ], + }); + + const seriesB = toDataFrame({ + fields: [ + { name: 'time', type: FieldType.time, values: [3000, 4000, 5000, 6000] }, + { name: '2021', type: FieldType.number, values: [7, 8, 9, 10] }, + ], + }); + + await expect(transformDataFrame([cfg], [seriesA, seriesB])).toEmitValuesWith((received) => { + const processed = received[0]; + const expected: Field[] = [ + { + name: 'Field', + type: FieldType.string, + values: new ArrayVector(['a', '2021']), + config: {}, + }, + { + name: 'Max', + type: FieldType.number, + values: new ArrayVector([6, 10]), + config: {}, + }, + ]; + + expect(processed.length).toEqual(1); + expect(processed[0].length).toEqual(2); + expect(processed[0].fields).toEqual(expected); + }); + }); }); diff --git a/packages/grafana-data/src/transformations/transformers/reduce.ts b/packages/grafana-data/src/transformations/transformers/reduce.ts index 63a45492ccb..413f6c561e3 100644 --- a/packages/grafana-data/src/transformations/transformers/reduce.ts +++ b/packages/grafana-data/src/transformations/transformers/reduce.ts @@ -1,7 +1,7 @@ import { map } from 'rxjs/operators'; import { DataTransformerID } from './ids'; -import { DataTransformerInfo, MatcherConfig, FieldMatcher } from '../../types/transformations'; +import { DataTransformerInfo, FieldMatcher, MatcherConfig } from '../../types/transformations'; import { fieldReducers, reduceField, ReducerID } from '../fieldReducer'; import { alwaysFieldMatcher, notTimeFieldMatcher } from '../matchers/predicates'; import { DataFrame, Field, FieldType } from '../../types/dataFrame'; @@ -149,15 +149,18 @@ export function mergeResults(data: DataFrame[]): DataFrame | undefined { for (let seriesIndex = 1; seriesIndex < data.length; seriesIndex++) { const series = data[seriesIndex]; - for (const baseField of baseFrame.fields) { - for (const field of series.fields) { - if (baseField.type !== field.type || baseField.name !== field.name) { - continue; - } + for (let baseIndex = 0; baseIndex < baseFrame.fields.length; baseIndex++) { + const baseField = baseFrame.fields[baseIndex]; + for (let fieldIndex = 0; fieldIndex < series.fields.length; fieldIndex++) { + const field = series.fields[fieldIndex]; + const isFirstField = baseIndex === 0 && fieldIndex === 0; + const isSameField = baseField.type === field.type && baseField.name === field.name; - const baseValues: any[] = ((baseField.values as unknown) as ArrayVector).buffer; - const values: any[] = ((field.values as unknown) as ArrayVector).buffer; - ((baseField.values as unknown) as ArrayVector).buffer = baseValues.concat(values); + if (isFirstField || isSameField) { + const baseValues: any[] = baseField.values.toArray(); + const values: any[] = field.values.toArray(); + ((baseField.values as unknown) as ArrayVector).buffer = baseValues.concat(values); + } } } }