diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index c81a991fbe4..202a2c164c2 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -205,11 +205,17 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra }); } +// this is a significant optimization for streaming, where we currently re-process all values in the buffer on ech update +// via field.display(value). this can potentially be removed once we... +// 1. process data packets incrementally and/if cache the results in the streaming datafame (maybe by buffer index) +// 2. have the ability to selectively get display color or text (but not always both, which are each quite expensive) +// 3. sufficently optimize text formating and threshold color determinitation function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): DisplayProcessor { const cache = new Map(); return (value: any) => { let v = cache.get(value); + if (!v) { // Don't grow too big if (cache.size === maxCacheSize) { @@ -226,6 +232,7 @@ function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): D cache.set(value, v); } + return v; }; } diff --git a/packages/grafana-data/src/themes/colorManipulator.test.ts b/packages/grafana-data/src/themes/colorManipulator.test.ts index b591658b092..16a25e78a68 100644 --- a/packages/grafana-data/src/themes/colorManipulator.test.ts +++ b/packages/grafana-data/src/themes/colorManipulator.test.ts @@ -279,6 +279,10 @@ describe('utils/colorManipulator', () => { expect(alpha('hsla(0, 100%, 50%, 0.2)', 0.5)).toEqual('hsla(0, 100%, 50%, 0.5)'); }); + it('converts an rgb hex color with the alpha value provided', () => { + expect(alpha('#FFFFFF', 0)).toEqual('#FFFFFF00'); + }); + it('throw on invalid colors', () => { expect(() => { alpha('white', 0.4); diff --git a/packages/grafana-data/src/themes/colorManipulator.ts b/packages/grafana-data/src/themes/colorManipulator.ts index 2f1bc881e53..b76552ed0c1 100644 --- a/packages/grafana-data/src/themes/colorManipulator.ts +++ b/packages/grafana-data/src/themes/colorManipulator.ts @@ -263,7 +263,12 @@ export function alpha(color: string, value: number) { color = color.substring(0, 7); } - return color + Math.round(value * 255).toString(16); + return ( + color + + Math.round(value * 255) + .toString(16) + .padStart(2, '0') + ); } // rgb(, hsl( else if (color[3] === '(') { diff --git a/public/app/plugins/panel/state-timeline/timeline.ts b/public/app/plugins/panel/state-timeline/timeline.ts index 78fd73b8c1b..975d485f084 100644 --- a/public/app/plugins/panel/state-timeline/timeline.ts +++ b/public/app/plugins/panel/state-timeline/timeline.ts @@ -547,6 +547,12 @@ export function getConfig(opts: TimelineCoreOptions) { } function getFillColor(fieldConfig: TimelineFieldConfig, color: string) { + // if #rgba with pre-existing alpha. ignore fieldConfig.fillOpacity + // e.g. thresholds with opacity + if (color[0] === '#' && color.length === 9) { + return color; + } + const opacityPercent = (fieldConfig.fillOpacity ?? 100) / 100; return alpha(color, opacityPercent); }