mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
Refactor and unify option creation between new visualizations (#33867)
* Refactor and unify option creation between new visualizations * move to grafana/ui * move to grafana/ui * resolve duplicate scale config * more imports Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
parent
7b5223bf19
commit
fe5fc75ded
@ -11,10 +11,11 @@ import {
|
||||
VizOrientation,
|
||||
} from '@grafana/data';
|
||||
import { BarChartFieldConfig, BarChartOptions, BarValueVisibility, defaultBarChartFieldConfig } from './types';
|
||||
import { AxisPlacement, ScaleDirection, ScaleDistribution, ScaleOrientation } from '../uPlot/config';
|
||||
import { AxisPlacement, ScaleDirection, ScaleOrientation } from '../uPlot/config';
|
||||
import { BarsOptions, getConfig } from './bars';
|
||||
import { FIXED_UNIT } from '../GraphNG/GraphNG';
|
||||
import { Select } from 'uplot';
|
||||
import { ScaleDistribution } from '../uPlot/models.gen';
|
||||
|
||||
/** @alpha */
|
||||
export function preparePlotConfigBuilder(
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { ScaleDistribution } from './models.gen';
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
@ -49,15 +50,6 @@ export enum BarAlignment {
|
||||
After = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export enum ScaleDistribution {
|
||||
Linear = 'linear',
|
||||
Logarithmic = 'log',
|
||||
Ordinal = 'ordinal',
|
||||
}
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
|
@ -6,12 +6,12 @@ import {
|
||||
AxisPlacement,
|
||||
DrawStyle,
|
||||
PointVisibility,
|
||||
ScaleDistribution,
|
||||
ScaleOrientation,
|
||||
ScaleDirection,
|
||||
GraphTresholdsStyleMode,
|
||||
} from '../config';
|
||||
import { createTheme, ThresholdsMode } from '@grafana/data';
|
||||
import { ScaleDistribution } from '../models.gen';
|
||||
|
||||
describe('UPlotConfigBuilder', () => {
|
||||
const darkTheme = createTheme();
|
||||
|
@ -1,6 +1,7 @@
|
||||
import uPlot, { Scale, Range } from 'uplot';
|
||||
import { PlotConfigBuilder } from '../types';
|
||||
import { ScaleDistribution, ScaleOrientation, ScaleDirection } from '../config';
|
||||
import { ScaleOrientation, ScaleDirection } from '../config';
|
||||
import { ScaleDistribution } from '../models.gen';
|
||||
|
||||
export interface ScaleProps {
|
||||
scaleKey: string;
|
||||
@ -37,12 +38,12 @@ export class UPlotScaleBuilder extends PlotConfigBuilder<ScaleProps, Scale> {
|
||||
const distribution = !isTime
|
||||
? {
|
||||
distr:
|
||||
this.props.distribution === ScaleDistribution.Logarithmic
|
||||
this.props.distribution === ScaleDistribution.Log
|
||||
? 3
|
||||
: this.props.distribution === ScaleDistribution.Ordinal
|
||||
? 2
|
||||
: 1,
|
||||
log: this.props.distribution === ScaleDistribution.Logarithmic ? this.props.log || 2 : undefined,
|
||||
log: this.props.distribution === ScaleDistribution.Log ? this.props.log || 2 : undefined,
|
||||
}
|
||||
: {};
|
||||
|
||||
|
@ -4,7 +4,7 @@ AxisPlacement: "auto" | "top" | "right" | "bottom" | "left" | "hidden" @cuetsy(t
|
||||
PointVisibility: "auto" | "never" | "always" @cuetsy(targetType="enum")
|
||||
DrawStyle: "line" | "bars" | "points" @cuetsy(targetType="enum")
|
||||
LineInterpolation: "linear" | "smooth" | "stepBefore" | "stepAfter" @cuetsy(targetType="enum")
|
||||
ScaleDistribution: "linear" | "log" @cuetsy(targetType="enum")
|
||||
ScaleDistribution: "linear" | "log" | "ordinal" @cuetsy(targetType="enum")
|
||||
GraphGradientMode: "none" | "opacity" | "hue" | "scheme" @cuetsy(targetType="enum")
|
||||
|
||||
LineStyle: {
|
||||
|
@ -30,6 +30,7 @@ export enum LineInterpolation {
|
||||
export enum ScaleDistribution {
|
||||
Linear = 'linear',
|
||||
Log = 'log',
|
||||
Ordinal = 'ordinal',
|
||||
}
|
||||
export enum GraphGradientMode {
|
||||
Hue = 'hue',
|
||||
|
@ -7,6 +7,7 @@ export * from './components';
|
||||
export * from './types';
|
||||
export * from './utils';
|
||||
export * from './themes';
|
||||
export * from './options';
|
||||
export * from './slate-plugins';
|
||||
|
||||
// Exposes standard editors for registries of optionsUi config and panel options UI
|
||||
|
153
packages/grafana-ui/src/options/builder/axis.tsx
Normal file
153
packages/grafana-ui/src/options/builder/axis.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
FieldConfigEditorBuilder,
|
||||
FieldOverrideEditorProps,
|
||||
FieldType,
|
||||
identityOverrideProcessor,
|
||||
SelectableValue,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
AxisConfig,
|
||||
AxisPlacement,
|
||||
graphFieldOptions,
|
||||
ScaleDistributionConfig,
|
||||
Select,
|
||||
HorizontalGroup,
|
||||
RadioButtonGroup,
|
||||
} from '../../index';
|
||||
import { ScaleDistribution } from '../../components/uPlot/models.gen';
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export function addAxisConfig(
|
||||
builder: FieldConfigEditorBuilder<AxisConfig>,
|
||||
defaultConfig: AxisConfig,
|
||||
hideScale?: boolean
|
||||
) {
|
||||
builder
|
||||
.addRadio({
|
||||
path: 'axisPlacement',
|
||||
name: 'Placement',
|
||||
category: ['Axis'],
|
||||
defaultValue: graphFieldOptions.axisPlacement[0].value,
|
||||
settings: {
|
||||
options: graphFieldOptions.axisPlacement,
|
||||
},
|
||||
})
|
||||
.addTextInput({
|
||||
path: 'axisLabel',
|
||||
name: 'Label',
|
||||
category: ['Axis'],
|
||||
defaultValue: '',
|
||||
settings: {
|
||||
placeholder: 'Optional text',
|
||||
},
|
||||
showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden,
|
||||
// no matter what the field type is
|
||||
shouldApply: () => true,
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisWidth',
|
||||
name: 'Width',
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'Auto',
|
||||
},
|
||||
showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden,
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisSoftMin',
|
||||
name: 'Soft min',
|
||||
defaultValue: defaultConfig.axisSoftMin,
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'See: Standard options > Min',
|
||||
},
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisSoftMax',
|
||||
name: 'Soft max',
|
||||
defaultValue: defaultConfig.axisSoftMax,
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'See: Standard options > Max',
|
||||
},
|
||||
});
|
||||
if (!hideScale) {
|
||||
builder.addCustomEditor<void, ScaleDistributionConfig>({
|
||||
id: 'scaleDistribution',
|
||||
path: 'scaleDistribution',
|
||||
name: 'Scale',
|
||||
category: ['Axis'],
|
||||
editor: ScaleDistributionEditor,
|
||||
override: ScaleDistributionEditor,
|
||||
defaultValue: { type: ScaleDistribution.Linear },
|
||||
shouldApply: (f) => f.type === FieldType.number,
|
||||
process: identityOverrideProcessor,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const DISTRIBUTION_OPTIONS: Array<SelectableValue<ScaleDistribution>> = [
|
||||
{
|
||||
label: 'Linear',
|
||||
value: ScaleDistribution.Linear,
|
||||
},
|
||||
{
|
||||
label: 'Logarithmic',
|
||||
value: ScaleDistribution.Log,
|
||||
},
|
||||
];
|
||||
|
||||
const LOG_DISTRIBUTION_OPTIONS: Array<SelectableValue<number>> = [
|
||||
{
|
||||
label: '2',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '10',
|
||||
value: 10,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
const ScaleDistributionEditor: React.FC<FieldOverrideEditorProps<ScaleDistributionConfig, any>> = ({
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
return (
|
||||
<HorizontalGroup>
|
||||
<RadioButtonGroup
|
||||
value={value.type || ScaleDistribution.Linear}
|
||||
options={DISTRIBUTION_OPTIONS}
|
||||
onChange={(v) => {
|
||||
console.log(v, value);
|
||||
onChange({
|
||||
...value,
|
||||
type: v!,
|
||||
log: v === ScaleDistribution.Linear ? undefined : 2,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{value.type === ScaleDistribution.Log && (
|
||||
<Select
|
||||
allowCustomValue={false}
|
||||
autoFocus
|
||||
options={LOG_DISTRIBUTION_OPTIONS}
|
||||
value={value.log || 2}
|
||||
prefix={'base'}
|
||||
width={12}
|
||||
onChange={(v) => {
|
||||
onChange({
|
||||
...value,
|
||||
log: v.value!,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
56
packages/grafana-ui/src/options/builder/hideSeries.tsx
Normal file
56
packages/grafana-ui/src/options/builder/hideSeries.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { startCase } from 'lodash';
|
||||
import { FilterPill, HorizontalGroup } from '../../index';
|
||||
import { FieldConfigEditorBuilder, FieldConfigEditorProps } from '@grafana/data';
|
||||
import { HideableFieldConfig, HideSeriesConfig } from '../../components/uPlot/config';
|
||||
|
||||
const SeriesConfigEditor: React.FC<FieldConfigEditorProps<HideSeriesConfig, {}>> = (props) => {
|
||||
const { value, onChange } = props;
|
||||
|
||||
const onChangeToggle = useCallback(
|
||||
(prop: keyof HideSeriesConfig) => {
|
||||
onChange({ ...value, [prop]: !value[prop] });
|
||||
},
|
||||
[value, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<HorizontalGroup spacing="xs">
|
||||
{Object.keys(value).map((k) => {
|
||||
const key = k as keyof HideSeriesConfig;
|
||||
return (
|
||||
<FilterPill
|
||||
icon={value[key] ? 'eye-slash' : 'eye'}
|
||||
onClick={() => onChangeToggle(key)}
|
||||
key={key}
|
||||
label={startCase(key)}
|
||||
selected={value[key]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export function addHideFrom(builder: FieldConfigEditorBuilder<HideableFieldConfig>) {
|
||||
builder.addCustomEditor({
|
||||
id: 'hideFrom',
|
||||
name: 'Hide in area',
|
||||
category: ['Series'],
|
||||
path: 'hideFrom',
|
||||
defaultValue: {
|
||||
tooltip: false,
|
||||
graph: false,
|
||||
legend: false,
|
||||
},
|
||||
editor: SeriesConfigEditor,
|
||||
override: SeriesConfigEditor,
|
||||
shouldApply: () => true,
|
||||
hideFromDefaults: true,
|
||||
hideFromOverrides: true,
|
||||
process: (value) => value,
|
||||
});
|
||||
}
|
3
packages/grafana-ui/src/options/builder/index.ts
Normal file
3
packages/grafana-ui/src/options/builder/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './axis';
|
||||
export * from './hideSeries';
|
||||
export * from './legend';
|
57
packages/grafana-ui/src/options/builder/legend.tsx
Normal file
57
packages/grafana-ui/src/options/builder/legend.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { PanelOptionsEditorBuilder, standardEditorsRegistry, StatsPickerConfigSettings } from '@grafana/data';
|
||||
import { LegendDisplayMode } from '../../index';
|
||||
import { OptionsWithLegend } from '../models.gen';
|
||||
|
||||
/**
|
||||
* @alpha
|
||||
*/
|
||||
export function addLegendOptions<T extends OptionsWithLegend>(
|
||||
builder: PanelOptionsEditorBuilder<T>,
|
||||
includeLegendCalcs = true
|
||||
) {
|
||||
builder
|
||||
.addRadio({
|
||||
path: 'legend.displayMode',
|
||||
name: 'Legend mode',
|
||||
category: ['Legend'],
|
||||
description: '',
|
||||
defaultValue: LegendDisplayMode.List,
|
||||
settings: {
|
||||
options: [
|
||||
{ value: LegendDisplayMode.List, label: 'List' },
|
||||
{ value: LegendDisplayMode.Table, label: 'Table' },
|
||||
{ value: LegendDisplayMode.Hidden, label: 'Hidden' },
|
||||
],
|
||||
},
|
||||
})
|
||||
.addRadio({
|
||||
path: 'legend.placement',
|
||||
name: 'Legend placement',
|
||||
category: ['Legend'],
|
||||
description: '',
|
||||
defaultValue: 'bottom',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'bottom', label: 'Bottom' },
|
||||
{ value: 'right', label: 'Right' },
|
||||
],
|
||||
},
|
||||
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
});
|
||||
|
||||
if (includeLegendCalcs) {
|
||||
builder.addCustomEditor<StatsPickerConfigSettings, string[]>({
|
||||
id: 'legend.calcs',
|
||||
path: 'legend.calcs',
|
||||
name: 'Legend values',
|
||||
category: ['Legend'],
|
||||
description: 'Select values or calculations to show in legend',
|
||||
editor: standardEditorsRegistry.get('stats-picker').editor as any,
|
||||
defaultValue: [],
|
||||
settings: {
|
||||
allowMultiple: true,
|
||||
},
|
||||
showIf: (currentConfig) => currentConfig.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
});
|
||||
}
|
||||
}
|
4
packages/grafana-ui/src/options/index.ts
Normal file
4
packages/grafana-ui/src/options/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// namespace is too big
|
||||
export * as commonOptionsBuilder from './builder';
|
||||
|
||||
export * from './models.gen';
|
7
packages/grafana-ui/src/options/models.gen.ts
Normal file
7
packages/grafana-ui/src/options/models.gen.ts
Normal file
@ -0,0 +1,7 @@
|
||||
// TODO: this should be generated with cue
|
||||
|
||||
import { VizLegendOptions } from '../components';
|
||||
|
||||
export interface OptionsWithLegend {
|
||||
legend: VizLegendOptions;
|
||||
}
|
@ -7,8 +7,14 @@ import {
|
||||
VizOrientation,
|
||||
} from '@grafana/data';
|
||||
import { BarChartPanel } from './BarChartPanel';
|
||||
import { BarChartFieldConfig, BarChartOptions, StackingMode, BarValueVisibility, graphFieldOptions } from '@grafana/ui';
|
||||
import { addAxisConfig, addHideFrom, addLegendOptions } from '../timeseries/config';
|
||||
import {
|
||||
BarChartFieldConfig,
|
||||
BarChartOptions,
|
||||
StackingMode,
|
||||
BarValueVisibility,
|
||||
graphFieldOptions,
|
||||
commonOptionsBuilder,
|
||||
} from '@grafana/ui';
|
||||
import { defaultBarChartFieldConfig } from '@grafana/ui/src/components/BarChart/types';
|
||||
|
||||
export const plugin = new PanelPlugin<BarChartOptions, BarChartFieldConfig>(BarChartPanel)
|
||||
@ -56,8 +62,8 @@ export const plugin = new PanelPlugin<BarChartOptions, BarChartFieldConfig>(BarC
|
||||
},
|
||||
});
|
||||
|
||||
addAxisConfig(builder, cfg, true);
|
||||
addHideFrom(builder);
|
||||
commonOptionsBuilder.addAxisConfig(builder, cfg, true);
|
||||
commonOptionsBuilder.addHideFrom(builder);
|
||||
},
|
||||
})
|
||||
.setPanelOptions((builder) => {
|
||||
@ -113,7 +119,7 @@ export const plugin = new PanelPlugin<BarChartOptions, BarChartFieldConfig>(BarC
|
||||
},
|
||||
});
|
||||
|
||||
addLegendOptions(builder);
|
||||
commonOptionsBuilder.addLegendOptions(builder);
|
||||
});
|
||||
|
||||
function countNumberFields(data?: DataFrame[]): number {
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
getFieldDisplayName,
|
||||
getFieldSeriesColor,
|
||||
GrafanaTheme2,
|
||||
histogramBucketSizes,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
Themeable2,
|
||||
@ -16,12 +15,15 @@ import {
|
||||
VizLayout,
|
||||
AxisPlacement,
|
||||
ScaleDirection,
|
||||
ScaleDistribution,
|
||||
ScaleOrientation,
|
||||
} from '@grafana/ui';
|
||||
|
||||
import { histogramFrameBucketMaxFieldName } from '@grafana/data/src/transformations/transformers/histogram';
|
||||
import {
|
||||
histogramBucketSizes,
|
||||
histogramFrameBucketMaxFieldName,
|
||||
} from '@grafana/data/src/transformations/transformers/histogram';
|
||||
import { PanelOptions } from './models.gen';
|
||||
import { ScaleDistribution } from '@grafana/ui/src/components/uPlot/models.gen';
|
||||
|
||||
export interface HistogramProps extends Themeable2 {
|
||||
options: PanelOptions; // used for diff
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { FieldColorModeId, FieldConfigProperty, PanelPlugin, ReducerID, standardEditorsRegistry } from '@grafana/data';
|
||||
import { PieChartPanel } from './PieChartPanel';
|
||||
import { PieChartOptions, PieChartType, PieChartLabels, PieChartLegendValues } from './types';
|
||||
import { LegendDisplayMode } from '@grafana/ui';
|
||||
import { LegendDisplayMode, commonOptionsBuilder } from '@grafana/ui';
|
||||
import { PieChartPanelChangedHandler } from './migrations';
|
||||
import { addHideFrom } from '../timeseries/config';
|
||||
|
||||
export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
||||
.setPanelChangeHandler(PieChartPanelChangedHandler)
|
||||
@ -22,7 +21,7 @@ export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
||||
},
|
||||
},
|
||||
useCustomConfig: (builder) => {
|
||||
addHideFrom(builder);
|
||||
commonOptionsBuilder.addHideFrom(builder);
|
||||
},
|
||||
})
|
||||
.setPanelOptions((builder) => {
|
||||
@ -73,42 +72,20 @@ export const plugin = new PanelPlugin<PieChartOptions>(PieChartPanel)
|
||||
{ value: 'none', label: 'Hidden' },
|
||||
],
|
||||
},
|
||||
})
|
||||
.addRadio({
|
||||
path: 'legend.displayMode',
|
||||
name: 'Legend mode',
|
||||
description: '',
|
||||
defaultValue: LegendDisplayMode.List,
|
||||
settings: {
|
||||
options: [
|
||||
{ value: LegendDisplayMode.List, label: 'List' },
|
||||
{ value: LegendDisplayMode.Table, label: 'Table' },
|
||||
{ value: LegendDisplayMode.Hidden, label: 'Hidden' },
|
||||
],
|
||||
},
|
||||
})
|
||||
.addRadio({
|
||||
path: 'legend.placement',
|
||||
name: 'Legend placement',
|
||||
description: '',
|
||||
defaultValue: 'right',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'bottom', label: 'Bottom' },
|
||||
{ value: 'right', label: 'Right' },
|
||||
],
|
||||
},
|
||||
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
})
|
||||
.addMultiSelect({
|
||||
name: 'Legend values',
|
||||
path: 'legend.values',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: PieChartLegendValues.Percent, label: 'Percent' },
|
||||
{ value: PieChartLegendValues.Value, label: 'Value' },
|
||||
],
|
||||
},
|
||||
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
});
|
||||
|
||||
commonOptionsBuilder.addLegendOptions(builder, false);
|
||||
|
||||
builder.addMultiSelect({
|
||||
name: 'Legend values',
|
||||
path: 'legend.values',
|
||||
category: ['Legend'],
|
||||
settings: {
|
||||
options: [
|
||||
{ value: PieChartLegendValues.Percent, label: 'Percent' },
|
||||
{ value: PieChartLegendValues.Value, label: 'Value' },
|
||||
],
|
||||
},
|
||||
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
});
|
||||
});
|
||||
|
@ -1,32 +0,0 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { startCase } from 'lodash';
|
||||
import { FilterPill, HorizontalGroup } from '@grafana/ui';
|
||||
import { FieldConfigEditorProps } from '@grafana/data';
|
||||
import { HideSeriesConfig } from '@grafana/ui/src/components/uPlot/config';
|
||||
|
||||
export const SeriesConfigEditor: React.FC<FieldConfigEditorProps<HideSeriesConfig, {}>> = (props) => {
|
||||
const { value, onChange } = props;
|
||||
|
||||
const onChangeToggle = useCallback(
|
||||
(prop: keyof HideSeriesConfig) => {
|
||||
onChange({ ...value, [prop]: !value[prop] });
|
||||
},
|
||||
[value, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<HorizontalGroup spacing="xs">
|
||||
{Object.keys(value).map((key: keyof HideSeriesConfig) => {
|
||||
return (
|
||||
<FilterPill
|
||||
icon={value[key] ? 'eye-slash' : 'eye'}
|
||||
onClick={() => onChangeToggle(key)}
|
||||
key={key}
|
||||
label={startCase(key)}
|
||||
selected={value[key]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
@ -1,63 +0,0 @@
|
||||
import React from 'react';
|
||||
import { FieldOverrideEditorProps, SelectableValue } from '@grafana/data';
|
||||
import { HorizontalGroup, RadioButtonGroup, ScaleDistribution, ScaleDistributionConfig, Select } from '@grafana/ui';
|
||||
|
||||
const DISTRIBUTION_OPTIONS: Array<SelectableValue<ScaleDistribution>> = [
|
||||
{
|
||||
label: 'Linear',
|
||||
value: ScaleDistribution.Linear,
|
||||
},
|
||||
{
|
||||
label: 'Logarithmic',
|
||||
value: ScaleDistribution.Logarithmic,
|
||||
},
|
||||
];
|
||||
|
||||
const LOG_DISTRIBUTION_OPTIONS: Array<SelectableValue<number>> = [
|
||||
{
|
||||
label: '2',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '10',
|
||||
value: 10,
|
||||
},
|
||||
];
|
||||
|
||||
export const ScaleDistributionEditor: React.FC<FieldOverrideEditorProps<ScaleDistributionConfig, any>> = ({
|
||||
value,
|
||||
onChange,
|
||||
}) => {
|
||||
return (
|
||||
<HorizontalGroup>
|
||||
<RadioButtonGroup
|
||||
value={value.type || ScaleDistribution.Linear}
|
||||
options={DISTRIBUTION_OPTIONS}
|
||||
onChange={(v) => {
|
||||
console.log(v, value);
|
||||
onChange({
|
||||
...value,
|
||||
type: v!,
|
||||
log: v === ScaleDistribution.Linear ? undefined : 2,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{value.type === ScaleDistribution.Logarithmic && (
|
||||
<Select
|
||||
allowCustomValue={false}
|
||||
autoFocus
|
||||
options={LOG_DISTRIBUTION_OPTIONS}
|
||||
value={value.log || 2}
|
||||
prefix={'base'}
|
||||
width={12}
|
||||
onChange={(v) => {
|
||||
onChange({
|
||||
...value,
|
||||
log: v.value!,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
@ -4,35 +4,24 @@ import {
|
||||
FieldConfigProperty,
|
||||
FieldType,
|
||||
identityOverrideProcessor,
|
||||
PanelOptionsEditorBuilder,
|
||||
SetFieldConfigOptionsArgs,
|
||||
standardEditorsRegistry,
|
||||
StatsPickerConfigSettings,
|
||||
stringOverrideProcessor,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
AxisConfig,
|
||||
AxisPlacement,
|
||||
BarAlignment,
|
||||
DrawStyle,
|
||||
GraphFieldConfig,
|
||||
graphFieldOptions,
|
||||
GraphGradientMode,
|
||||
HideableFieldConfig,
|
||||
LegendDisplayMode,
|
||||
LineInterpolation,
|
||||
LineStyle,
|
||||
PointVisibility,
|
||||
ScaleDistribution,
|
||||
ScaleDistributionConfig,
|
||||
StackingConfig,
|
||||
StackingMode,
|
||||
commonOptionsBuilder,
|
||||
} from '@grafana/ui';
|
||||
import { SeriesConfigEditor } from './HideSeriesConfigEditor';
|
||||
import { ScaleDistributionEditor } from './ScaleDistributionEditor';
|
||||
import { LineStyleEditor } from './LineStyleEditor';
|
||||
import { FillBellowToEditor } from './FillBelowToEditor';
|
||||
import { OptionsWithLegend } from './types';
|
||||
import { SpanNullsEditor } from './SpanNullsEditor';
|
||||
import { StackingEditor } from './StackingEditor';
|
||||
|
||||
@ -188,8 +177,8 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig): SetFieldConfigOption
|
||||
});
|
||||
|
||||
addStackingConfig(builder, cfg.stacking);
|
||||
addAxisConfig(builder, cfg);
|
||||
addHideFrom(builder);
|
||||
commonOptionsBuilder.addAxisConfig(builder, cfg);
|
||||
commonOptionsBuilder.addHideFrom(builder);
|
||||
|
||||
builder.addSelect({
|
||||
path: 'thresholdsStyle.mode',
|
||||
@ -204,140 +193,6 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig): SetFieldConfigOption
|
||||
};
|
||||
}
|
||||
|
||||
export function addHideFrom(builder: FieldConfigEditorBuilder<HideableFieldConfig>) {
|
||||
builder.addCustomEditor({
|
||||
id: 'hideFrom',
|
||||
name: 'Hide in area',
|
||||
category: ['Series'],
|
||||
path: 'hideFrom',
|
||||
defaultValue: {
|
||||
tooltip: false,
|
||||
graph: false,
|
||||
legend: false,
|
||||
},
|
||||
editor: SeriesConfigEditor,
|
||||
override: SeriesConfigEditor,
|
||||
shouldApply: () => true,
|
||||
hideFromDefaults: true,
|
||||
hideFromOverrides: true,
|
||||
process: (value) => value,
|
||||
});
|
||||
}
|
||||
|
||||
export function addAxisConfig(
|
||||
builder: FieldConfigEditorBuilder<AxisConfig>,
|
||||
defaultConfig: AxisConfig,
|
||||
hideScale?: boolean
|
||||
) {
|
||||
builder
|
||||
.addRadio({
|
||||
path: 'axisPlacement',
|
||||
name: 'Placement',
|
||||
category: ['Axis'],
|
||||
defaultValue: graphFieldOptions.axisPlacement[0].value,
|
||||
settings: {
|
||||
options: graphFieldOptions.axisPlacement,
|
||||
},
|
||||
})
|
||||
.addTextInput({
|
||||
path: 'axisLabel',
|
||||
name: 'Label',
|
||||
category: ['Axis'],
|
||||
defaultValue: '',
|
||||
settings: {
|
||||
placeholder: 'Optional text',
|
||||
},
|
||||
showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden,
|
||||
// no matter what the field type is
|
||||
shouldApply: () => true,
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisWidth',
|
||||
name: 'Width',
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'Auto',
|
||||
},
|
||||
showIf: (c) => c.axisPlacement !== AxisPlacement.Hidden,
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisSoftMin',
|
||||
name: 'Soft min',
|
||||
defaultValue: defaultConfig.axisSoftMin,
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'See: Standard options > Min',
|
||||
},
|
||||
})
|
||||
.addNumberInput({
|
||||
path: 'axisSoftMax',
|
||||
name: 'Soft max',
|
||||
defaultValue: defaultConfig.axisSoftMax,
|
||||
category: ['Axis'],
|
||||
settings: {
|
||||
placeholder: 'See: Standard options > Max',
|
||||
},
|
||||
});
|
||||
if (!hideScale) {
|
||||
builder.addCustomEditor<void, ScaleDistributionConfig>({
|
||||
id: 'scaleDistribution',
|
||||
path: 'scaleDistribution',
|
||||
name: 'Scale',
|
||||
category: ['Axis'],
|
||||
editor: ScaleDistributionEditor,
|
||||
override: ScaleDistributionEditor,
|
||||
defaultValue: { type: ScaleDistribution.Linear },
|
||||
shouldApply: (f) => f.type === FieldType.number,
|
||||
process: identityOverrideProcessor,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function addLegendOptions<T extends OptionsWithLegend>(builder: PanelOptionsEditorBuilder<T>) {
|
||||
builder
|
||||
.addRadio({
|
||||
path: 'legend.displayMode',
|
||||
name: 'Legend mode',
|
||||
category: ['Legend'],
|
||||
description: '',
|
||||
defaultValue: LegendDisplayMode.List,
|
||||
settings: {
|
||||
options: [
|
||||
{ value: LegendDisplayMode.List, label: 'List' },
|
||||
{ value: LegendDisplayMode.Table, label: 'Table' },
|
||||
{ value: LegendDisplayMode.Hidden, label: 'Hidden' },
|
||||
],
|
||||
},
|
||||
})
|
||||
.addRadio({
|
||||
path: 'legend.placement',
|
||||
name: 'Legend placement',
|
||||
category: ['Legend'],
|
||||
description: '',
|
||||
defaultValue: 'bottom',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'bottom', label: 'Bottom' },
|
||||
{ value: 'right', label: 'Right' },
|
||||
],
|
||||
},
|
||||
showIf: (c) => c.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
})
|
||||
.addCustomEditor<StatsPickerConfigSettings, string[]>({
|
||||
id: 'legend.calcs',
|
||||
path: 'legend.calcs',
|
||||
name: 'Legend values',
|
||||
category: ['Legend'],
|
||||
description: 'Select values or calculations to show in legend',
|
||||
editor: standardEditorsRegistry.get('stats-picker').editor as any,
|
||||
defaultValue: [],
|
||||
settings: {
|
||||
allowMultiple: true,
|
||||
},
|
||||
showIf: (currentConfig) => currentConfig.legend.displayMode !== LegendDisplayMode.Hidden,
|
||||
});
|
||||
}
|
||||
|
||||
export function addStackingConfig(
|
||||
builder: FieldConfigEditorBuilder<{ stacking: StackingConfig }>,
|
||||
defaultConfig?: StackingConfig
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { GraphFieldConfig } from '@grafana/ui';
|
||||
import { GraphFieldConfig, commonOptionsBuilder } from '@grafana/ui';
|
||||
import { TimeSeriesPanel } from './TimeSeriesPanel';
|
||||
import { graphPanelChangedHandler } from './migrations';
|
||||
import { Options } from './types';
|
||||
import { addLegendOptions, defaultGraphConfig, getGraphFieldConfig } from './config';
|
||||
import { defaultGraphConfig, getGraphFieldConfig } from './config';
|
||||
|
||||
export const plugin = new PanelPlugin<Options, GraphFieldConfig>(TimeSeriesPanel)
|
||||
.setPanelChangeHandler(graphPanelChangedHandler)
|
||||
@ -24,6 +24,6 @@ export const plugin = new PanelPlugin<Options, GraphFieldConfig>(TimeSeriesPanel
|
||||
},
|
||||
});
|
||||
|
||||
addLegendOptions(builder);
|
||||
commonOptionsBuilder.addLegendOptions(builder);
|
||||
})
|
||||
.setDataSupport({ annotations: true, alertStates: true });
|
||||
|
@ -1,9 +1,4 @@
|
||||
import { VizLegendOptions, VizTooltipOptions } from '@grafana/ui';
|
||||
|
||||
export interface OptionsWithLegend {
|
||||
legend: VizLegendOptions;
|
||||
}
|
||||
|
||||
import { VizTooltipOptions, OptionsWithLegend } from '@grafana/ui';
|
||||
export interface Options extends OptionsWithLegend {
|
||||
tooltipOptions: VizTooltipOptions;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { DrawStyle, GraphFieldConfig } from '@grafana/ui';
|
||||
import { DrawStyle, GraphFieldConfig, commonOptionsBuilder } from '@grafana/ui';
|
||||
import { XYChartPanel } from './XYChartPanel';
|
||||
import { Options } from './types';
|
||||
import { XYDimsEditor } from './XYDimsEditor';
|
||||
import { getGraphFieldConfig, defaultGraphConfig, addLegendOptions } from '../timeseries/config';
|
||||
import { getGraphFieldConfig, defaultGraphConfig } from '../timeseries/config';
|
||||
|
||||
export const plugin = new PanelPlugin<Options, GraphFieldConfig>(XYChartPanel)
|
||||
.useFieldConfig(
|
||||
@ -34,5 +34,5 @@ export const plugin = new PanelPlugin<Options, GraphFieldConfig>(XYChartPanel)
|
||||
},
|
||||
});
|
||||
|
||||
addLegendOptions(builder);
|
||||
commonOptionsBuilder.addLegendOptions(builder);
|
||||
});
|
||||
|
@ -1,6 +1,4 @@
|
||||
import { VizTooltipOptions } from '@grafana/ui';
|
||||
import { OptionsWithLegend } from '../timeseries/types';
|
||||
|
||||
import { VizTooltipOptions, OptionsWithLegend } from '@grafana/ui';
|
||||
export interface XYDimensionConfig {
|
||||
frame: number;
|
||||
x?: string; // name | first
|
||||
|
Loading…
Reference in New Issue
Block a user