Transformations: Reduce > Reduce fields should not persist labels between reducers (#107590)

Reduce fields should not persist labels updates between reducers
This commit is contained in:
Kristina
2025-07-07 12:05:55 -05:00
committed by GitHub
parent 7181f8d89d
commit 0f2284d5e6
2 changed files with 61 additions and 2 deletions
@@ -8,7 +8,7 @@ import { notTimeFieldMatcher } from '../matchers/predicates';
import { transformDataFrame } from '../transformDataFrame';
import { DataTransformerID } from './ids';
import { reduceFields, reduceTransformer, ReduceTransformerOptions } from './reduce';
import { reduceFields, reduceTransformer, ReduceTransformerMode, ReduceTransformerOptions } from './reduce';
const seriesAWithSingleField = toDataFrame({
name: 'A',
@@ -582,4 +582,62 @@ describe('Reducer Transformer', () => {
`);
});
});
it('reduce fields mode keeps distinct label values with multiple reducers', async () => {
const cfg: DataTransformerConfig<ReduceTransformerOptions> = {
id: DataTransformerID.reduce,
options: {
mode: ReduceTransformerMode.ReduceFields,
reducers: [ReducerID.max, ReducerID.count],
labelsToFields: false,
},
};
const seriesA = toDataFrame({
length: 3,
fields: [{ name: 'value', config: {}, labels: { category: 'apple' }, type: FieldType.number, values: [3, 4, 5] }],
});
const seriesB = toDataFrame({
fields: [
{ name: 'value', config: {}, labels: { category: 'orange' }, type: FieldType.number, values: [6, 7, 8] },
],
});
await expect(transformDataFrame([cfg], [seriesA, seriesB])).toEmitValuesWith((received) => {
const processed = received[0];
expect(processed.length).toEqual(2);
expect(processed[0].fields).toMatchInlineSnapshot(`
[
{
"config": {},
"labels": {
"category": "apple",
"reducer": "Max",
},
"name": "value",
"state": undefined,
"type": "number",
"values": [
5,
],
},
{
"config": {},
"labels": {
"category": "apple",
"reducer": "Count",
},
"name": "value",
"state": undefined,
"type": "number",
"values": [
3,
],
},
]
`);
});
});
});
@@ -230,10 +230,11 @@ export function reduceFields(data: DataFrame[], matcher: FieldMatcher, reducerId
const value = results[reducer];
const copy = {
...field,
labels: { ...field.labels },
type: getFieldType(reducer, field),
values: [value],
state: undefined,
};
copy.state = undefined;
if (reducers.length > 1) {
if (!copy.labels) {
copy.labels = {};