grafana/public/app/features/transformers/rowsToFields/rowsToFields.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

98 lines
2.5 KiB
TypeScript

import { map } from 'rxjs/operators';
import {
ArrayVector,
DataFrame,
DataTransformerID,
DataTransformerInfo,
Field,
getFieldDisplayName,
Labels,
} from '@grafana/data';
import {
getFieldConfigFromFrame,
FieldToConfigMapping,
evaluteFieldMappings,
EvaluatedMappingResult,
FieldConfigHandlerKey,
} from '../fieldToConfigMapping/fieldToConfigMapping';
export interface RowToFieldsTransformOptions {
nameField?: string;
valueField?: string;
mappings?: FieldToConfigMapping[];
}
export const rowsToFieldsTransformer: DataTransformerInfo<RowToFieldsTransformOptions> = {
id: DataTransformerID.rowsToFields,
name: 'Rows to fields',
description: 'Convert each row into a field with dynamic config',
defaultOptions: {},
/**
* 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) => {
return data.map((frame) => rowsToFields(options, frame));
})
),
};
export function rowsToFields(options: RowToFieldsTransformOptions, data: DataFrame): DataFrame {
const mappingResult = evaluteFieldMappings(data, options.mappings ?? [], true);
const { nameField, valueField } = mappingResult;
if (!nameField || !valueField) {
return data;
}
const outFields: Field[] = [];
for (let index = 0; index < nameField.values.length; index++) {
const name = nameField.values.get(index);
const value = valueField.values.get(index);
const config = getFieldConfigFromFrame(data, index, mappingResult);
const labels = getLabelsFromRow(data, index, mappingResult);
const field: Field = {
name: `${name}`,
type: valueField.type,
values: new ArrayVector([value]),
config: config,
labels,
};
outFields.push(field);
}
return {
fields: outFields,
length: 1,
};
}
function getLabelsFromRow(frame: DataFrame, index: number, mappingResult: EvaluatedMappingResult): Labels {
const labels = { ...mappingResult.nameField!.labels };
for (let i = 0; i < frame.fields.length; i++) {
const field = frame.fields[i];
const fieldName = getFieldDisplayName(field, frame);
const fieldMapping = mappingResult.index[fieldName];
if (fieldMapping.handler && fieldMapping.handler.key !== FieldConfigHandlerKey.Label) {
continue;
}
const value = field.values.get(index);
if (value != null) {
labels[fieldName] = value;
}
}
return labels;
}