diff --git a/packages/grafana-data/src/themes/colorManipulator.test.ts b/packages/grafana-data/src/themes/colorManipulator.test.ts index a4df21d4c93..b591658b092 100644 --- a/packages/grafana-data/src/themes/colorManipulator.test.ts +++ b/packages/grafana-data/src/themes/colorManipulator.test.ts @@ -260,7 +260,7 @@ describe('utils/colorManipulator', () => { describe('alpha', () => { it('converts an rgb color to an rgba color with the value provided', () => { - expect(alpha('rgb(1, 2, 3)', 0.4)).toEqual('rgba(1, 2, 3, 0.4)'); + expect(alpha('rgb(1, 2, 3)', 0.4)).toEqual('rgb(1, 2, 3, 0.4)'); }); it('updates an CSS4 color with the alpha value provided', () => { @@ -272,7 +272,7 @@ describe('utils/colorManipulator', () => { }); it('converts an hsl color to an hsla color with the value provided', () => { - expect(alpha('hsl(0, 100%, 50%)', 0.1)).toEqual('hsla(0, 100%, 50%, 0.1)'); + expect(alpha('hsl(0, 100%, 50%)', 0.1)).toEqual('hsl(0, 100%, 50%, 0.1)'); }); it('updates an hsla color with the alpha value provided', () => { diff --git a/packages/grafana-data/src/themes/colorManipulator.ts b/packages/grafana-data/src/themes/colorManipulator.ts index 6c63f57c6c0..f04b6e4faee 100644 --- a/packages/grafana-data/src/themes/colorManipulator.ts +++ b/packages/grafana-data/src/themes/colorManipulator.ts @@ -240,12 +240,29 @@ export function emphasize(color: string, coefficient = 0.15) { * @beta */ export function alpha(color: string, value: number) { - const parts = decomposeColor(color); value = clamp(value); - if (parts.type === 'rgb' || parts.type === 'hsl') { - parts.type += 'a'; + // hex 6, hex 8 (w/alpha) + if (color[0] === '#') { + if (color.length === 9) { + color = color.substring(0, 7); + } + + return color + Math.round(value * 255).toString(16); } + // rgb(, hsl( + else if (color[3] === '(') { + // rgb() and hsl() do not require the "a" suffix to accept alpha values in modern browsers: + // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb()#accepts_alpha_value + return color.replace(')', `, ${value})`); + } + // rgba(, hsla( + else if (color[4] === '(') { + return color.substring(0, color.lastIndexOf(',')) + `, ${value})`; + } + + const parts = decomposeColor(color); + if (parts.type === 'color') { parts.values[3] = `/${value}`; } else { diff --git a/public/app/plugins/panel/state-timeline/timeline.ts b/public/app/plugins/panel/state-timeline/timeline.ts index 6d596087238..df163655729 100644 --- a/public/app/plugins/panel/state-timeline/timeline.ts +++ b/public/app/plugins/panel/state-timeline/timeline.ts @@ -5,7 +5,7 @@ import { distribute, SPACE_BETWEEN } from 'app/plugins/panel/barchart/distribute import { TimelineFieldConfig, TimelineMode, TimelineValueAlignment } from './types'; import { GrafanaTheme2, TimeRange } from '@grafana/data'; import { BarValueVisibility } from '@grafana/ui'; -import tinycolor from 'tinycolor2'; +import { alpha } from '@grafana/data/src/themes/colorManipulator'; const { round, min, ceil } = Math; @@ -523,5 +523,5 @@ export function getConfig(opts: TimelineCoreOptions) { function getFillColor(fieldConfig: TimelineFieldConfig, color: string) { const opacityPercent = (fieldConfig.fillOpacity ?? 100) / 100; - return tinycolor(color).setAlpha(opacityPercent).toString(); + return alpha(color, opacityPercent); }