[Feature] Add 'Template expression' option to 'Add field from calculation'
This commit is contained in:
+3
-6
@@ -167,6 +167,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
|
||||
],
|
||||
"packages/grafana-data/src/transformations/transformers/calculateField.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
@@ -3810,12 +3813,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/panel/geomap/layers/basemaps/esri.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/layersgeojsonDynamic.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/layersrouteLayer.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/panel/geomap/layers/registry.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
|
||||
@@ -578,7 +578,6 @@ Use this transformation to customize the output of a string field. This transfor
|
||||
- **Kebab case** - Formats all characters in the string in lowercase and uses dashes instead of spaces between words.
|
||||
- **Trim** - Removes all leading and trailing spaces from the string.
|
||||
- **Substring** - Returns a substring of the string, using the specified start and end positions.
|
||||
- **Affix** - Add a prefix or suffix string to the string. Allows pasting the value of other fields when provided {field} as the affix expression.
|
||||
|
||||
This transformation provides a convenient way to standardize and tailor the presentation of string data for better visualization and analysis.
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ export enum CalculateFieldMode {
|
||||
BinaryOperation = 'binary',
|
||||
UnaryOperation = 'unary',
|
||||
Index = 'index',
|
||||
TemplateExpression = 'templateExpression',
|
||||
}
|
||||
|
||||
export enum WindowSizeMode {
|
||||
@@ -72,6 +73,10 @@ interface IndexOptions {
|
||||
asPercentile: boolean;
|
||||
}
|
||||
|
||||
interface TemplateExpressionOptions {
|
||||
expression: string;
|
||||
}
|
||||
|
||||
const defaultReduceOptions: ReduceOptions = {
|
||||
reducer: ReducerID.sum,
|
||||
};
|
||||
@@ -106,6 +111,7 @@ export interface CalculateFieldTransformerOptions {
|
||||
binary?: BinaryOptions;
|
||||
unary?: UnaryOptions;
|
||||
index?: IndexOptions;
|
||||
template?: TemplateExpressionOptions;
|
||||
|
||||
// Remove other fields
|
||||
replaceFields?: boolean;
|
||||
@@ -249,6 +255,36 @@ export const calculateFieldTransformer: DataTransformerInfo<CalculateFieldTransf
|
||||
fields: options.replaceFields ? [f] : [...frame.fields, f],
|
||||
};
|
||||
});
|
||||
case CalculateFieldMode.TemplateExpression:
|
||||
const expression = options.template?.expression ?? '';
|
||||
const exprFieldNames = [
|
||||
...new Set([...expression.matchAll(/\{([\w\d\._-]+)\}/g)].map((match) => match[1])),
|
||||
];
|
||||
type FieldData = { fieldName: string; values: any[] };
|
||||
|
||||
creator = (frame: DataFrame) => {
|
||||
if (!options.template) {
|
||||
return undefined;
|
||||
}
|
||||
const exprFieldValues: FieldData[] = exprFieldNames.reduce((values: FieldData[], fieldName: string) => {
|
||||
const field = frame.fields.find((f) => f.name === fieldName);
|
||||
if (field) {
|
||||
values.push({ fieldName, values: field.values });
|
||||
}
|
||||
return values;
|
||||
}, []);
|
||||
|
||||
const outValues = [];
|
||||
for (let i = 0; i < frame.length; i++) {
|
||||
let rowValue = expression;
|
||||
exprFieldValues.map(({ fieldName, values }) => {
|
||||
rowValue = rowValue.replaceAll(`{${fieldName}}`, values[i]);
|
||||
});
|
||||
outValues.push(rowValue);
|
||||
}
|
||||
return outValues;
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
// Nothing configured
|
||||
|
||||
@@ -61,6 +61,7 @@ Use this transformation to add a new field calculated from two other fields. Eac
|
||||
- **Stddev** - Calculates the moving standard deviation.
|
||||
- **Variance** - Calculates the moving variance.
|
||||
- **Row index** - Insert a field with the row index.
|
||||
- **Template expression** - Insert a field with the value generated from a template expression. The expression can use the values of other fields in the calculation by using the {field} syntax.
|
||||
- **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][].
|
||||
- **Operation** - If you select **Binary operation** or **Unary operation** mode, then the **Operation** fields appear. These fields allow you to apply basic math operations on values in a single row from selected fields. You can also use numerical values for binary operations.
|
||||
@@ -515,6 +516,7 @@ Use this transformation to customize the output of a string field. This transfor
|
||||
- **Kebab case** - Formats all characters in the string in lowercase and uses dashes instead of spaces between words.
|
||||
- **Trim** - Removes all leading and trailing spaces from the string.
|
||||
- **Substring** - Returns a substring of the string, using the specified start and end positions.
|
||||
- **Affix** - Add a prefix or suffix string to the string. Allows pasting the value of other fields when provided {field} as the affix expression.
|
||||
|
||||
This transformation provides a convenient way to standardize and tailor the presentation of string data for better visualization and analysis.`;
|
||||
},
|
||||
|
||||
+13
@@ -34,6 +34,7 @@ import { BinaryOperationOptionsEditor } from './BinaryOperationOptionsEditor';
|
||||
import { CumulativeOptionsEditor } from './CumulativeOptionsEditor';
|
||||
import { IndexOptionsEditor } from './IndexOptionsEditor';
|
||||
import { ReduceRowOptionsEditor } from './ReduceRowOptionsEditor';
|
||||
import { TemplateExpressionOptionsEditor } from './TemplateExpressionOptionsEditor';
|
||||
import { UnaryOperationEditor } from './UnaryOperationEditor';
|
||||
import { WindowOptionsEditor } from './WindowOptionsEditor';
|
||||
import { LABEL_WIDTH } from './constants';
|
||||
@@ -89,6 +90,11 @@ export const CalculateFieldTransformerEditor = (props: CalculateFieldTransformer
|
||||
);
|
||||
}
|
||||
|
||||
calculationModes.push({
|
||||
value: CalculateFieldMode.TemplateExpression,
|
||||
label: t('transformers.calculate-field-transformer-editor.label.template-expression', 'Template expression'),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const ctx = { interpolate: (v: string) => v };
|
||||
const subscription = of(input)
|
||||
@@ -244,6 +250,13 @@ export const CalculateFieldTransformerEditor = (props: CalculateFieldTransformer
|
||||
{mode === CalculateFieldMode.Index && (
|
||||
<IndexOptionsEditor options={options} onChange={props.onChange}></IndexOptionsEditor>
|
||||
)}
|
||||
{mode === CalculateFieldMode.TemplateExpression && (
|
||||
<TemplateExpressionOptionsEditor
|
||||
input={input}
|
||||
options={options}
|
||||
onChange={props.onChange}
|
||||
></TemplateExpressionOptionsEditor>
|
||||
)}
|
||||
<InlineField
|
||||
labelWidth={LABEL_WIDTH}
|
||||
label={t('transformers.calculate-field-transformer-editor.label-alias', 'Alias')}
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { TransformerUIProps, StringFieldConfigSettings, StandardEditorsRegistryItem } from '@grafana/data';
|
||||
import { CalculateFieldMode, CalculateFieldTransformerOptions } from '@grafana/data/internal';
|
||||
import { t } from '@grafana/i18n';
|
||||
import { InlineField, InlineFieldRow } from '@grafana/ui';
|
||||
import { StringValueEditor } from 'app/core/components/OptionsUI/string';
|
||||
|
||||
import { LABEL_WIDTH } from './constants';
|
||||
|
||||
export const TemplateExpressionOptionsEditor = ({
|
||||
input,
|
||||
options,
|
||||
onChange,
|
||||
}: TransformerUIProps<CalculateFieldTransformerOptions>) => {
|
||||
const onTemplateExpressionChanged = useCallback(
|
||||
(value?: string) => {
|
||||
onChange({
|
||||
...options,
|
||||
mode: CalculateFieldMode.TemplateExpression,
|
||||
template: {
|
||||
expression: value ?? '',
|
||||
},
|
||||
});
|
||||
},
|
||||
[onChange, options]
|
||||
);
|
||||
|
||||
const dummyStringSettings: StandardEditorsRegistryItem<string, StringFieldConfigSettings> = {
|
||||
id: '',
|
||||
name: '',
|
||||
description: '',
|
||||
editor: StringValueEditor,
|
||||
settings: {},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
labelWidth={LABEL_WIDTH}
|
||||
label={t('transformers.template-expression-options-editor.label-expression', 'Expression')}
|
||||
tooltip={t(
|
||||
'transformers.template-expression-options-editor.tooltip-transform-template-expression',
|
||||
'Transform a template expression into a field value'
|
||||
)}
|
||||
>
|
||||
<StringValueEditor
|
||||
context={{ data: input }}
|
||||
value={options.template?.expression ?? ''}
|
||||
onChange={onTemplateExpressionChanged}
|
||||
item={dummyStringSettings}
|
||||
preserveWhitespace={true}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -12834,13 +12834,18 @@
|
||||
"placeholder-field-or-number": "Field or number",
|
||||
"placeholder-fields-or-number": "Field(s) or number"
|
||||
},
|
||||
"template-expression-options-editor": {
|
||||
"label-expression:": "Expression",
|
||||
"tooltip-transform-template-expression": "Transform a template expression into a field value"
|
||||
},
|
||||
"calculate-field-transformer-editor": {
|
||||
"calculation-modes": {
|
||||
"label": {
|
||||
"binary-operation": "Binary operation",
|
||||
"reduce-row": "Reduce row",
|
||||
"row-index": "Row index",
|
||||
"unary-operation": "Unary operation"
|
||||
"unary-operation": "Unary operation",
|
||||
"template-expression": "Template expression"
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
|
||||
Reference in New Issue
Block a user