mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 00:25:46 -06:00
130 lines
3.8 KiB
TypeScript
130 lines
3.8 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import React, { useCallback } from 'react';
|
|
|
|
import {
|
|
GrafanaTheme2,
|
|
SelectableValue,
|
|
TransformerRegistryItem,
|
|
TransformerUIProps,
|
|
TransformerCategory,
|
|
} from '@grafana/data';
|
|
import { InlineField, InlineFieldRow, Select, useStyles2 } from '@grafana/ui';
|
|
|
|
import { prepareTimeSeriesTransformer, PrepareTimeSeriesOptions, timeSeriesFormat } from './prepareTimeSeries';
|
|
|
|
const wideInfo = {
|
|
label: 'Wide time series',
|
|
value: timeSeriesFormat.TimeSeriesWide,
|
|
description: 'Creates a single frame joined by time',
|
|
info: (
|
|
<ul>
|
|
<li>Single frame</li>
|
|
<li>1st field is shared time field</li>
|
|
<li>Time in ascending order</li>
|
|
<li>Multiple value fields of any type</li>
|
|
</ul>
|
|
),
|
|
};
|
|
|
|
const multiInfo = {
|
|
label: 'Multi-frame time series',
|
|
value: timeSeriesFormat.TimeSeriesMulti,
|
|
description: 'Creates a new frame for each time/number pair',
|
|
info: (
|
|
<ul>
|
|
<li>Multiple frames</li>
|
|
<li>Each frame has two fields: time, value</li>
|
|
<li>Time in ascending order</li>
|
|
<li>String values are represented as labels</li>
|
|
<li>All values are numeric</li>
|
|
</ul>
|
|
),
|
|
};
|
|
|
|
const longInfo = {
|
|
label: 'Long time series',
|
|
value: timeSeriesFormat.TimeSeriesLong,
|
|
description: 'Convert each frame to long format',
|
|
info: (
|
|
<ul>
|
|
<li>Single frame</li>
|
|
<li>1st field is time field</li>
|
|
<li>Time in ascending order, but may have duplictes</li>
|
|
<li>String values are represented as separate fields rather than as labels</li>
|
|
<li>Multiple value fields may exist</li>
|
|
</ul>
|
|
),
|
|
};
|
|
|
|
const formats: Array<SelectableValue<timeSeriesFormat>> = [wideInfo, multiInfo, longInfo];
|
|
|
|
export function PrepareTimeSeriesEditor(props: TransformerUIProps<PrepareTimeSeriesOptions>): React.ReactElement {
|
|
const { options, onChange } = props;
|
|
const styles = useStyles2(getStyles);
|
|
|
|
const onSelectFormat = useCallback(
|
|
(value: SelectableValue<timeSeriesFormat>) => {
|
|
onChange({
|
|
...options,
|
|
format: value.value!,
|
|
});
|
|
},
|
|
[onChange, options]
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<InlineFieldRow>
|
|
<InlineField label="Format" labelWidth={12}>
|
|
<Select
|
|
width={35}
|
|
options={formats}
|
|
value={
|
|
formats.find((v) => {
|
|
// migrate previously selected timeSeriesMany to multi
|
|
if (
|
|
v.value === timeSeriesFormat.TimeSeriesMulti &&
|
|
options.format === timeSeriesFormat.TimeSeriesMany
|
|
) {
|
|
return true;
|
|
} else {
|
|
return v.value === options.format;
|
|
}
|
|
}) || formats[0]
|
|
}
|
|
onChange={onSelectFormat}
|
|
className="flex-grow-1"
|
|
/>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
<InlineFieldRow>
|
|
<InlineField label="Info" labelWidth={12}>
|
|
<div className={styles.info}>{(formats.find((v) => v.value === options.format) || formats[0]).info}</div>
|
|
</InlineField>
|
|
</InlineFieldRow>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
info: css`
|
|
margin-left: 20px;
|
|
`,
|
|
});
|
|
|
|
export const prepareTimeseriesTransformerRegistryItem: TransformerRegistryItem<PrepareTimeSeriesOptions> = {
|
|
id: prepareTimeSeriesTransformer.id,
|
|
editor: PrepareTimeSeriesEditor,
|
|
transformation: prepareTimeSeriesTransformer,
|
|
name: prepareTimeSeriesTransformer.name,
|
|
description: prepareTimeSeriesTransformer.description,
|
|
help: `
|
|
### Use cases
|
|
|
|
This takes query results and transforms them into a predictable timeseries format.
|
|
This transformer may be especially useful when using old panels that only expect the
|
|
many-frame timeseries format.
|
|
`,
|
|
categories: new Set([TransformerCategory.Reformat]),
|
|
};
|