The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/transformers/regression/regressionEditor.tsx

142 lines
4.4 KiB

import React, { useEffect } from 'react';
import {
DataTransformerID,
TransformerRegistryItem,
TransformerUIProps,
TransformerCategory,
fieldMatchers,
FieldMatcherID,
Field,
} from '@grafana/data';
import { InlineField, Select } from '@grafana/ui';
import { FieldNamePicker } from '@grafana/ui/src/components/MatchersUI/FieldNamePicker';
import { NumberInput } from 'app/core/components/OptionsUI/NumberInput';
import { getTransformationContent } from '../docs/getTransformationContent';
import { DEFAULTS, ModelType, RegressionTransformer, RegressionTransformerOptions } from './regression';
const fieldNamePickerSettings = {
editor: FieldNamePicker,
id: '',
name: '',
settings: { width: 24, isClearable: false },
};
const LABEL_WIDTH = 20;
export const RegressionTransformerEditor = ({
input,
options,
onChange,
}: TransformerUIProps<RegressionTransformerOptions>) => {
const modelTypeOptions = [
{ label: 'Linear', value: ModelType.linear },
{ label: 'Polynomial', value: ModelType.polynomial },
];
useEffect(() => {
let x: Field | undefined;
let y: Field | undefined;
if (!options.xFieldName) {
const timeMatcher = fieldMatchers.get(FieldMatcherID.firstTimeField).get({});
for (const frame of input) {
x = frame.fields.find((field) => timeMatcher(field, frame, input));
if (x) {
break;
}
}
if (!x) {
const firstMatcher = fieldMatchers.get(FieldMatcherID.numeric).get({});
for (const frame of input) {
x = frame.fields.find((field) => firstMatcher(field, frame, input));
if (x) {
break;
}
}
}
}
if (!options.yFieldName) {
const numberMatcher = fieldMatchers.get(FieldMatcherID.numeric).get({});
for (const frame of input) {
y = frame.fields.find((field) => numberMatcher(field, frame, input) && field !== x);
if (y) {
break;
}
}
}
if (x && y) {
onChange({ ...options, xFieldName: x.name, yFieldName: y.name });
}
});
return (
<>
<InlineField labelWidth={LABEL_WIDTH} label="X field">
<FieldNamePicker
context={{ data: input }}
value={options.xFieldName ?? ''}
item={fieldNamePickerSettings}
onChange={(v) => {
onChange({ ...options, xFieldName: v });
}}
></FieldNamePicker>
</InlineField>
<InlineField labelWidth={LABEL_WIDTH} label="Y field">
<FieldNamePicker
context={{ data: input }}
value={options.yFieldName ?? ''}
item={fieldNamePickerSettings}
onChange={(v) => {
onChange({ ...options, yFieldName: v });
}}
></FieldNamePicker>
</InlineField>
<InlineField labelWidth={LABEL_WIDTH} label="Model type">
<Select
value={options.modelType ?? DEFAULTS.modelType}
onChange={(v) => {
onChange({ ...options, modelType: v.value ?? DEFAULTS.modelType });
}}
options={modelTypeOptions}
></Select>
</InlineField>
<InlineField labelWidth={LABEL_WIDTH} label="Predicted points" tooltip={'Number of X,Y points to predict'}>
<NumberInput
value={options.predictionCount ?? DEFAULTS.predictionCount}
onChange={(v) => {
onChange({ ...options, predictionCount: v });
}}
></NumberInput>
</InlineField>
{options.modelType === ModelType.polynomial && (
<InlineField labelWidth={LABEL_WIDTH} label="Degree">
<Select<number>
value={options.degree ?? DEFAULTS.degree}
options={[
{ label: 'Quadratic', value: 2 },
{ label: 'Cubic', value: 3 },
{ label: 'Quartic', value: 4 },
{ label: 'Quintic', value: 5 },
]}
onChange={(v) => {
onChange({ ...options, degree: v.value });
}}
></Select>
</InlineField>
)}
</>
);
};
export const regressionTransformerRegistryItem: TransformerRegistryItem<RegressionTransformerOptions> = {
id: DataTransformerID.regression,
editor: RegressionTransformerEditor,
transformation: RegressionTransformer,
name: RegressionTransformer.name,
description: RegressionTransformer.description,
categories: new Set([TransformerCategory.CalculateNewFields]),
help: getTransformationContent(DataTransformerID.regression).helperDocs,
};