mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Transforms: allow boolean in field calculations (#30802)
This commit is contained in:
parent
25ef563a53
commit
c9c7bfbcaa
@ -21,6 +21,7 @@ const seriesBC = toDataFrame({
|
|||||||
{ name: 'B', type: FieldType.number, values: [2, 200] },
|
{ name: 'B', type: FieldType.number, values: [2, 200] },
|
||||||
{ name: 'C', type: FieldType.number, values: [3, 300] },
|
{ name: 'C', type: FieldType.number, values: [3, 300] },
|
||||||
{ name: 'D', type: FieldType.string, values: ['first', 'second'] },
|
{ name: 'D', type: FieldType.string, values: ['first', 'second'] },
|
||||||
|
{ name: 'E', type: FieldType.boolean, values: [true, false] },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ describe('calculateField transformer w/ timeseries', () => {
|
|||||||
B: 2,
|
B: 2,
|
||||||
C: 3,
|
C: 3,
|
||||||
D: 'first',
|
D: 'first',
|
||||||
|
E: true,
|
||||||
'The Total': 6,
|
'The Total': 6,
|
||||||
TheTime: 1000,
|
TheTime: 1000,
|
||||||
},
|
},
|
||||||
@ -56,6 +58,7 @@ describe('calculateField transformer w/ timeseries', () => {
|
|||||||
B: 200,
|
B: 200,
|
||||||
C: 300,
|
C: 300,
|
||||||
D: 'second',
|
D: 'second',
|
||||||
|
E: false,
|
||||||
'The Total': 600,
|
'The Total': 600,
|
||||||
TheTime: 2000,
|
TheTime: 2000,
|
||||||
},
|
},
|
||||||
@ -129,7 +132,7 @@ describe('calculateField transformer w/ timeseries', () => {
|
|||||||
mode: CalculateFieldMode.BinaryOperation,
|
mode: CalculateFieldMode.BinaryOperation,
|
||||||
binary: {
|
binary: {
|
||||||
left: 'B',
|
left: 'B',
|
||||||
operation: BinaryOperationID.Add,
|
operator: BinaryOperationID.Add,
|
||||||
right: 'C',
|
right: 'C',
|
||||||
},
|
},
|
||||||
replaceFields: true,
|
replaceFields: true,
|
||||||
@ -160,7 +163,7 @@ describe('calculateField transformer w/ timeseries', () => {
|
|||||||
mode: CalculateFieldMode.BinaryOperation,
|
mode: CalculateFieldMode.BinaryOperation,
|
||||||
binary: {
|
binary: {
|
||||||
left: 'B',
|
left: 'B',
|
||||||
operation: BinaryOperationID.Add,
|
operator: BinaryOperationID.Add,
|
||||||
right: '2',
|
right: '2',
|
||||||
},
|
},
|
||||||
replaceFields: true,
|
replaceFields: true,
|
||||||
@ -183,4 +186,37 @@ describe('calculateField transformer w/ timeseries', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('boolean field', async () => {
|
||||||
|
const cfg = {
|
||||||
|
id: DataTransformerID.calculateField,
|
||||||
|
options: {
|
||||||
|
mode: CalculateFieldMode.BinaryOperation,
|
||||||
|
binary: {
|
||||||
|
left: 'E',
|
||||||
|
operator: BinaryOperationID.Multiply,
|
||||||
|
right: '1',
|
||||||
|
},
|
||||||
|
replaceFields: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(transformDataFrame([cfg], [seriesBC])).toEmitValuesWith((received) => {
|
||||||
|
const data = received[0];
|
||||||
|
const filtered = data[0];
|
||||||
|
const rows = new DataFrameView(filtered).toArray();
|
||||||
|
expect(rows).toMatchInlineSnapshot(`
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"E * 1": 1,
|
||||||
|
"TheTime": 1000,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"E * 1": 0,
|
||||||
|
"TheTime": 2000,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@ import { getFieldMatcher } from '../matchers';
|
|||||||
import { FieldMatcherID } from '../matchers/ids';
|
import { FieldMatcherID } from '../matchers/ids';
|
||||||
import { RowVector } from '../../vector/RowVector';
|
import { RowVector } from '../../vector/RowVector';
|
||||||
import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector';
|
import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector';
|
||||||
|
import { AsNumberVector } from '../../vector/AsNumberVector';
|
||||||
import { getTimeField } from '../../dataframe/processDataFrame';
|
import { getTimeField } from '../../dataframe/processDataFrame';
|
||||||
import defaults from 'lodash/defaults';
|
import defaults from 'lodash/defaults';
|
||||||
import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators';
|
import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators';
|
||||||
@ -187,6 +188,9 @@ function findFieldValuesWithNameOrConstant(frame: DataFrame, name: string, allFr
|
|||||||
|
|
||||||
for (const f of frame.fields) {
|
for (const f of frame.fields) {
|
||||||
if (name === getFieldDisplayName(f, frame, allFrames)) {
|
if (name === getFieldDisplayName(f, frame, allFrames)) {
|
||||||
|
if (f.type === FieldType.boolean) {
|
||||||
|
return new AsNumberVector(f.values);
|
||||||
|
}
|
||||||
return f.values;
|
return f.values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
packages/grafana-data/src/vector/AsNumberVector.ts
Normal file
16
packages/grafana-data/src/vector/AsNumberVector.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { Vector } from '../types';
|
||||||
|
import { FunctionalVector } from './FunctionalVector';
|
||||||
|
|
||||||
|
export class AsNumberVector extends FunctionalVector<number> {
|
||||||
|
constructor(private field: Vector) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this.field.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(index: number) {
|
||||||
|
return +this.field.get(index);
|
||||||
|
}
|
||||||
|
}
|
@ -6,5 +6,6 @@ export * from './BinaryOperationVector';
|
|||||||
export * from './SortedVector';
|
export * from './SortedVector';
|
||||||
export * from './FormattedVector';
|
export * from './FormattedVector';
|
||||||
export * from './IndexVector';
|
export * from './IndexVector';
|
||||||
|
export * from './AsNumberVector';
|
||||||
|
|
||||||
export { vectorator } from './FunctionalVector';
|
export { vectorator } from './FunctionalVector';
|
||||||
|
@ -39,6 +39,8 @@ const calculationModes = [
|
|||||||
{ value: CalculateFieldMode.ReduceRow, label: 'Reduce row' },
|
{ value: CalculateFieldMode.ReduceRow, label: 'Reduce row' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const okTypes = new Set<FieldType>([FieldType.time, FieldType.number, FieldType.string]);
|
||||||
|
|
||||||
export class CalculateFieldTransformerEditor extends React.PureComponent<
|
export class CalculateFieldTransformerEditor extends React.PureComponent<
|
||||||
CalculateFieldTransformerEditorProps,
|
CalculateFieldTransformerEditorProps,
|
||||||
CalculateFieldTransformerEditorState
|
CalculateFieldTransformerEditorState
|
||||||
@ -86,7 +88,7 @@ export class CalculateFieldTransformerEditor extends React.PureComponent<
|
|||||||
|
|
||||||
for (const frame of input) {
|
for (const frame of input) {
|
||||||
for (const field of frame.fields) {
|
for (const field of frame.fields) {
|
||||||
if (field.type !== FieldType.number) {
|
if (!okTypes.has(field.type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user