GraphNG: Fix thresholds by color not following data update (#48571)

* GraphNG: Fix thresholds by  color not following data update

* Refactor dynamicSeriesColor to time series

* avoid exposing frames on builder
rely on seriesIdx & cached alignedFrame to grab field
handle dynamic fill recoloring
only recolor when not in a special gradient mode

* bail when opacity = 0

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Zoltán Bedi
2022-05-04 10:41:03 +02:00
committed by GitHub
co-authored by Leon Sorokin
parent 713e624790
commit b420179be4
3 changed files with 58 additions and 2 deletions
@@ -5,6 +5,7 @@ import {
DataFrame,
DefaultTimeZone,
EventBusSrv,
FieldColorModeId,
FieldConfig,
FieldMatcherID,
fieldMatchers,
@@ -38,6 +39,9 @@ function mockDataFrame() {
const f1Config: FieldConfig<GraphFieldConfig> = {
displayName: 'Metric 1',
color: {
mode: FieldColorModeId.Fixed,
},
decimals: 2,
custom: {
drawStyle: GraphDrawStyle.Line,
@@ -62,6 +66,9 @@ function mockDataFrame() {
const f2Config: FieldConfig<GraphFieldConfig> = {
displayName: 'Metric 2',
color: {
mode: FieldColorModeId.Fixed,
},
decimals: 2,
custom: {
drawStyle: GraphDrawStyle.Bars,
@@ -87,6 +94,9 @@ function mockDataFrame() {
const f3Config: FieldConfig<GraphFieldConfig> = {
displayName: 'Metric 3',
decimals: 2,
color: {
mode: FieldColorModeId.Fixed,
},
custom: {
drawStyle: GraphDrawStyle.Line,
gradientMode: GraphGradientMode.Opacity,
@@ -110,6 +120,9 @@ function mockDataFrame() {
const f4Config: FieldConfig<GraphFieldConfig> = {
displayName: 'Metric 4',
decimals: 2,
color: {
mode: FieldColorModeId.Fixed,
},
custom: {
drawStyle: GraphDrawStyle.Bars,
gradientMode: GraphGradientMode.Hue,
@@ -133,6 +146,9 @@ function mockDataFrame() {
const f5Config: FieldConfig<GraphFieldConfig> = {
displayName: 'Metric 4',
decimals: 2,
color: {
mode: FieldColorModeId.Fixed,
},
custom: {
drawStyle: GraphDrawStyle.Bars,
gradientMode: GraphGradientMode.Hue,
@@ -14,6 +14,7 @@ import {
getFieldSeriesColor,
getFieldDisplayName,
getDisplayProcessor,
FieldColorModeId,
} from '@grafana/data';
import {
AxisPlacement,
@@ -54,7 +55,14 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
}) => {
const builder = new UPlotConfigBuilder(timeZone);
builder.setPrepData((frames) => preparePlotData2(frames[0], builder.getStackingGroups()));
let alignedFrame: DataFrame;
builder.setPrepData((frames) => {
// cache alignedFrame
alignedFrame = frames[0];
return preparePlotData2(frames[0], builder.getStackingGroups());
});
// X is the first field in the aligned frame
const xField = frame.fields[0];
@@ -278,6 +286,12 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
}
}
let dynamicSeriesColor: ((seriesIdx: number) => string | undefined) | undefined = undefined;
if (colorMode.id === FieldColorModeId.Thresholds) {
dynamicSeriesColor = (seriesIdx) => getFieldSeriesColor(alignedFrame.fields[seriesIdx], theme).color;
}
builder.addSeries({
pathBuilder,
pointsBuilder,
@@ -287,6 +301,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
colorMode,
fillOpacity,
theme,
dynamicSeriesColor,
drawStyle: customConfig.drawStyle!,
lineColor: customConfig.lineColor ?? seriesColor,
lineWidth: customConfig.lineWidth,
@@ -29,6 +29,7 @@ export interface SeriesProps extends LineConfig, BarConfig, FillConfig, PointsCo
scaleKey: string;
pxAlign?: boolean;
gradientMode?: GraphGradientMode;
dynamicSeriesColor?: (seriesIdx: number) => string | undefined;
facets?: uPlot.Series.Facet[];
@@ -150,7 +151,22 @@ export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
}
private getLineColor(): Series.Stroke {
const { lineColor, gradientMode, colorMode, thresholds, theme, hardMin, hardMax, softMin, softMax } = this.props;
const {
lineColor,
gradientMode,
colorMode,
thresholds,
theme,
hardMin,
hardMax,
softMin,
softMax,
dynamicSeriesColor,
} = this.props;
if (gradientMode === GraphGradientMode.None && dynamicSeriesColor) {
return (plot: uPlot, seriesIdx: number) => dynamicSeriesColor(seriesIdx) ?? lineColor ?? FALLBACK_COLOR;
}
if (gradientMode === GraphGradientMode.Scheme && colorMode?.id !== FieldColorModeId.Fixed) {
return getScaleGradientFn(1, theme, colorMode, thresholds, hardMin, hardMax, softMin, softMax);
@@ -172,6 +188,7 @@ export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
hardMax,
softMin,
softMax,
dynamicSeriesColor,
} = this.props;
if (fillColor) {
@@ -181,6 +198,14 @@ export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
const mode = gradientMode ?? GraphGradientMode.None;
const opacityPercent = (fillOpacity ?? 0) / 100;
if (mode === GraphGradientMode.None && dynamicSeriesColor && opacityPercent > 0) {
return (u: uPlot, seriesIdx: number) => {
// @ts-ignore
let lineColor = u.series[seriesIdx]._stroke; // cache
return colorManipulator.alpha(lineColor ?? '', opacityPercent);
};
}
switch (mode) {
case GraphGradientMode.Opacity:
return getOpacityGradientFn((fillColor ?? lineColor)!, opacityPercent);