grafana/public/app/features/transformers/configFromQuery/configFromQuery.ts
Josh Hunt 3c6e0e8ef8
Chore: ESlint import order (#44959)
* Add and configure eslint-plugin-import

* Fix the lint:ts npm command

* Autofix + prettier all the files

* Manually fix remaining files

* Move jquery code in jest-setup to external file to safely reorder imports

* Resolve issue caused by circular dependencies within Prometheus

* Update .betterer.results

* Fix missing // @ts-ignore

* ignore iconBundle.ts

* Fix missing // @ts-ignore
2022-04-22 14:33:13 +01:00

108 lines
2.7 KiB
TypeScript

import { map } from 'rxjs/operators';
import {
ArrayVector,
DataFrame,
DataTransformerID,
DataTransformerInfo,
FieldMatcherID,
getFieldDisplayName,
getFieldMatcher,
MatcherConfig,
reduceField,
} from '@grafana/data';
import {
getFieldConfigFromFrame,
FieldToConfigMapping,
evaluteFieldMappings,
} 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 = evaluteFieldMappings(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 = new ArrayVector([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,
};
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))),
};