From 6b7ef6a80bea3934cf9c5829cfc04dfe490dba87 Mon Sep 17 00:00:00 2001 From: Leon Sorokin Date: Thu, 16 Dec 2021 11:43:29 -0600 Subject: [PATCH] BarChart: fix gradient fill orientation when horizontal (#43183) --- .../uPlot/config/UPlotThresholds.ts | 3 +- .../components/uPlot/config/gradientFills.ts | 60 ++++++++++++++----- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts b/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts index e7bd4c24440..21029f98f07 100644 --- a/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts +++ b/packages/grafana-ui/src/components/uPlot/config/UPlotThresholds.ts @@ -1,6 +1,6 @@ import { GrafanaTheme2, ThresholdsConfig, ThresholdsMode } from '@grafana/data'; import { GraphThresholdsStyleConfig, GraphTresholdsStyleMode } from '@grafana/schema'; -import { getGradientRange, GradientDirection, scaleGradient } from './gradientFills'; +import { getGradientRange, scaleGradient } from './gradientFills'; import tinycolor from 'tinycolor2'; import uPlot from 'uplot'; @@ -86,7 +86,6 @@ export function getThresholdsDrawHook(options: UPlotThresholdOptions) { let grd = scaleGradient( u, u.series[1].scale!, - GradientDirection.Up, steps.map((step) => { let color = tinycolor(theme.visualization.getColorByName(step.color)); diff --git a/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts b/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts index 06a838efee9..c3daf47fb0a 100644 --- a/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts +++ b/packages/grafana-ui/src/components/uPlot/config/gradientFills.ts @@ -6,17 +6,45 @@ import { ThresholdsConfig, ThresholdsMode, } from '@grafana/data'; +import { ScaleOrientation } from '@grafana/schema'; import tinycolor from 'tinycolor2'; import uPlot from 'uplot'; import { getCanvasContext } from '../../../utils/measureText'; +function makeDirectionalGradient(direction: GradientDirection, bbox: uPlot.BBox, ctx: CanvasRenderingContext2D) { + let x0 = 0, + y0 = 0, + x1 = 0, + y1 = 0; + + if (direction === GradientDirection.Down) { + y0 = bbox.top; + y1 = bbox.top + bbox.height; + } else if (direction === GradientDirection.Left) { + x0 = bbox.left + bbox.width; + x1 = bbox.left; + } else if (direction === GradientDirection.Up) { + y0 = bbox.top + bbox.height; + y1 = bbox.top; + } else if (direction === GradientDirection.Right) { + x0 = bbox.left; + x1 = bbox.left + bbox.width; + } + + return ctx.createLinearGradient(x0, y0, x1, y1); +} + export function getOpacityGradientFn( color: string, opacity: number ): (self: uPlot, seriesIdx: number) => CanvasGradient { return (plot: uPlot, seriesIdx: number) => { const ctx = getCanvasContext(); - const gradient = ctx.createLinearGradient(0, plot.bbox.top, 0, plot.bbox.top + plot.bbox.height); + const gradient = makeDirectionalGradient( + plot.scales.x!.ori === ScaleOrientation.Horizontal ? GradientDirection.Down : GradientDirection.Left, + plot.bbox, + ctx + ); gradient.addColorStop(0, colorManipulator.alpha(color, opacity)); gradient.addColorStop(1, colorManipulator.alpha(color, 0)); @@ -24,6 +52,7 @@ export function getOpacityGradientFn( return gradient; }; } + export function getHueGradientFn( color: string, opacity: number, @@ -31,7 +60,12 @@ export function getHueGradientFn( ): (self: uPlot, seriesIdx: number) => CanvasGradient { return (plot: uPlot, seriesIdx: number) => { const ctx = getCanvasContext(); - const gradient = ctx.createLinearGradient(0, plot.bbox.top, 0, plot.bbox.top + plot.bbox.height); + const gradient = makeDirectionalGradient( + plot.scales.x!.ori === ScaleOrientation.Horizontal ? GradientDirection.Down : GradientDirection.Left, + plot.bbox, + ctx + ); + const color1 = tinycolor(color).spin(-15); const color2 = tinycolor(color).spin(15); @@ -48,21 +82,17 @@ export function getHueGradientFn( } export enum GradientDirection { - 'Right' = 0, - 'Up' = 1, + Right = 0, + Up = 1, + Left = 2, + Down = 3, } type ValueStop = [value: number, color: string]; type ScaleValueStops = ValueStop[]; -export function scaleGradient( - u: uPlot, - scaleKey: string, - dir: GradientDirection, - scaleStops: ScaleValueStops, - discrete = false -) { +export function scaleGradient(u: uPlot, scaleKey: string, scaleStops: ScaleValueStops, discrete = false) { let scale = u.scales[scaleKey]; // we want the stop below or at the scaleMax @@ -106,7 +136,7 @@ export function scaleGradient( let x0, y0, x1, y1; - if (dir === GradientDirection.Up) { + if (u.scales.x!.ori === ScaleOrientation.Horizontal) { x0 = x1 = 0; y0 = minStopPos; y1 = maxStopPos; @@ -222,7 +252,7 @@ export function getScaleGradientFn( (step) => [step.value, colorManipulator.alpha(theme.visualization.getColorByName(step.color), opacity)] as ValueStop ); - gradient = scaleGradient(plot, scaleKey, GradientDirection.Up, valueStops, true); + gradient = scaleGradient(plot, scaleKey, valueStops, true); } else { const [min, max] = getGradientRange(plot, scaleKey, hardMin, hardMax, softMin, softMax); const range = max - min; @@ -233,7 +263,7 @@ export function getScaleGradientFn( colorManipulator.alpha(theme.visualization.getColorByName(step.color), opacity), ] as ValueStop ); - gradient = scaleGradient(plot, scaleKey, GradientDirection.Up, valueStops, true); + gradient = scaleGradient(plot, scaleKey, valueStops, true); } } else if (colorMode.getColors) { const colors = colorMode.getColors(theme); @@ -246,7 +276,7 @@ export function getScaleGradientFn( colorManipulator.alpha(theme.visualization.getColorByName(color), opacity), ] as ValueStop ); - gradient = scaleGradient(plot, scaleKey, GradientDirection.Up, valueStops, false); + gradient = scaleGradient(plot, scaleKey, valueStops, false); } return gradient;