BarChart: Fix coloring from thresholds and value mappings (#58285)

This commit is contained in:
Leon Sorokin
2022-11-10 07:43:32 -06:00
committed by GitHub
parent 30f0d66983
commit 778337e522
9 changed files with 1220 additions and 5 deletions
+7
View File
@@ -107,6 +107,13 @@ local dashboard = grafana.dashboard;
id: 0,
}
},
dashboard.new('barchart-thresholds-mappings', import 'panel-barchart/barchart-thresholds-mappings.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{
spec+: {
id: 0,
}
},
dashboard.new('candlestick', import 'panel-candlestick/candlestick.json') +
resource.addMetadata('folder', 'dev-dashboards') +
{
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -218,8 +218,8 @@ seqs: [
type: #MappingType & "range"
options: {
// to and from are `number | null` in current ts, really not sure what to do
from: int32 @grafanamaturity(NeedsExpertReview)
to: int32 @grafanamaturity(NeedsExpertReview)
from: float64 @grafanamaturity(NeedsExpertReview)
to: float64 @grafanamaturity(NeedsExpertReview)
result: #ValueMappingResult
}
} @cuetsy(kind="interface") @grafanamaturity(NeedsExpertReview)
+2 -2
View File
@@ -767,14 +767,14 @@ type PanelRepeatDirection string
type RangeMap struct {
Options struct {
// to and from are `number | null` in current ts, really not sure what to do
From int32 `json:"from"`
From float64 `json:"from"`
Result struct {
Color *string `json:"color,omitempty"`
Icon *string `json:"icon,omitempty"`
Index *int32 `json:"index,omitempty"`
Text *string `json:"text,omitempty"`
} `json:"result"`
To int32 `json:"to"`
To float64 `json:"to"`
} `json:"options"`
Type RangeMapType `json:"type"`
}
@@ -5,6 +5,8 @@ import {
compareDataFrameStructures,
DataFrame,
Field,
FieldColorModeId,
FieldType,
getFieldDisplayName,
PanelProps,
TimeRange,
@@ -12,6 +14,7 @@ import {
} from '@grafana/data';
import { PanelDataErrorView } from '@grafana/runtime';
import {
GraphGradientMode,
GraphNG,
GraphNGProps,
measureText,
@@ -233,6 +236,26 @@ export const BarChartPanel: React.FunctionComponent<Props> = ({
fillOpacity = (colorByField.config.custom.fillOpacity ?? 100) / 100;
// gradientMode? ignore?
getColor = (seriesIdx: number, valueIdx: number) => disp(colorByFieldRef.current?.values.get(valueIdx)).color!;
} else {
const hasPerBarColor = frame0Ref.current!.fields.some((f) => {
const fromThresholds =
f.config.custom?.gradientMode === GraphGradientMode.Scheme &&
f.config.color?.mode === FieldColorModeId.Thresholds;
return fromThresholds || f.config.mappings?.some((m) => m.options.result.color != null);
});
if (hasPerBarColor) {
// use opacity from first numeric field
let opacityField = frame0Ref.current!.fields.find((f) => f.type === FieldType.number)!;
fillOpacity = (opacityField.config.custom.fillOpacity ?? 100) / 100;
getColor = (seriesIdx: number, valueIdx: number) => {
let field = frame0Ref.current!.fields[seriesIdx];
return field.display!(field.values.get(valueIdx)).color!;
};
}
}
const prepConfig = (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => {
@@ -64,6 +64,8 @@ Panel: thema.#Lineage & {
// Set the mode of the gradient fill. Fill gradient is based on the line color. To change the color, use the standard color scheme field option.
// Gradient appearance is influenced by the Fill opacity setting.
gradientMode?: ui.GraphGradientMode | *"none"
// Threshold rendering
thresholdsStyle?: ui.GraphThresholdsStyleConfig
} @cuetsy(kind="interface")
},
]
@@ -85,6 +85,10 @@ export interface PanelFieldConfig extends ui.AxisConfig, ui.HideableFieldConfig
* Controls line width of the bars.
*/
lineWidth?: number;
/**
* Threshold rendering
*/
thresholdsStyle?: ui.GraphThresholdsStyleConfig;
}
export const defaultPanelFieldConfig: Partial<PanelFieldConfig> = {
+19 -1
View File
@@ -4,13 +4,16 @@ import {
FieldConfigProperty,
FieldType,
getFieldDisplayName,
identityOverrideProcessor,
PanelPlugin,
VizOrientation,
} from '@grafana/data';
import { config } from '@grafana/runtime';
import { GraphTransform, StackingMode, VisibilityMode } from '@grafana/schema';
import { GraphTransform, GraphTresholdsStyleMode, StackingMode, VisibilityMode } from '@grafana/schema';
import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui';
import { ThresholdsStyleEditor } from '../timeseries/ThresholdsStyleEditor';
import { BarChartPanel } from './BarChartPanel';
import { TickSpacingEditor } from './TickSpacingEditor';
import { PanelFieldConfig, PanelOptions, defaultPanelFieldConfig, defaultPanelOptions } from './models.gen';
@@ -85,6 +88,21 @@ export const plugin = new PanelPlugin<PanelOptions, PanelFieldConfig>(BarChartPa
hideFromDefaults: true,
});
builder.addCustomEditor({
id: 'thresholdsStyle',
path: 'thresholdsStyle',
name: 'Show thresholds',
category: ['Thresholds'],
defaultValue: { mode: GraphTresholdsStyleMode.Off },
settings: {
options: graphFieldOptions.thresholdsDisplayModes,
},
editor: ThresholdsStyleEditor,
override: ThresholdsStyleEditor,
process: identityOverrideProcessor,
shouldApply: () => true,
});
commonOptionsBuilder.addAxisConfig(builder, cfg, false);
commonOptionsBuilder.addHideFrom(builder);
},
@@ -20,6 +20,7 @@ import { maybeSortFrame } from '@grafana/data/src/transformations/transformers/j
import {
AxisPlacement,
GraphTransform,
GraphTresholdsStyleMode,
ScaleDirection,
ScaleDistribution,
ScaleOrientation,
@@ -192,6 +193,23 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<BarChartOptionsEX> = ({
softMax = 0;
}
// Render thresholds in graph
if (customConfig.thresholdsStyle && field.config.thresholds) {
const thresholdDisplay = customConfig.thresholdsStyle.mode ?? GraphTresholdsStyleMode.Off;
if (thresholdDisplay !== GraphTresholdsStyleMode.Off) {
builder.addThresholds({
config: customConfig.thresholdsStyle,
thresholds: field.config.thresholds,
scaleKey,
theme,
hardMin: field.config.min,
hardMax: field.config.max,
softMin: customConfig.axisSoftMin,
softMax: customConfig.axisSoftMax,
});
}
}
builder.addSeries({
scaleKey,
pxAlign: true,