mirror of https://github.com/grafana/grafana.git
Refactorings
CodeQL checks / Detect whether code changed (push) Waiting to run
Details
CodeQL checks / Analyze (actions) (push) Blocked by required conditions
Details
CodeQL checks / Analyze (go) (push) Blocked by required conditions
Details
CodeQL checks / Analyze (javascript) (push) Blocked by required conditions
Details
CodeQL checks / Detect whether code changed (push) Waiting to run
Details
CodeQL checks / Analyze (actions) (push) Blocked by required conditions
Details
CodeQL checks / Analyze (go) (push) Blocked by required conditions
Details
CodeQL checks / Analyze (javascript) (push) Blocked by required conditions
Details
This commit is contained in:
parent
b2447fa3d9
commit
73e3122621
|
@ -7,15 +7,14 @@ import { GaugeDimensions } from './utils';
|
|||
|
||||
interface GradientDefProps {
|
||||
fieldDisplay: FieldDisplay;
|
||||
index: number;
|
||||
id: string;
|
||||
theme: GrafanaTheme2;
|
||||
gaugeId: string;
|
||||
gradient: RadialGradientMode;
|
||||
dimensions: GaugeDimensions;
|
||||
shape: RadialShape;
|
||||
}
|
||||
|
||||
export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dimensions, shape }: GradientDefProps) {
|
||||
export function GradientDef({ fieldDisplay, id, theme, gradient, dimensions, shape }: GradientDefProps) {
|
||||
const colorModeId = fieldDisplay.field.color?.mode;
|
||||
const valuePercent = fieldDisplay.display.percent ?? 0;
|
||||
const colorMode = getFieldColorMode(colorModeId);
|
||||
|
@ -39,7 +38,7 @@ export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dim
|
|||
y1="0"
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
id={getGradientId(gaugeId, index)}
|
||||
id={id}
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform={transform}
|
||||
>
|
||||
|
@ -59,7 +58,7 @@ export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dim
|
|||
y1="0"
|
||||
x2={x2}
|
||||
y2={y2}
|
||||
id={getGradientId(gaugeId, index)}
|
||||
id={id}
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform={transform}
|
||||
>
|
||||
|
@ -83,7 +82,7 @@ export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dim
|
|||
const count = colors.length;
|
||||
|
||||
return (
|
||||
<linearGradient x1="0" y1="1" x2={1 / valuePercent} y2="1" id={getGradientId(gaugeId, index)}>
|
||||
<linearGradient x1="0" y1="1" x2={1 / valuePercent} y2="1" id={id}>
|
||||
{colors.map((stopColor, i) => (
|
||||
<stop key={i} offset={`${(i / (count - 1)).toFixed(2)}`} stopColor={stopColor} stopOpacity={1} />
|
||||
))}
|
||||
|
@ -91,7 +90,7 @@ export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dim
|
|||
);
|
||||
} else {
|
||||
return (
|
||||
<linearGradient x1="0" y1="1" x2={0} y2="1" id={getGradientId(gaugeId, index)}>
|
||||
<linearGradient x1="0" y1="1" x2={0} y2="1" id={id}>
|
||||
<stop stopColor={fieldDisplay.display.color ?? 'gray'} stopOpacity={1} />
|
||||
</linearGradient>
|
||||
);
|
||||
|
@ -117,7 +116,3 @@ export function GradientDef({ fieldDisplay, index, theme, gaugeId, gradient, dim
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getGradientId(gaugeId: string, index: number) {
|
||||
return `radial-gauge-${gaugeId}-${index}`;
|
||||
}
|
||||
|
|
|
@ -1,42 +1,38 @@
|
|||
import { FieldDisplay, GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { GaugeDimensions, getValueAngleForValue } from './utils';
|
||||
import { GaugeDimensions } from './utils';
|
||||
|
||||
export interface RadialBarProps {
|
||||
gaugeId: string;
|
||||
dimensions: GaugeDimensions;
|
||||
fieldDisplay: FieldDisplay;
|
||||
angleRange: number;
|
||||
angle: number;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
color: string;
|
||||
roundedBars?: boolean;
|
||||
spotlight?: boolean;
|
||||
glow?: boolean;
|
||||
spotlightStroke: string;
|
||||
glowFilter?: string;
|
||||
}
|
||||
export function RadialBar({
|
||||
dimensions,
|
||||
fieldDisplay,
|
||||
gaugeId,
|
||||
angleRange,
|
||||
angle,
|
||||
startAngle,
|
||||
endAngle,
|
||||
color,
|
||||
roundedBars,
|
||||
spotlight,
|
||||
glow,
|
||||
spotlightStroke,
|
||||
glowFilter,
|
||||
}: RadialBarProps) {
|
||||
const theme = useTheme2();
|
||||
const { range, angle } = getValueAngleForValue(fieldDisplay, startAngle, endAngle);
|
||||
|
||||
const trackStart = startAngle + angle;
|
||||
const trackLength = range - angle;
|
||||
const trackLength = angleRange - angle;
|
||||
|
||||
return (
|
||||
<>
|
||||
<g>
|
||||
{/** Track */}
|
||||
<RadialArcPath
|
||||
gaugeId={gaugeId}
|
||||
angle={trackLength}
|
||||
dimensions={dimensions}
|
||||
startAngle={trackStart}
|
||||
|
@ -46,41 +42,38 @@ export function RadialBar({
|
|||
/>
|
||||
{/** The colored bar */}
|
||||
<RadialArcPath
|
||||
gaugeId={gaugeId}
|
||||
angle={angle}
|
||||
dimensions={dimensions}
|
||||
startAngle={startAngle}
|
||||
color={color}
|
||||
roundedBars={roundedBars}
|
||||
spotlight={spotlight}
|
||||
glow={glow}
|
||||
spotlightStroke={spotlightStroke}
|
||||
glowFilter={glowFilter}
|
||||
theme={theme}
|
||||
/>
|
||||
</>
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
export interface RadialArcPathProps {
|
||||
gaugeId: string;
|
||||
angle: number;
|
||||
startAngle: number;
|
||||
dimensions: GaugeDimensions;
|
||||
color: string;
|
||||
roundedBars?: boolean;
|
||||
spotlight?: boolean;
|
||||
glow?: boolean;
|
||||
spotlightStroke?: string;
|
||||
glowFilter?: string;
|
||||
theme: GrafanaTheme2;
|
||||
}
|
||||
|
||||
export function RadialArcPath({
|
||||
gaugeId,
|
||||
startAngle,
|
||||
dimensions,
|
||||
angle,
|
||||
color,
|
||||
roundedBars,
|
||||
spotlight,
|
||||
glow,
|
||||
spotlightStroke,
|
||||
glowFilter,
|
||||
theme,
|
||||
}: RadialArcPathProps) {
|
||||
let { radius, centerX, centerY, barWidth } = dimensions;
|
||||
|
@ -114,17 +107,17 @@ export function RadialArcPath({
|
|||
strokeLinecap={roundedBars ? 'round' : 'butt'}
|
||||
strokeWidth={barWidth}
|
||||
strokeDasharray="0"
|
||||
filter={glow ? `url(#glow-${gaugeId})` : undefined}
|
||||
filter={glowFilter}
|
||||
/>
|
||||
{spotlight && angle > 8 && (
|
||||
{spotlightStroke && angle > 8 && (
|
||||
<SpotlightSquareEffect
|
||||
radius={radius}
|
||||
centerX={centerX}
|
||||
centerY={centerY}
|
||||
angleRadian={endRadians}
|
||||
barWidth={barWidth}
|
||||
glow={glow}
|
||||
gaugeId={gaugeId}
|
||||
glowFilter={glowFilter}
|
||||
spotlightStroke={spotlightStroke}
|
||||
theme={theme}
|
||||
roundedBars={roundedBars}
|
||||
/>
|
||||
|
@ -139,8 +132,8 @@ interface SpotlightEffectProps {
|
|||
centerY: number;
|
||||
angleRadian: number;
|
||||
barWidth: number;
|
||||
glow?: boolean;
|
||||
gaugeId: string;
|
||||
glowFilter?: string;
|
||||
spotlightStroke: string;
|
||||
theme: GrafanaTheme2;
|
||||
roundedBars?: boolean;
|
||||
}
|
||||
|
@ -151,8 +144,8 @@ function SpotlightSquareEffect({
|
|||
centerY,
|
||||
angleRadian,
|
||||
barWidth,
|
||||
glow,
|
||||
gaugeId,
|
||||
glowFilter,
|
||||
spotlightStroke,
|
||||
roundedBars,
|
||||
}: SpotlightEffectProps) {
|
||||
let x1 = centerX + radius * Math.cos(angleRadian - 0.2);
|
||||
|
@ -167,9 +160,9 @@ function SpotlightSquareEffect({
|
|||
d={path}
|
||||
fill="none"
|
||||
strokeWidth={barWidth}
|
||||
stroke={`url(#spotlight-${gaugeId})`}
|
||||
stroke={spotlightStroke}
|
||||
strokeLinecap={roundedBars ? 'round' : 'butt'}
|
||||
filter={glow ? `url(#glow-${gaugeId})` : undefined}
|
||||
filter={glowFilter}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,30 +3,27 @@ import { DisplayProcessor, FieldDisplay } from '@grafana/data';
|
|||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { RadialGradientMode } from './RadialGauge';
|
||||
import { GaugeDimensions, getValueAngleForValue } from './utils';
|
||||
import { GaugeDimensions } from './utils';
|
||||
|
||||
export interface RadialBarSegmentedProps {
|
||||
gaugeId: string;
|
||||
fieldDisplay: FieldDisplay;
|
||||
dimensions: GaugeDimensions;
|
||||
angleRange: number;
|
||||
startAngle: number;
|
||||
endAngle: number;
|
||||
color: string;
|
||||
spotlight?: boolean;
|
||||
glow?: boolean;
|
||||
glowFilter?: string;
|
||||
segmentCount: number;
|
||||
segmentSpacing: number;
|
||||
displayProcessor: DisplayProcessor;
|
||||
gradient: RadialGradientMode;
|
||||
}
|
||||
export function RadialBarSegmented({
|
||||
gaugeId,
|
||||
fieldDisplay,
|
||||
dimensions,
|
||||
startAngle,
|
||||
endAngle,
|
||||
angleRange,
|
||||
color,
|
||||
glow,
|
||||
glowFilter,
|
||||
segmentCount,
|
||||
segmentSpacing,
|
||||
displayProcessor,
|
||||
|
@ -35,8 +32,7 @@ export function RadialBarSegmented({
|
|||
const segments: React.ReactNode[] = [];
|
||||
const theme = useTheme2();
|
||||
|
||||
const { range } = getValueAngleForValue(fieldDisplay, startAngle, endAngle);
|
||||
const segmentCountAdjusted = getOptimalSegmentCount(dimensions, segmentSpacing, segmentCount, range);
|
||||
const segmentCountAdjusted = getOptimalSegmentCount(dimensions, segmentSpacing, segmentCount, angleRange);
|
||||
|
||||
const min = fieldDisplay.field.min ?? 0;
|
||||
const max = fieldDisplay.field.max ?? 100;
|
||||
|
@ -54,41 +50,38 @@ export function RadialBarSegmented({
|
|||
for (let i = 0; i < segmentCountAdjusted; i++) {
|
||||
const angleValue = ((max - min) / segmentCountAdjusted) * i;
|
||||
const angleColor = getColorForValue(angleValue);
|
||||
const segmentAngle = startAngle + (range / segmentCountAdjusted) * i + 0.01;
|
||||
const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01;
|
||||
const segmentColor = angleValue > value ? theme.colors.action.hover : angleColor;
|
||||
|
||||
segments.push(
|
||||
<RadialSegmentArcPath
|
||||
gaugeId={gaugeId}
|
||||
angle={segmentAngle}
|
||||
dimensions={dimensions}
|
||||
color={segmentColor}
|
||||
glow={glow}
|
||||
glowFilter={glowFilter}
|
||||
segmentSpacing={segmentSpacing}
|
||||
arcLengthDeg={range / segmentCountAdjusted}
|
||||
arcLengthDeg={angleRange / segmentCountAdjusted}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return segments;
|
||||
return <g>{segments}</g>;
|
||||
}
|
||||
|
||||
export interface RadialSegmentProps {
|
||||
gaugeId: string;
|
||||
angle: number;
|
||||
dimensions: GaugeDimensions;
|
||||
color: string;
|
||||
glow?: boolean;
|
||||
glowFilter?: string;
|
||||
segmentSpacing: number;
|
||||
arcLengthDeg: number;
|
||||
}
|
||||
|
||||
export function RadialSegmentArcPath({
|
||||
gaugeId,
|
||||
angle,
|
||||
dimensions,
|
||||
color,
|
||||
glow,
|
||||
glowFilter,
|
||||
segmentSpacing,
|
||||
arcLengthDeg,
|
||||
}: RadialSegmentProps) {
|
||||
|
@ -121,7 +114,7 @@ export function RadialSegmentArcPath({
|
|||
strokeLinecap={'butt'}
|
||||
strokeWidth={barWidth}
|
||||
strokeDasharray="0"
|
||||
filter={glow ? `url(#glow-${gaugeId})` : undefined}
|
||||
filter={glowFilter}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -325,6 +325,10 @@ function RadialBarExample({
|
|||
}: ExampleProps) {
|
||||
const theme = useTheme2();
|
||||
|
||||
if (gradient === 'scheme' && colorMode === FieldColorModeId.Fixed) {
|
||||
colorMode = FieldColorModeId.ContinuousGrYlRd;
|
||||
}
|
||||
|
||||
const frame = toDataFrame({
|
||||
name: 'TestData',
|
||||
length: 18,
|
||||
|
@ -400,7 +404,7 @@ function getExtraSeries(seriesCount: number, colorMode: FieldColorModeId, theme:
|
|||
const fields: Field[] = [];
|
||||
const colors = ['blue', 'green', 'purple', 'orange', 'yellow'];
|
||||
|
||||
for (let i = 0; i < seriesCount; i++) {
|
||||
for (let i = 1; i < seriesCount; i++) {
|
||||
fields.push({
|
||||
name: `Series ${i + 1}`,
|
||||
type: FieldType.number,
|
||||
|
|
|
@ -2,17 +2,17 @@ import { css } from '@emotion/css';
|
|||
import { isNumber } from 'lodash';
|
||||
import { useId } from 'react';
|
||||
|
||||
import { DisplayValue, FieldDisplay, getDisplayProcessor, GrafanaTheme2 } from '@grafana/data';
|
||||
import { FieldDisplay, getDisplayProcessor, GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { GradientDef, getGradientId } from './GradientDef';
|
||||
import { GradientDef } from './GradientDef';
|
||||
import { RadialBar } from './RadialBar';
|
||||
import { RadialBarSegmented } from './RadialBarSegmented';
|
||||
import { RadialSparkline } from './RadialSparkline';
|
||||
import { RadialText } from './RadialText';
|
||||
import { CenterGlowGradient, GlowGradient, SpotlightGradient } from './effects';
|
||||
import { calculateDimensions, GaugeDimensions, getValueAngleForValue } from './utils';
|
||||
import { GlowGradient, MiddleCircleGlow, SpotlightGradient } from './effects';
|
||||
import { calculateDimensions, getValueAngleForValue } from './utils';
|
||||
|
||||
export interface RadialGaugeProps {
|
||||
values: FieldDisplay[];
|
||||
|
@ -81,136 +81,130 @@ export function RadialGauge(props: RadialGaugeProps) {
|
|||
const startAngle = shape === 'gauge' ? 250 : 0;
|
||||
const endAngle = shape === 'gauge' ? 110 : 360;
|
||||
|
||||
const dimensions = calculateDimensions(width, height, endAngle, glowBar, spotlight, roundedBars, barWidthFactor);
|
||||
console.log('dimensions', dimensions);
|
||||
const defs: React.ReactNode[] = [];
|
||||
const graphics: React.ReactNode[] = [];
|
||||
let sparklineElement: React.ReactNode | null = null;
|
||||
|
||||
const primaryValue = values[0];
|
||||
const color = primaryValue.display.color ?? theme.colors.primary.main;
|
||||
for (let barIndex = 0; barIndex < values.length; barIndex++) {
|
||||
const displayValue = values[barIndex];
|
||||
const { angle, angleRange } = getValueAngleForValue(displayValue, startAngle, endAngle);
|
||||
const color = displayValue.display.color ?? 'gray';
|
||||
const dimensions = calculateDimensions(width, height, endAngle, glowBar, roundedBars, barWidthFactor, barIndex);
|
||||
|
||||
const { angle } = getValueAngleForValue(primaryValue, startAngle, endAngle);
|
||||
let displayProcessor = getDisplayProcessor();
|
||||
|
||||
if (displayValue.view && isNumber(displayValue.colIndex)) {
|
||||
displayProcessor = displayValue.view.getFieldDisplayProcessor(displayValue.colIndex) ?? displayProcessor;
|
||||
}
|
||||
|
||||
const spotlightGradientId = `spotlight-${barIndex}-${gaugeId}`;
|
||||
const glowFilterId = `glow-${gaugeId}`;
|
||||
const colorGradientId = `bar-color-${barIndex}-${gaugeId}`;
|
||||
const barColor = gradient !== 'none' ? `url(#${colorGradientId})` : color;
|
||||
|
||||
defs.push(
|
||||
<GradientDef
|
||||
key={`gradient-${barIndex}`}
|
||||
fieldDisplay={displayValue}
|
||||
id={colorGradientId}
|
||||
theme={theme}
|
||||
gradient={gradient}
|
||||
dimensions={dimensions}
|
||||
shape={shape}
|
||||
/>
|
||||
);
|
||||
|
||||
if (spotlight) {
|
||||
defs.push(
|
||||
<SpotlightGradient
|
||||
key={spotlightGradientId}
|
||||
id={spotlightGradientId}
|
||||
angle={angle + startAngle}
|
||||
dimensions={dimensions}
|
||||
roundedBars={roundedBars}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (segmentCount > 1) {
|
||||
graphics.push(
|
||||
<RadialBarSegmented
|
||||
dimensions={dimensions}
|
||||
fieldDisplay={displayValue}
|
||||
angleRange={angleRange}
|
||||
startAngle={startAngle}
|
||||
color={barColor}
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
segmentCount={segmentCount}
|
||||
segmentSpacing={segmentSpacing}
|
||||
displayProcessor={displayProcessor}
|
||||
gradient={gradient}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
graphics.push(
|
||||
<RadialBar
|
||||
dimensions={dimensions}
|
||||
key={barIndex}
|
||||
angle={angle}
|
||||
angleRange={angleRange}
|
||||
startAngle={startAngle}
|
||||
color={barColor}
|
||||
roundedBars={roundedBars}
|
||||
spotlightStroke={`url(#${spotlightGradientId})`}
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// These elements are only added for first value / bar
|
||||
|
||||
if (barIndex === 0) {
|
||||
if (glowBar) {
|
||||
defs.push(<GlowGradient id={glowFilterId} radius={dimensions.radius} />);
|
||||
}
|
||||
|
||||
if (glowCenter) {
|
||||
graphics.push(<MiddleCircleGlow gaugeId={gaugeId} color={color} dimensions={dimensions} />);
|
||||
}
|
||||
|
||||
graphics.push(
|
||||
<RadialText
|
||||
vizCount={vizCount}
|
||||
textMode={textMode}
|
||||
displayValue={displayValue.display}
|
||||
dimensions={dimensions}
|
||||
theme={theme}
|
||||
shape={shape}
|
||||
/>
|
||||
);
|
||||
|
||||
if (displayValue.sparkline) {
|
||||
sparklineElement = (
|
||||
<RadialSparkline
|
||||
sparkline={displayValue.sparkline}
|
||||
dimensions={dimensions}
|
||||
theme={theme}
|
||||
color={color}
|
||||
shape={shape}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.vizWrapper} style={{ width, height }}>
|
||||
<svg width={width} height={height}>
|
||||
<defs>
|
||||
{values.map((displayValue, barIndex) => (
|
||||
<GradientDef
|
||||
key={barIndex}
|
||||
fieldDisplay={displayValue}
|
||||
index={barIndex}
|
||||
theme={theme}
|
||||
gaugeId={gaugeId}
|
||||
gradient={gradient}
|
||||
dimensions={dimensions}
|
||||
shape={shape}
|
||||
/>
|
||||
))}
|
||||
{spotlight && (
|
||||
<SpotlightGradient
|
||||
angle={angle + startAngle}
|
||||
gaugeId={gaugeId}
|
||||
dimensions={dimensions}
|
||||
roundedBars={roundedBars}
|
||||
theme={theme}
|
||||
/>
|
||||
)}
|
||||
{glowBar && <GlowGradient gaugeId={gaugeId} radius={dimensions.radius} />}
|
||||
{glowCenter && <CenterGlowGradient gaugeId={gaugeId} color={color} />}
|
||||
</defs>
|
||||
<g>
|
||||
{values.map((displayValue, barIndex) => {
|
||||
const barColor = getColorForBar(displayValue.display, barIndex, gradient, gaugeId);
|
||||
//const barSize = dimensions.radius - (barWidth * 2 + 8) * barIndex;
|
||||
|
||||
let displayProcessor = getDisplayProcessor();
|
||||
|
||||
if (displayValue.view && isNumber(displayValue.colIndex)) {
|
||||
displayProcessor = displayValue.view.getFieldDisplayProcessor(displayValue.colIndex) ?? displayProcessor;
|
||||
}
|
||||
|
||||
if (segmentCount > 1) {
|
||||
return (
|
||||
<RadialBarSegmented
|
||||
dimensions={dimensions}
|
||||
key={barIndex}
|
||||
gaugeId={gaugeId}
|
||||
fieldDisplay={displayValue}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
color={barColor}
|
||||
spotlight={spotlight}
|
||||
glow={glowBar}
|
||||
segmentCount={segmentCount}
|
||||
segmentSpacing={segmentSpacing}
|
||||
displayProcessor={displayProcessor}
|
||||
gradient={gradient}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<RadialBar
|
||||
dimensions={dimensions}
|
||||
key={barIndex}
|
||||
gaugeId={gaugeId}
|
||||
fieldDisplay={displayValue}
|
||||
startAngle={startAngle}
|
||||
endAngle={endAngle}
|
||||
color={barColor}
|
||||
roundedBars={roundedBars}
|
||||
spotlight={spotlight}
|
||||
glow={glowBar}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</g>
|
||||
<g>
|
||||
{glowCenter && <MiddleCircle fill={`url(#circle-glow-${gaugeId})`} dimensions={dimensions} />}
|
||||
{primaryValue && (
|
||||
<RadialText
|
||||
vizCount={vizCount}
|
||||
textMode={textMode}
|
||||
displayValue={primaryValue.display}
|
||||
dimensions={dimensions}
|
||||
theme={theme}
|
||||
shape={shape}
|
||||
/>
|
||||
)}
|
||||
</g>
|
||||
<defs>{defs}</defs>
|
||||
{graphics}
|
||||
</svg>
|
||||
{primaryValue && primaryValue.sparkline && (
|
||||
<RadialSparkline
|
||||
sparkline={primaryValue.sparkline}
|
||||
dimensions={dimensions}
|
||||
theme={theme}
|
||||
color={color}
|
||||
shape={shape}
|
||||
/>
|
||||
)}
|
||||
{sparklineElement}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getColorForBar(displayValue: DisplayValue, barIndex: number, gradient: RadialGradientMode, gaugeId: string) {
|
||||
if (gradient === 'none') {
|
||||
return displayValue.color ?? 'gray';
|
||||
}
|
||||
|
||||
return `url(#${getGradientId(gaugeId, barIndex)})`;
|
||||
}
|
||||
|
||||
export interface MiddleCircleProps {
|
||||
dimensions: GaugeDimensions;
|
||||
fill?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function MiddleCircle({ dimensions, fill, className }: MiddleCircleProps) {
|
||||
return (
|
||||
<circle cx={dimensions.centerX} cy={dimensions.centerY} r={dimensions.radius} fill={fill} className={className} />
|
||||
);
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
vizWrapper: css({
|
||||
|
|
|
@ -3,15 +3,15 @@ import { GrafanaTheme2 } from '@grafana/data';
|
|||
import { GaugeDimensions } from './utils';
|
||||
|
||||
export interface GlowGradientProps {
|
||||
gaugeId: string;
|
||||
id: string;
|
||||
radius: number;
|
||||
}
|
||||
|
||||
export function GlowGradient({ gaugeId, radius }: GlowGradientProps) {
|
||||
export function GlowGradient({ id, radius }: GlowGradientProps) {
|
||||
const glowSize = 0.04 * radius;
|
||||
|
||||
return (
|
||||
<filter id={`glow-${gaugeId}`} filterUnits="userSpaceOnUse">
|
||||
<filter id={id} filterUnits="userSpaceOnUse">
|
||||
<feGaussianBlur stdDeviation={glowSize} />
|
||||
<feComponentTransfer>
|
||||
<feFuncA type="linear" slope="1" />
|
||||
|
@ -22,13 +22,13 @@ export function GlowGradient({ gaugeId, radius }: GlowGradientProps) {
|
|||
}
|
||||
|
||||
export function SpotlightGradient({
|
||||
gaugeId,
|
||||
id,
|
||||
dimensions,
|
||||
roundedBars,
|
||||
angle,
|
||||
theme,
|
||||
}: {
|
||||
gaugeId: string;
|
||||
id: string;
|
||||
dimensions: GaugeDimensions;
|
||||
angle: number;
|
||||
roundedBars: boolean;
|
||||
|
@ -44,7 +44,7 @@ export function SpotlightGradient({
|
|||
const color = theme.colors.text.maxContrast;
|
||||
|
||||
return (
|
||||
<linearGradient x1={x1} y1={y1} x2={x2} y2={y2} id={`spotlight-${gaugeId}`} gradientUnits="userSpaceOnUse">
|
||||
<linearGradient x1={x1} y1={y1} x2={x2} y2={y2} id={id} gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stopColor={color} stopOpacity={0.0} />
|
||||
<stop offset="95%" stopColor={color} stopOpacity={0.5} />
|
||||
{roundedBars && <stop offset="100%" stopColor={color} stopOpacity={roundedBars ? 0.7 : 1} />}
|
||||
|
@ -60,3 +60,27 @@ export function CenterGlowGradient({ gaugeId, color }: { gaugeId: string; color:
|
|||
</radialGradient>
|
||||
);
|
||||
}
|
||||
|
||||
export interface CenterGlowProps {
|
||||
dimensions: GaugeDimensions;
|
||||
gaugeId: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export function MiddleCircleGlow({ dimensions, gaugeId, color }: CenterGlowProps) {
|
||||
const gradientId = `circle-glow-${gaugeId}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<defs>
|
||||
<radialGradient id={gradientId} r={'50%'} fr={'0%'}>
|
||||
<stop offset="0%" stopColor={color} stopOpacity={0.2} />
|
||||
<stop offset="90%" stopColor={color} stopOpacity={0} />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<circle cx={dimensions.centerX} cy={dimensions.centerY} r={dimensions.radius} fill={`url(#${gradientId})`} />
|
||||
</g>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { FieldDisplay } from '@grafana/data';
|
||||
|
||||
export function getValueAngleForValue(fieldDisplay: FieldDisplay, startAngle: number, endAngle: number) {
|
||||
const range = (360 % (startAngle === 0 ? 1 : startAngle)) + endAngle;
|
||||
const angleRange = (360 % (startAngle === 0 ? 1 : startAngle)) + endAngle;
|
||||
const min = fieldDisplay.field.min ?? 0;
|
||||
const max = fieldDisplay.field.max ?? 100;
|
||||
|
||||
let angle = ((fieldDisplay.display.numeric - min) / (max - min)) * range;
|
||||
let angle = ((fieldDisplay.display.numeric - min) / (max - min)) * angleRange;
|
||||
|
||||
if (angle > range) {
|
||||
angle = range;
|
||||
if (angle > angleRange) {
|
||||
angle = angleRange;
|
||||
}
|
||||
|
||||
return { range, angle };
|
||||
return { angleRange, angle };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,6 +31,7 @@ export interface GaugeDimensions {
|
|||
centerY: number;
|
||||
barWidth: number;
|
||||
endAngle?: number;
|
||||
barIndex: number;
|
||||
}
|
||||
|
||||
export function calculateDimensions(
|
||||
|
@ -38,9 +39,9 @@ export function calculateDimensions(
|
|||
height: number,
|
||||
endAngle: number,
|
||||
glow: boolean,
|
||||
spotlight: boolean,
|
||||
roundedBars: boolean,
|
||||
barWidthFactor: number
|
||||
barWidthFactor: number,
|
||||
barIndex: number
|
||||
): GaugeDimensions {
|
||||
const yMaxAngle = endAngle > 180 ? 180 : endAngle;
|
||||
let margin = 0;
|
||||
|
@ -67,9 +68,14 @@ export function calculateDimensions(
|
|||
outerRadius -= (margin * 2) / (1 + heightRatioV);
|
||||
}
|
||||
|
||||
const innerRadius = outerRadius - barWidth / 2;
|
||||
let innerRadius = outerRadius - barWidth / 2;
|
||||
|
||||
const centerX = width / 2;
|
||||
const centerY = outerRadius + margin;
|
||||
|
||||
return { margin, radius: innerRadius, centerX, centerY, barWidth };
|
||||
if (barIndex > 0) {
|
||||
innerRadius = innerRadius - (barWidth + 4) * barIndex;
|
||||
}
|
||||
|
||||
return { margin, radius: innerRadius, centerX, centerY, barWidth, barIndex };
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue