Transformers: Support adding the row index using calculate field transformer (#65148)

pull/65229/head
Ryan McKinley 2 years ago committed by GitHub
parent f96637b5fc
commit 732f3da33f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/sources/panels-visualizations/query-transform-data/transform-data/index.md
  2. 16
      packages/grafana-data/src/transformations/transformers/calculateField.test.ts
  3. 30
      packages/grafana-data/src/transformations/transformers/calculateField.ts
  4. 1
      public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx

@ -89,6 +89,7 @@ Use this transformation to add a new field calculated from two other fields. Eac
- **Mode -** Select a mode:
- **Reduce row -** Apply selected calculation on each row of selected fields independently.
- **Binary option -** Apply basic math operation(sum, multiply, etc) on values in a single row from two selected fields.
- **Index -** Will insert a field with the row index.
- **Field name -** Select the names of fields you want to use in the calculation for the new field.
- **Calculation -** If you select **Reduce row** mode, then the **Calculation** field appears. Click in the field to see a list of calculation choices you can use to create the new field. For information about available calculations, refer to [Calculation types]({{< relref "../../calculation-types" >}}).
- **Operation -** If you select **Binary option** mode, then the **Operation** fields appear. These fields allow you to do basic math operations on values in a single row from two selected fields. You can also use numerical values for binary operations.

@ -222,6 +222,22 @@ describe('calculateField transformer w/ timeseries', () => {
});
});
it('can add index field', async () => {
const cfg = {
id: DataTransformerID.calculateField,
options: {
mode: CalculateFieldMode.Index,
replaceFields: true,
},
};
await expect(transformDataFrame([cfg], [seriesBC])).toEmitValuesWith((received) => {
const data = received[0][0];
expect(data.fields.length).toEqual(1);
expect(data.fields[0].values.toArray()).toEqual([0, 1]);
});
});
it('uses template variable substituion', async () => {
const cfg = {
id: DataTransformerID.calculateField,

@ -5,7 +5,7 @@ import { getTimeField } from '../../dataframe/processDataFrame';
import { getFieldDisplayName } from '../../field';
import { DataFrame, DataTransformerInfo, Field, FieldType, NullValueMode, Vector } from '../../types';
import { BinaryOperationID, binaryOperators } from '../../utils/binaryOperators';
import { ArrayVector, BinaryOperationVector, ConstantVector } from '../../vector';
import { ArrayVector, BinaryOperationVector, ConstantVector, IndexVector } from '../../vector';
import { AsNumberVector } from '../../vector/AsNumberVector';
import { RowVector } from '../../vector/RowVector';
import { doStandardCalcs, fieldReducers, ReducerID } from '../fieldReducer';
@ -19,6 +19,7 @@ import { noopTransformer } from './noop';
export enum CalculateFieldMode {
ReduceRow = 'reduceRow',
BinaryOperation = 'binary',
Index = 'index',
}
export interface ReduceOptions {
@ -98,6 +99,22 @@ export const calculateFieldTransformer: DataTransformerInfo<CalculateFieldTransf
};
creator = getBinaryCreator(defaults(binaryOptions, defaultBinaryOptions), data);
} else if (mode === CalculateFieldMode.Index) {
return data.map((frame) => {
const f = {
name: options.alias ?? 'Row',
type: FieldType.number,
values: new IndexVector(frame.length),
config: {
min: 0,
max: frame.length - 1,
},
};
return {
...frame,
fields: options.replaceFields ? [f] : [...frame.fields, f],
};
});
}
// Nothing configured
@ -235,17 +252,22 @@ export function getNameFromOptions(options: CalculateFieldTransformerOptions) {
return options.alias;
}
if (options.mode === CalculateFieldMode.BinaryOperation) {
switch (options.mode) {
case CalculateFieldMode.BinaryOperation: {
const { binary } = options;
return `${binary?.left ?? ''} ${binary?.operator ?? ''} ${binary?.right ?? ''}`;
}
if (options.mode === CalculateFieldMode.ReduceRow) {
case CalculateFieldMode.ReduceRow:
{
const r = fieldReducers.getIfExists(options.reduce?.reducer);
if (r) {
return r.name;
}
}
break;
case CalculateFieldMode.Index:
return 'Row';
}
return 'math';
}

@ -37,6 +37,7 @@ interface CalculateFieldTransformerEditorState {
const calculationModes = [
{ value: CalculateFieldMode.BinaryOperation, label: 'Binary operation' },
{ value: CalculateFieldMode.ReduceRow, label: 'Reduce row' },
{ value: CalculateFieldMode.Index, label: 'Row index' },
];
const okTypes = new Set<FieldType>([FieldType.time, FieldType.number, FieldType.string]);

Loading…
Cancel
Save