more cleanup, optimization
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useId, useMemo, memo } from 'react';
|
||||
import { useId, memo, HTMLAttributes } from 'react';
|
||||
|
||||
import { FieldDisplay } from '@grafana/data';
|
||||
|
||||
@@ -48,53 +48,36 @@ export const RadialArcPath = memo(
|
||||
const theme = useTheme2();
|
||||
const id = useId();
|
||||
|
||||
const gradientStops = useMemo(() => {
|
||||
if (gradientMode === 'none') {
|
||||
return [];
|
||||
}
|
||||
return buildGradientColors(gradientMode, theme, fieldDisplay, fieldDisplay.display.color);
|
||||
}, [gradientMode, fieldDisplay, theme]);
|
||||
const gradientStops = buildGradientColors(gradientMode, theme, fieldDisplay, fieldDisplay.display.color);
|
||||
|
||||
const { guideDotColors, endpointColors } = useMemo(() => {
|
||||
if (!showGuideDots || gradientStops.length === 0) {
|
||||
return {
|
||||
guideDotStartColor: undefined,
|
||||
guideDotEndColor: undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
guideDotColors: getGuideDotColors(gradientStops, fieldDisplay.display.percent ?? 0),
|
||||
endpointColors:
|
||||
shape === 'circle' ? getEndpointColors(gradientStops, fieldDisplay.display.percent ?? 1) : undefined,
|
||||
};
|
||||
}, [showGuideDots, fieldDisplay, gradientStops, shape]);
|
||||
let guideDotColors: [string, string] | undefined;
|
||||
let endpointColors: [string, string] | undefined;
|
||||
|
||||
const bgDivStyle = useMemo(() => {
|
||||
const baseStyles = { width: '100%', height: '100%' };
|
||||
if (color) {
|
||||
return { backgroundColor: color, ...baseStyles };
|
||||
if (showGuideDots && gradientStops.length > 0) {
|
||||
guideDotColors = getGuideDotColors(gradientStops, fieldDisplay.display.percent);
|
||||
if (shape === 'circle') {
|
||||
endpointColors = getEndpointColors(gradientStops, fieldDisplay.display.percent);
|
||||
}
|
||||
const gradientCss = getGradientCss(gradientStops, shape);
|
||||
return { backgroundImage: gradientCss, ...baseStyles };
|
||||
}, [color, gradientStops, shape]);
|
||||
}
|
||||
|
||||
const bgDivStyle: HTMLAttributes<HTMLDivElement>['style'] = { width: '100%', height: '100%' };
|
||||
if (color) {
|
||||
bgDivStyle.backgroundColor = color;
|
||||
} else {
|
||||
bgDivStyle.backgroundImage = getGradientCss(gradientStops, shape);
|
||||
}
|
||||
|
||||
const { radius, centerX, centerY, barWidth } = dimensions;
|
||||
|
||||
const path = useMemo(
|
||||
() => drawRadialArcPath(angle, arcLengthDeg, dimensions, roundedBars),
|
||||
[angle, arcLengthDeg, dimensions, roundedBars]
|
||||
);
|
||||
const path = drawRadialArcPath(angle, arcLengthDeg, dimensions, roundedBars);
|
||||
|
||||
const { x1, x2, y1, y2 } = useMemo(() => {
|
||||
const startRadians = toRad(angle);
|
||||
const endRadians = toRad(angle + arcLengthDeg);
|
||||
const startRadians = toRad(angle);
|
||||
const endRadians = toRad(angle + arcLengthDeg);
|
||||
|
||||
let x1 = centerX + radius * Math.cos(startRadians);
|
||||
let y1 = centerY + radius * Math.sin(startRadians);
|
||||
let x2 = centerX + radius * Math.cos(endRadians);
|
||||
let y2 = centerY + radius * Math.sin(endRadians);
|
||||
return { x1, y1, x2, y2 };
|
||||
}, [angle, arcLengthDeg, centerX, centerY, radius]);
|
||||
const x1 = centerX + radius * Math.cos(startRadians);
|
||||
const y1 = centerY + radius * Math.sin(startRadians);
|
||||
const x2 = centerX + radius * Math.cos(endRadians);
|
||||
const y2 = centerY + radius * Math.sin(endRadians);
|
||||
|
||||
const dotRadius = Math.min((barWidth / 2) * DOT_RADIUS_FACTOR, MAX_DOT_RADIUS);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ export const RadialBarSegmented = memo(
|
||||
const value = fieldDisplay.display.numeric;
|
||||
const angleBetweenSegments = getAngleBetweenSegments(segmentSpacing, segmentCount, angleRange);
|
||||
const segmentArcLengthDeg = angleRange / segmentCountAdjusted - angleBetweenSegments;
|
||||
const displayProcessor = getFieldDisplayProcessor(fieldDisplay);
|
||||
|
||||
for (let i = 0; i < segmentCountAdjusted; i++) {
|
||||
const angleValue = min + ((max - min) / segmentCountAdjusted) * i;
|
||||
@@ -53,7 +54,7 @@ export const RadialBarSegmented = memo(
|
||||
if (angleValue >= value) {
|
||||
segmentColor = theme.colors.action.hover;
|
||||
} else if (gradientMode === 'none') {
|
||||
segmentColor = getFieldDisplayProcessor(fieldDisplay)(angleValue).color ?? FALLBACK_COLOR;
|
||||
segmentColor = displayProcessor(angleValue).color ?? FALLBACK_COLOR;
|
||||
}
|
||||
|
||||
segments.push(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
import { FieldDisplay, GrafanaTheme2, FieldConfig } from '@grafana/data';
|
||||
import { GraphFieldConfig, GraphGradientMode, LineInterpolation } from '@grafana/schema';
|
||||
|
||||
@@ -22,36 +24,43 @@ const SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE = 4;
|
||||
const SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE_NAME_AND_VALUE = 3.3;
|
||||
const SPARKLINE_SPACING = 8;
|
||||
|
||||
export function RadialSparkline({ sparkline, dimensions, theme, color, shape, textMode }: RadialSparklineProps) {
|
||||
const { radius, barWidth } = dimensions;
|
||||
export const RadialSparkline = memo(
|
||||
({ sparkline, dimensions, theme, color, shape, textMode }: RadialSparklineProps) => {
|
||||
const { radius, barWidth } = dimensions;
|
||||
|
||||
if (!sparkline) {
|
||||
return null;
|
||||
const showNameAndValue = textMode === 'value_and_name';
|
||||
const height = radius / (showNameAndValue ? SPARKLINE_HEIGHT_DIVISOR_NAME_AND_VALUE : SPARKLINE_HEIGHT_DIVISOR);
|
||||
const width = radius * (shape === 'gauge' ? SPARKLINE_WIDTH_FACTOR_ARC : SPARKLINE_WIDTH_FACTOR_CIRCLE) - barWidth;
|
||||
const topPos =
|
||||
shape === 'gauge'
|
||||
? dimensions.gaugeBottomY - height - SPARKLINE_SPACING
|
||||
: `calc(50% + ${radius / (showNameAndValue ? SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE_NAME_AND_VALUE : SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE)}px)`;
|
||||
|
||||
const config: FieldConfig<GraphFieldConfig> = useMemo(
|
||||
() => ({
|
||||
color: {
|
||||
mode: 'fixed',
|
||||
fixedColor: color ?? 'blue',
|
||||
},
|
||||
custom: {
|
||||
gradientMode: GraphGradientMode.Opacity,
|
||||
fillOpacity: 40,
|
||||
lineInterpolation: LineInterpolation.Smooth,
|
||||
},
|
||||
}),
|
||||
[color]
|
||||
);
|
||||
|
||||
if (!sparkline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ position: 'absolute', top: topPos }}>
|
||||
<Sparkline height={height} width={width} sparkline={sparkline} theme={theme} config={config} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const showNameAndValue = textMode === 'value_and_name';
|
||||
const height = radius / (showNameAndValue ? SPARKLINE_HEIGHT_DIVISOR_NAME_AND_VALUE : SPARKLINE_HEIGHT_DIVISOR);
|
||||
const width = radius * (shape === 'gauge' ? SPARKLINE_WIDTH_FACTOR_ARC : SPARKLINE_WIDTH_FACTOR_CIRCLE) - barWidth;
|
||||
const topPos =
|
||||
shape === 'gauge'
|
||||
? dimensions.gaugeBottomY - height - SPARKLINE_SPACING
|
||||
: `calc(50% + ${radius / (showNameAndValue ? SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE_NAME_AND_VALUE : SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE)}px)`;
|
||||
|
||||
const config: FieldConfig<GraphFieldConfig> = {
|
||||
color: {
|
||||
mode: 'fixed',
|
||||
fixedColor: color ?? 'blue',
|
||||
},
|
||||
custom: {
|
||||
gradientMode: GraphGradientMode.Opacity,
|
||||
fillOpacity: 40,
|
||||
lineInterpolation: LineInterpolation.Smooth,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ position: 'absolute', top: topPos }}>
|
||||
<Sparkline height={height} width={width} sparkline={sparkline} theme={theme} config={config} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
RadialSparkline.displayName = 'RadialSparkline';
|
||||
|
||||
@@ -172,7 +172,7 @@ const getGuideDotColor = (color: string): string => {
|
||||
return colorManipulator.getContrastRatio(darkColor, color) >= CONTRAST_THRESHOLD_MAX ? darkColor : lightColor;
|
||||
};
|
||||
|
||||
export function getGuideDotColors(gradientStops: GradientStop[], percent: number): [string, string] {
|
||||
export function getGuideDotColors(gradientStops: GradientStop[], percent = 1): [string, string] {
|
||||
const [startColor, endColor] = getEndpointColors(gradientStops, percent);
|
||||
return [getGuideDotColor(startColor), getGuideDotColor(endColor)];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user