1import {
2  FieldColorModeId,
3  FieldConfigProperty,
4  FieldType,
5  identityOverrideProcessor,
6  SetFieldConfigOptionsArgs,
7  stringOverrideProcessor,
8} from '@grafana/data';
9import {
10  BarAlignment,
11  GraphDrawStyle,
12  GraphFieldConfig,
13  GraphGradientMode,
14  LineInterpolation,
15  LineStyle,
16  VisibilityMode,
17  StackingMode,
18  GraphTresholdsStyleMode,
19} from '@grafana/schema';
20
21import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui';
22
23import { LineStyleEditor } from './LineStyleEditor';
24import { FillBellowToEditor } from './FillBelowToEditor';
25import { SpanNullsEditor } from './SpanNullsEditor';
26import { ThresholdsStyleEditor } from './ThresholdsStyleEditor';
27
28export const defaultGraphConfig: GraphFieldConfig = {
29  drawStyle: GraphDrawStyle.Line,
30  lineInterpolation: LineInterpolation.Linear,
31  lineWidth: 1,
32  fillOpacity: 0,
33  gradientMode: GraphGradientMode.None,
34  barAlignment: BarAlignment.Center,
35  stacking: {
36    mode: StackingMode.None,
37    group: 'A',
38  },
39  axisGridShow: true,
40};
41
42const categoryStyles = ['Graph styles'];
43
44export function getGraphFieldConfig(cfg: GraphFieldConfig): SetFieldConfigOptionsArgs<GraphFieldConfig> {
45  return {
46    standardOptions: {
47      [FieldConfigProperty.Color]: {
48        settings: {
49          byValueSupport: true,
50          bySeriesSupport: true,
51          preferThresholdsMode: false,
52        },
53        defaultValue: {
54          mode: FieldColorModeId.PaletteClassic,
55        },
56      },
57    },
58    useCustomConfig: (builder) => {
59      builder
60        .addRadio({
61          path: 'drawStyle',
62          name: 'Style',
63          category: categoryStyles,
64          defaultValue: cfg.drawStyle,
65          settings: {
66            options: graphFieldOptions.drawStyle,
67          },
68        })
69        .addRadio({
70          path: 'lineInterpolation',
71          name: 'Line interpolation',
72          category: categoryStyles,
73          defaultValue: cfg.lineInterpolation,
74          settings: {
75            options: graphFieldOptions.lineInterpolation,
76          },
77          showIf: (c) => c.drawStyle === GraphDrawStyle.Line,
78        })
79        .addRadio({
80          path: 'barAlignment',
81          name: 'Bar alignment',
82          category: categoryStyles,
83          defaultValue: cfg.barAlignment,
84          settings: {
85            options: graphFieldOptions.barAlignment,
86          },
87          showIf: (c) => c.drawStyle === GraphDrawStyle.Bars,
88        })
89        .addSliderInput({
90          path: 'lineWidth',
91          name: 'Line width',
92          category: categoryStyles,
93          defaultValue: cfg.lineWidth,
94          settings: {
95            min: 0,
96            max: 10,
97            step: 1,
98            ariaLabelForHandle: 'Line width',
99          },
100          showIf: (c) => c.drawStyle !== GraphDrawStyle.Points,
101        })
102        .addSliderInput({
103          path: 'fillOpacity',
104          name: 'Fill opacity',
105          category: categoryStyles,
106          defaultValue: cfg.fillOpacity,
107          settings: {
108            min: 0,
109            max: 100,
110            step: 1,
111            ariaLabelForHandle: 'Fill opacity',
112          },
113          showIf: (c) => c.drawStyle !== GraphDrawStyle.Points,
114        })
115        .addRadio({
116          path: 'gradientMode',
117          name: 'Gradient mode',
118          category: categoryStyles,
119          defaultValue: graphFieldOptions.fillGradient[0].value,
120          settings: {
121            options: graphFieldOptions.fillGradient,
122          },
123          showIf: (c) => c.drawStyle !== GraphDrawStyle.Points,
124        })
125        .addCustomEditor({
126          id: 'fillBelowTo',
127          path: 'fillBelowTo',
128          name: 'Fill below to',
129          category: categoryStyles,
130          editor: FillBellowToEditor,
131          override: FillBellowToEditor,
132          process: stringOverrideProcessor,
133          hideFromDefaults: true,
134          shouldApply: (f) => true,
135        })
136        .addCustomEditor<void, LineStyle>({
137          id: 'lineStyle',
138          path: 'lineStyle',
139          name: 'Line style',
140          category: categoryStyles,
141          showIf: (c) => c.drawStyle === GraphDrawStyle.Line,
142          editor: LineStyleEditor,
143          override: LineStyleEditor,
144          process: identityOverrideProcessor,
145          shouldApply: (f) => f.type === FieldType.number,
146        })
147        .addCustomEditor<void, boolean>({
148          id: 'spanNulls',
149          path: 'spanNulls',
150          name: 'Connect null values',
151          category: categoryStyles,
152          defaultValue: false,
153          editor: SpanNullsEditor,
154          override: SpanNullsEditor,
155          showIf: (c) => c.drawStyle === GraphDrawStyle.Line,
156          shouldApply: (f) => f.type !== FieldType.time,
157          process: identityOverrideProcessor,
158        })
159        .addRadio({
160          path: 'showPoints',
161          name: 'Show points',
162          category: categoryStyles,
163          defaultValue: graphFieldOptions.showPoints[0].value,
164          settings: {
165            options: graphFieldOptions.showPoints,
166          },
167          showIf: (c) => c.drawStyle !== GraphDrawStyle.Points,
168        })
169        .addSliderInput({
170          path: 'pointSize',
171          name: 'Point size',
172          category: categoryStyles,
173          defaultValue: 5,
174          settings: {
175            min: 1,
176            max: 40,
177            step: 1,
178            ariaLabelForHandle: 'Point size',
179          },
180          showIf: (c) => c.showPoints !== VisibilityMode.Never || c.drawStyle === GraphDrawStyle.Points,
181        });
182
183      commonOptionsBuilder.addStackingConfig(builder, cfg.stacking, categoryStyles);
184      commonOptionsBuilder.addAxisConfig(builder, cfg);
185      commonOptionsBuilder.addHideFrom(builder);
186
187      builder.addCustomEditor({
188        id: 'thresholdsStyle',
189        path: 'thresholdsStyle',
190        name: 'Show thresholds',
191        category: ['Thresholds'],
192        defaultValue: { mode: GraphTresholdsStyleMode.Off },
193        settings: {
194          options: graphFieldOptions.thresholdsDisplayModes,
195        },
196        editor: ThresholdsStyleEditor,
197        override: ThresholdsStyleEditor,
198        process: identityOverrideProcessor,
199        shouldApply: () => true,
200      });
201    },
202  };
203}
204