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