diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx
index b1a068c93a6..abf142bc46c 100644
--- a/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx
@@ -1,15 +1,15 @@
import { useId } from 'react';
-import { colorManipulator } from '@grafana/data';
-
import { RadialColorDefs } from './RadialColorDefs';
+import { RadialShape } from './RadialGauge';
import { GaugeDimensions, toRad } from './utils';
export interface RadialArcPathPropsBase {
startAngle: number;
dimensions: GaugeDimensions;
- colorDef: RadialColorDefs;
+ colorDefs: RadialColorDefs;
arcLengthDeg: number;
+ shape: RadialShape;
color?: string;
gradient?: string;
glowFilter?: string;
@@ -116,9 +116,10 @@ export function RadialArcPath({
startAngle: angle,
dimensions,
color,
- colorDef,
- gradient,
+ colorDefs,
+ shape,
arcLengthDeg,
+ glowFilter,
roundedBars,
showGuideDots,
guideDotStartColor,
@@ -129,7 +130,7 @@ export function RadialArcPath({
const startRadians = toRad(angle);
const endRadians = toRad(angle + arcLengthDeg);
- const gradientList = colorDef?.getGradient();
+ const [startColor, endColor] = colorDefs.getEndpointColors();
const path = drawRadialArcPath({ angle, arcLengthDeg, dimensions, roundedBars });
let x1 = centerX + radius * Math.cos(startRadians);
@@ -144,19 +145,34 @@ export function RadialArcPath({
-
-
-
+
+
+
+
+
- {roundedBars && gradientList && (
- <>
-
- {/* this would actually need to be the color determined by the display */}
-
- >
- )}
{showGuideDots && (
<>
+ {shape === 'circle' && (
+ <>
+
+
+ >
+ )}
+
{arcLengthDeg > 5 && }
>
diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx
index bb0dac60d45..729f60ed630 100644
--- a/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx
@@ -2,6 +2,7 @@ import { useTheme2 } from '../../themes/ThemeContext';
import { RadialArcPath } from './RadialArcPath';
import { RadialColorDefs } from './RadialColorDefs';
+import { RadialShape } from './RadialGauge';
import { GaugeDimensions } from './utils';
export interface RadialBarProps {
@@ -12,6 +13,7 @@ export interface RadialBarProps {
startAngle: number;
roundedBars?: boolean;
glowFilter?: string;
+ shape: RadialShape;
}
export function RadialBar({
dimensions,
@@ -21,6 +23,7 @@ export function RadialBar({
startAngle,
roundedBars,
glowFilter,
+ shape,
}: RadialBarProps) {
const theme = useTheme2();
const [startDotColor, endDotColor] = colorDefs.getGuideDotColors();
@@ -33,20 +36,24 @@ export function RadialBar({
startAngle={startAngle + angle}
dimensions={dimensions}
arcLengthDeg={angleRange - angle}
+ colorDefs={colorDefs}
color={theme.colors.action.hover}
roundedBars={roundedBars}
+ shape={shape}
/>
{/** The colored bar */}
{colorDefs.getDefs()}
diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx
index dd2ec0ac9bf..dbd668f3a00 100644
--- a/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx
@@ -4,6 +4,7 @@ import { useTheme2 } from '../../themes/ThemeContext';
import { RadialArcPath } from './RadialArcPath';
import { RadialColorDefs } from './RadialColorDefs';
+import { RadialShape } from './RadialGauge';
import { GaugeDimensions } from './utils';
export interface RadialBarSegmentedProps {
@@ -15,6 +16,7 @@ export interface RadialBarSegmentedProps {
glowFilter?: string;
segmentCount: number;
segmentSpacing: number;
+ shape: RadialShape;
}
export function RadialBarSegmented({
fieldDisplay,
@@ -25,6 +27,7 @@ export function RadialBarSegmented({
segmentCount,
segmentSpacing,
colorDefs,
+ shape,
}: RadialBarSegmentedProps) {
const segments: React.ReactNode[] = [];
const theme = useTheme2();
@@ -38,9 +41,9 @@ export function RadialBarSegmented({
for (let i = 0; i < segmentCountAdjusted; i++) {
const angleValue = min + ((max - min) / segmentCountAdjusted) * i;
- const angleColor = colorDefs.getSegmentColor(angleValue, i);
+ // const angleColor = colorDefs.getSegmentColor(angleValue, i);
const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01;
- const segmentColor = angleValue >= value ? theme.colors.action.hover : angleColor;
+ const segmentColor = angleValue >= value ? theme.colors.action.hover : undefined;
segments.push(
diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx
index 97b24b99054..87a6a0d4ba8 100644
--- a/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx
@@ -122,35 +122,24 @@ export class RadialColorDefs {
}
getGradient(baseColor = this.getFieldBaseColor(), forSegment?: boolean): Array<{ color: string; percent: number }> {
- const { gradient, fieldDisplay, theme } = this.options;
- return buildGradientColors(gradient, baseColor, theme, fieldDisplay.field.color?.mode, forSegment);
+ const { displayProcessor, gradient, fieldDisplay, theme } = this.options;
+ return buildGradientColors(gradient, baseColor, theme, displayProcessor, fieldDisplay, forSegment);
}
getGradientDef(): string {
const gradientStops = this.getGradient();
const colorStrings = gradientStops.map((stop) => `${stop.color} ${(stop.percent * 100).toFixed(2)}%`);
return this.options.shape === 'circle'
- ? `conic-gradient(from -10deg, ${colorStrings.join(', ')})`
+ ? `conic-gradient(from 0deg, ${colorStrings.join(', ')})`
: 'linear-gradient(90deg, ' + colorStrings.join(', ') + ')';
}
- getGuideDotColors(): [string, string] {
- const { dimensions, fieldDisplay, shape } = this.options;
+ getEndpointColors(): [string, string] {
+ const { fieldDisplay } = this.options;
const gradient = this.getGradient();
- let valuePercent = fieldDisplay.display.percent ?? 0;
-
- // the linear gradient used in circular gradients means that we want to use the
- // y position of the edge of the bar to determine the color. If we ever address
- // that shortcoming, we could delete this block.
- if (shape === 'circle') {
- const angleDeg = ((valuePercent - 0.25) % 1) * 360;
- const angleRad = (angleDeg * Math.PI) / 180;
- const yPos = dimensions.centerY + dimensions.radius * Math.sin(angleRad);
- valuePercent = yPos / (dimensions.centerY * 2);
- }
-
- let startColor = gradient[0].color;
+ const valuePercent = fieldDisplay.display.percent ?? 0;
+ const startColor = gradient[0].color;
let endColor = gradient[gradient.length - 1].color;
// if we have a percentageFilled, use it to get a the correct end color based on where the bar terminates
@@ -161,7 +150,11 @@ export class RadialColorDefs {
? endColorByPercentage.toHexString()
: endColorByPercentage.toHex8String();
}
+ return [startColor, endColor];
+ }
+ getGuideDotColors(): [string, string] {
+ const [startColor, endColor] = this.getEndpointColors();
return [getGuideDotColor(startColor), getGuideDotColor(endColor)];
}
diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx
index d20665872c7..fc03f9845e3 100644
--- a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx
@@ -155,6 +155,7 @@ export function RadialGauge(props: RadialGaugeProps) {
segmentCount={segmentCount}
segmentSpacing={segmentSpacing}
colorDefs={colorDefs}
+ shape={shape}
/>
);
} else {
@@ -168,6 +169,7 @@ export function RadialGauge(props: RadialGaugeProps) {
startAngle={startAngle}
roundedBars={roundedBars}
glowFilter={`url(#${glowFilterId})`}
+ shape={shape}
/>
);
}
@@ -228,6 +230,7 @@ export function RadialGauge(props: RadialGaugeProps) {
roundedBars={roundedBars}
glowFilter={`url(#${glowFilterId})`}
colorDefs={colorDefs}
+ shape={shape}
/>
);
}
diff --git a/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx b/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx
index 8977bbb6642..15e5349e8a5 100644
--- a/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx
+++ b/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx
@@ -2,6 +2,7 @@ import { FieldDisplay, Threshold } from '@grafana/data';
import { RadialArcPath } from './RadialArcPath';
import { RadialColorDefs } from './RadialColorDefs';
+import { RadialShape } from './RadialGauge';
import { GaugeDimensions } from './utils';
export interface Props {
@@ -9,6 +10,7 @@ export interface Props {
angleRange: number;
startAngle: number;
endAngle: number;
+ shape: RadialShape;
fieldDisplay: FieldDisplay;
roundedBars?: boolean;
glowFilter?: string;
@@ -24,6 +26,7 @@ export function ThresholdsBar({
glowFilter,
colorDefs,
thresholds,
+ shape,
}: Props) {
const fieldConfig = fieldDisplay.field;
const min = fieldConfig.min ?? 0;
@@ -55,10 +58,11 @@ export function ThresholdsBar({
key={i}
startAngle={currentStart}
arcLengthDeg={lengthDeg}
+ colorDefs={colorDefs}
+ shape={shape}
dimensions={thresholdDimensions}
roundedBars={roundedBars}
glowFilter={glowFilter}
- color={colorDefs.getColor(threshold.color, i)}
/>
);
diff --git a/packages/grafana-ui/src/components/RadialGauge/colors.ts b/packages/grafana-ui/src/components/RadialGauge/colors.ts
index 62a31470ed3..99e23452898 100644
--- a/packages/grafana-ui/src/components/RadialGauge/colors.ts
+++ b/packages/grafana-ui/src/components/RadialGauge/colors.ts
@@ -1,6 +1,7 @@
import tinycolor from 'tinycolor2';
-import { FieldColorModeId, getFieldColorMode, GrafanaTheme2 } from '@grafana/data';
+import { DisplayProcessor, FieldDisplay, getFieldColorMode, GrafanaTheme2 } from '@grafana/data';
+import { FieldColorModeId } from '@grafana/schema';
import { RadialGradientMode } from './RadialGauge';
@@ -8,7 +9,8 @@ export function buildGradientColors(
gradientMode: RadialGradientMode,
baseColor: string,
theme: GrafanaTheme2,
- colorModeId?: FieldColorModeId | string,
+ displayProcessor: DisplayProcessor,
+ fieldDisplay: FieldDisplay,
forSegment?: boolean
): Array<{ color: string; percent: number }> {
if (gradientMode === 'none') {
@@ -18,15 +20,36 @@ export function buildGradientColors(
];
}
- const colorMode = getFieldColorMode(colorModeId);
+ const colorMode = getFieldColorMode(fieldDisplay.field.color?.mode);
+
+ if (colorMode.id === FieldColorModeId.Thresholds) {
+ const thresholds = fieldDisplay.field.thresholds?.steps ?? [];
+ const min = fieldDisplay.field.min ?? 0;
+ const max = fieldDisplay.field.max ?? 100;
+
+ const result: Array<{ color: string; percent: number }> = [
+ { color: displayProcessor(min).color ?? baseColor, percent: 0 },
+ ];
+
+ for (const threshold of thresholds) {
+ if (threshold.value > min && threshold.value < max) {
+ const percent = (threshold.value - min) / (max - min);
+ result.push({ color: threshold.color, percent });
+ }
+ }
+
+ result.push({ color: displayProcessor(max).color ?? baseColor, percent: 1 });
+
+ return result;
+ }
- // TODO we need to return thresholded values here. those will have breakpoints
- // which map to exact percentages, and we should show that correctly.
- // Handle continuous color modes first
if (colorMode.isContinuous && colorMode.getColors && !forSegment) {
+ // Handle continuous color modes first
const colors = colorMode.getColors(theme);
return colors.map((color, idx) => ({ color, percent: idx / (colors.length - 1) }));
- } else if (colorMode.isByValue) {
+ }
+
+ if (colorMode.isByValue) {
// For value based colors we want to stay more true to the specific color
// So a radial gradient that adds a bit of light and shade works best
const darkerColor = tinycolor(baseColor).darken(5);