grafana/public/app/features/transformers/configFromQuery/configFromQuery.ts
Lars Stegman 188aed05f9
Transformer: Config from Query: set threshold colours (#83366)
* Fix typo

* Create handler arguments

* Create handler arguments editor

* Create link in editor

* Add labels to arguments editor fields

* Create unit tests

* Hide "Additional settings" header when no additional settings possible

* Remove div

* Fix invalid DOM

---------

Co-authored-by: jev forsberg <jev.forsberg@grafana.com>
2024-03-22 15:39:01 -06:00

107 lines
2.7 KiB
TypeScript

import { map } from 'rxjs/operators';
import {
DataFrame,
DataTransformerID,
DataTransformerInfo,
FieldMatcherID,
getFieldDisplayName,
getFieldMatcher,
MatcherConfig,
reduceField,
} from '@grafana/data';
import {
evaluateFieldMappings,
FieldToConfigMapping,
getFieldConfigFromFrame,
} from '../fieldToConfigMapping/fieldToConfigMapping';
export interface ConfigFromQueryTransformOptions {
configRefId?: string;
mappings: FieldToConfigMapping[];
applyTo?: MatcherConfig;
}
export function extractConfigFromQuery(options: ConfigFromQueryTransformOptions, data: DataFrame[]) {
let configFrame: DataFrame | null = null;
for (const frame of data) {
if (frame.refId === options.configRefId) {
configFrame = frame;
break;
}
}
if (!configFrame) {
return data;
}
const reducedConfigFrame: DataFrame = {
fields: [],
length: 1,
};
const mappingResult = evaluateFieldMappings(configFrame, options.mappings ?? [], false);
// reduce config frame
for (const field of configFrame.fields) {
const newField = { ...field };
const fieldName = getFieldDisplayName(field, configFrame);
const fieldMapping = mappingResult.index[fieldName];
const result = reduceField({ field, reducers: [fieldMapping.reducerId] });
newField.values = [result[fieldMapping.reducerId]];
reducedConfigFrame.fields.push(newField);
}
const output: DataFrame[] = [];
const matcher = getFieldMatcher(options.applyTo || { id: FieldMatcherID.numeric });
for (const frame of data) {
// Skip config frame in output
if (frame === configFrame && data.length > 1) {
continue;
}
const outputFrame: DataFrame = {
fields: [],
length: frame.length,
refId: frame.refId,
};
for (const field of frame.fields) {
if (matcher(field, frame, data)) {
const dataConfig = getFieldConfigFromFrame(reducedConfigFrame, 0, mappingResult);
outputFrame.fields.push({
...field,
config: {
...field.config,
...dataConfig,
},
});
} else {
outputFrame.fields.push(field);
}
}
output.push(outputFrame);
}
return output;
}
export const configFromDataTransformer: DataTransformerInfo<ConfigFromQueryTransformOptions> = {
id: DataTransformerID.configFromData,
name: 'Config from query results',
description: 'Set unit, min, max and more from data.',
defaultOptions: {
configRefId: 'config',
mappings: [],
},
/**
* Return a modified copy of the series. If the transform is not or should not
* be applied, just return the input series
*/
operator: (options) => (source) => source.pipe(map((data) => extractConfigFromQuery(options, data))),
};