mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Transforms: Fix 'Filter data by values' removing rows in unrelated frames (#86087)
This commit is contained in:
parent
d409d8e860
commit
9682022b1d
@ -26,6 +26,25 @@ const seriesAWithSingleField = toDataFrame({
|
||||
],
|
||||
});
|
||||
|
||||
const multiSeriesWithSingleField = [
|
||||
toDataFrame({
|
||||
name: 'A',
|
||||
length: 3,
|
||||
fields: [
|
||||
{ name: 'time', type: FieldType.time, values: [1000, 2000, 3000] },
|
||||
{ name: 'value', type: FieldType.number, values: [1, 0, 1] },
|
||||
],
|
||||
}),
|
||||
toDataFrame({
|
||||
name: 'B',
|
||||
length: 3,
|
||||
fields: [
|
||||
{ name: 'time', type: FieldType.time, values: [5000, 6000, 7000] },
|
||||
{ name: 'value', type: FieldType.number, values: [0, 1, 1] },
|
||||
],
|
||||
}),
|
||||
];
|
||||
|
||||
describe('FilterByValue transformer', () => {
|
||||
beforeAll(() => {
|
||||
mockTransformationsRegistry([filterByValueTransformer]);
|
||||
@ -72,6 +91,68 @@ describe('FilterByValue transformer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not cross frame boundaries', async () => {
|
||||
const cfg: DataTransformerConfig<FilterByValueTransformerOptions> = {
|
||||
id: DataTransformerID.filterByValue,
|
||||
options: {
|
||||
type: FilterByValueType.exclude,
|
||||
match: FilterByValueMatch.any,
|
||||
filters: [
|
||||
{
|
||||
fieldName: 'A value',
|
||||
config: {
|
||||
id: ValueMatcherID.equal,
|
||||
options: { value: 0 },
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'B value',
|
||||
config: {
|
||||
id: ValueMatcherID.equal,
|
||||
options: { value: 0 },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
await expect(transformDataFrame([cfg], multiSeriesWithSingleField)).toEmitValuesWith((received) => {
|
||||
const processed = received[0];
|
||||
|
||||
expect(processed.length).toEqual(2);
|
||||
|
||||
expect(processed[0].fields).toEqual([
|
||||
{
|
||||
name: 'time',
|
||||
type: FieldType.time,
|
||||
values: [1000, 3000],
|
||||
state: {},
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
type: FieldType.number,
|
||||
values: [1, 1],
|
||||
state: {},
|
||||
},
|
||||
]);
|
||||
|
||||
expect(processed[1].fields).toEqual([
|
||||
{
|
||||
name: 'time',
|
||||
type: FieldType.time,
|
||||
values: [6000, 7000],
|
||||
state: {},
|
||||
},
|
||||
{
|
||||
name: 'value',
|
||||
type: FieldType.number,
|
||||
values: [1, 1],
|
||||
state: {},
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should include values', async () => {
|
||||
const lowerOrEqual: MatcherConfig<BasicValueMatcherOptions<number>> = {
|
||||
id: ValueMatcherID.lowerOrEqual,
|
||||
|
@ -92,14 +92,16 @@ export const filterByValueTransformer: DataTransformerInfo<FilterByValueTransfor
|
||||
|
||||
return source.pipe(
|
||||
map((data) => {
|
||||
if (!Array.isArray(data) || data.length === 0) {
|
||||
if (data.length === 0) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const rows = new Set<number>();
|
||||
const processed: DataFrame[] = [];
|
||||
|
||||
const fieldIndexByName = groupFieldIndexByName(data);
|
||||
|
||||
for (const frame of data) {
|
||||
const fieldIndexByName = groupFieldIndexByName(frame, data);
|
||||
const rows = new Set<number>();
|
||||
|
||||
let matchers;
|
||||
if (transformationsVariableSupport()) {
|
||||
@ -135,13 +137,9 @@ export const filterByValueTransformer: DataTransformerInfo<FilterByValueTransfor
|
||||
rows.add(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const processed: DataFrame[] = [];
|
||||
const frameLength = include ? rows.size : data[0].length - rows.size;
|
||||
|
||||
for (const frame of data) {
|
||||
const fields: Field[] = [];
|
||||
const frameLength = include ? rows.size : data[0].length - rows.size;
|
||||
|
||||
for (const field of frame.fields) {
|
||||
const buffer = [];
|
||||
@ -198,10 +196,15 @@ const createFilterValueMatchers = (
|
||||
});
|
||||
};
|
||||
|
||||
const groupFieldIndexByName = (frame: DataFrame, data: DataFrame[]): Record<string, number> => {
|
||||
return frame.fields.reduce((all: Record<string, number>, field, fieldIndex) => {
|
||||
const fieldName = getFieldDisplayName(field, frame, data);
|
||||
all[fieldName] = fieldIndex;
|
||||
return all;
|
||||
}, {});
|
||||
const groupFieldIndexByName = (data: DataFrame[]) => {
|
||||
const lookup: Record<string, number> = {};
|
||||
|
||||
for (const frame of data) {
|
||||
frame.fields.forEach((field, fieldIndex) => {
|
||||
const fieldName = getFieldDisplayName(field, frame, data);
|
||||
lookup[fieldName] = fieldIndex;
|
||||
});
|
||||
}
|
||||
|
||||
return lookup;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user