addressing PR comments
This commit is contained in:
@@ -2,18 +2,15 @@ import { useId, memo, HTMLAttributes, ReactNode } from 'react';
|
||||
|
||||
import { FieldDisplay } from '@grafana/data';
|
||||
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { buildGradientColors, getBarEndcapColors, getGradientCss, getEndpointMarkerColors } from './colors';
|
||||
import { RadialShape, RadialGaugeDimensions } from './types';
|
||||
import { getBarEndcapColors, getGradientCss, getEndpointMarkerColors } from './colors';
|
||||
import { RadialShape, RadialGaugeDimensions, GradientStop } from './types';
|
||||
import { drawRadialArcPath, toRad } from './utils';
|
||||
|
||||
export interface RadialArcPathPropsBase {
|
||||
arcLengthDeg: number;
|
||||
color?: string;
|
||||
barEndcaps?: boolean;
|
||||
dimensions: RadialGaugeDimensions;
|
||||
fieldDisplay: FieldDisplay;
|
||||
gradient?: boolean;
|
||||
roundedBars?: boolean;
|
||||
shape: RadialShape;
|
||||
endpointMarker?: 'point' | 'glow';
|
||||
@@ -22,13 +19,15 @@ export interface RadialArcPathPropsBase {
|
||||
endpointMarkerGlowFilter?: string;
|
||||
}
|
||||
|
||||
interface RadialArcPathPropsWithGuideDot extends RadialArcPathPropsBase {
|
||||
showGuideDots: true;
|
||||
guideDotStartColor: string;
|
||||
guideDotEndColor: string;
|
||||
interface RadialArcPathPropsWithColor extends RadialArcPathPropsBase {
|
||||
color: string;
|
||||
}
|
||||
|
||||
type RadialArcPathProps = RadialArcPathPropsBase | RadialArcPathPropsWithGuideDot;
|
||||
interface RadialArcPathPropsWithGradient extends RadialArcPathPropsBase {
|
||||
gradient: GradientStop[];
|
||||
}
|
||||
|
||||
type RadialArcPathProps = RadialArcPathPropsWithColor | RadialArcPathPropsWithGradient;
|
||||
|
||||
const ENDPOINT_MARKER_MIN_ANGLE = 10;
|
||||
const DOT_OPACITY = 0.5;
|
||||
@@ -38,27 +37,24 @@ const MAX_DOT_RADIUS = 8;
|
||||
export const RadialArcPath = memo(
|
||||
({
|
||||
arcLengthDeg,
|
||||
color,
|
||||
dimensions,
|
||||
fieldDisplay,
|
||||
gradient,
|
||||
roundedBars,
|
||||
shape,
|
||||
endpointMarker,
|
||||
barEndcaps,
|
||||
startAngle: angle,
|
||||
glowFilter,
|
||||
endpointMarkerGlowFilter,
|
||||
...rest
|
||||
}: RadialArcPathProps) => {
|
||||
const theme = useTheme2();
|
||||
const id = useId();
|
||||
|
||||
const gradientStops = buildGradientColors(gradient, theme, fieldDisplay, fieldDisplay.display.color);
|
||||
|
||||
const bgDivStyle: HTMLAttributes<HTMLDivElement>['style'] = { width: '100%', height: '100%' };
|
||||
if (color) {
|
||||
bgDivStyle.backgroundColor = color;
|
||||
if ('color' in rest) {
|
||||
bgDivStyle.backgroundColor = rest.color;
|
||||
} else {
|
||||
bgDivStyle.backgroundImage = getGradientCss(gradientStops, shape);
|
||||
bgDivStyle.backgroundImage = getGradientCss(rest.gradient, shape);
|
||||
}
|
||||
|
||||
const { radius, centerX, centerY, barWidth } = dimensions;
|
||||
@@ -76,44 +72,48 @@ export const RadialArcPath = memo(
|
||||
const dotRadius =
|
||||
endpointMarker === 'point' ? Math.min((barWidth / 2) * DOT_RADIUS_FACTOR, MAX_DOT_RADIUS) : barWidth / 2;
|
||||
|
||||
let barEndcapColors: [string | undefined, string | undefined] | undefined;
|
||||
|
||||
let barEndcapColors: [string, string] | undefined;
|
||||
let endpointMarks: ReactNode = null;
|
||||
if (endpointMarker && gradientStops.length > 0) {
|
||||
switch (endpointMarker) {
|
||||
case 'point':
|
||||
const [pointColorStart, pointColorEnd] = getEndpointMarkerColors(gradientStops, fieldDisplay.display.percent);
|
||||
endpointMarks = (
|
||||
<>
|
||||
{arcLengthDeg > ENDPOINT_MARKER_MIN_ANGLE && (
|
||||
<circle cx={xStart} cy={yStart} r={dotRadius} fill={pointColorStart} opacity={DOT_OPACITY} />
|
||||
)}
|
||||
<circle cx={xEnd} cy={yEnd} r={dotRadius} fill={pointColorEnd} opacity={DOT_OPACITY} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case 'glow':
|
||||
const offsetAngle = toRad(ENDPOINT_MARKER_MIN_ANGLE);
|
||||
const xStartMark = centerX + radius * Math.cos(endRadians + offsetAngle);
|
||||
const yStartMark = centerY + radius * Math.sin(endRadians + offsetAngle);
|
||||
endpointMarks =
|
||||
arcLengthDeg > ENDPOINT_MARKER_MIN_ANGLE ? (
|
||||
<path
|
||||
d={['M', xStartMark, yStartMark, 'A', radius, radius, 0, 0, 1, xEnd, yEnd].join(' ')}
|
||||
fill="none"
|
||||
strokeWidth={barWidth}
|
||||
stroke={endpointMarkerGlowFilter}
|
||||
strokeLinecap={roundedBars ? 'round' : 'butt'}
|
||||
filter={glowFilter}
|
||||
/>
|
||||
) : null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if ('gradient' in rest) {
|
||||
if (endpointMarker && (rest.gradient?.length ?? 0) > 0) {
|
||||
switch (endpointMarker) {
|
||||
case 'point':
|
||||
const [pointColorStart, pointColorEnd] = getEndpointMarkerColors(
|
||||
rest.gradient!,
|
||||
fieldDisplay.display.percent
|
||||
);
|
||||
endpointMarks = (
|
||||
<>
|
||||
{arcLengthDeg > ENDPOINT_MARKER_MIN_ANGLE && (
|
||||
<circle cx={xStart} cy={yStart} r={dotRadius} fill={pointColorStart} opacity={DOT_OPACITY} />
|
||||
)}
|
||||
<circle cx={xEnd} cy={yEnd} r={dotRadius} fill={pointColorEnd} opacity={DOT_OPACITY} />
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case 'glow':
|
||||
const offsetAngle = toRad(ENDPOINT_MARKER_MIN_ANGLE);
|
||||
const xStartMark = centerX + radius * Math.cos(endRadians + offsetAngle);
|
||||
const yStartMark = centerY + radius * Math.sin(endRadians + offsetAngle);
|
||||
endpointMarks =
|
||||
arcLengthDeg > ENDPOINT_MARKER_MIN_ANGLE ? (
|
||||
<path
|
||||
d={['M', xStartMark, yStartMark, 'A', radius, radius, 0, 0, 1, xEnd, yEnd].join(' ')}
|
||||
fill="none"
|
||||
strokeWidth={barWidth}
|
||||
stroke={endpointMarkerGlowFilter}
|
||||
strokeLinecap={roundedBars ? 'round' : 'butt'}
|
||||
filter={glowFilter}
|
||||
/>
|
||||
) : null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape === 'circle') {
|
||||
barEndcapColors = getBarEndcapColors(gradientStops, fieldDisplay.display.percent);
|
||||
if (barEndcaps) {
|
||||
barEndcapColors = getBarEndcapColors(rest.gradient, fieldDisplay.display.percent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { FieldDisplay } from '@grafana/data';
|
||||
import { FALLBACK_COLOR, FieldDisplay } from '@grafana/data';
|
||||
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { RadialArcPath } from './RadialArcPath';
|
||||
import { RadialShape, RadialGaugeDimensions } from './types';
|
||||
import { RadialShape, RadialGaugeDimensions, GradientStop } from './types';
|
||||
|
||||
export interface RadialBarProps {
|
||||
angle: number;
|
||||
angleRange: number;
|
||||
dimensions: RadialGaugeDimensions;
|
||||
fieldDisplay: FieldDisplay;
|
||||
gradient?: boolean;
|
||||
gradient?: GradientStop[];
|
||||
roundedBars?: boolean;
|
||||
endpointMarker?: 'point' | 'glow';
|
||||
shape: RadialShape;
|
||||
@@ -32,6 +32,7 @@ export function RadialBar({
|
||||
endpointMarkerGlowFilter,
|
||||
}: RadialBarProps) {
|
||||
const theme = useTheme2();
|
||||
const colorProps = gradient ? { gradient } : { color: fieldDisplay.display.color ?? FALLBACK_COLOR };
|
||||
return (
|
||||
<>
|
||||
{/** Track */}
|
||||
@@ -47,16 +48,16 @@ export function RadialBar({
|
||||
{/** The colored bar */}
|
||||
<RadialArcPath
|
||||
arcLengthDeg={angle}
|
||||
color={gradient ? undefined : fieldDisplay.display.color}
|
||||
barEndcaps={shape === 'circle' && roundedBars}
|
||||
dimensions={dimensions}
|
||||
endpointMarker={roundedBars ? endpointMarker : undefined}
|
||||
endpointMarkerGlowFilter={endpointMarkerGlowFilter}
|
||||
fieldDisplay={fieldDisplay}
|
||||
gradient={gradient}
|
||||
glowFilter={glowFilter}
|
||||
roundedBars={roundedBars}
|
||||
shape={shape}
|
||||
endpointMarker={roundedBars ? endpointMarker : undefined}
|
||||
startAngle={startAngle}
|
||||
endpointMarkerGlowFilter={endpointMarkerGlowFilter}
|
||||
glowFilter={glowFilter}
|
||||
{...colorProps}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { FALLBACK_COLOR, FieldDisplay } from '@grafana/data';
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
|
||||
import { RadialArcPath } from './RadialArcPath';
|
||||
import { RadialShape, RadialGaugeDimensions } from './types';
|
||||
import { RadialShape, RadialGaugeDimensions, GradientStop } from './types';
|
||||
import {
|
||||
getAngleBetweenSegments,
|
||||
getFieldConfigMinMax,
|
||||
@@ -22,7 +22,7 @@ export interface RadialBarSegmentedProps {
|
||||
segmentCount: number;
|
||||
segmentSpacing: number;
|
||||
shape: RadialShape;
|
||||
gradient?: boolean;
|
||||
gradient?: GradientStop[];
|
||||
}
|
||||
|
||||
export const RadialBarSegmented = memo(
|
||||
@@ -38,7 +38,6 @@ export const RadialBarSegmented = memo(
|
||||
shape,
|
||||
}: RadialBarSegmentedProps) => {
|
||||
const theme = useTheme2();
|
||||
|
||||
const segments: React.ReactNode[] = [];
|
||||
const segmentCountAdjusted = getOptimalSegmentCount(dimensions, segmentSpacing, segmentCount, angleRange);
|
||||
const [min, max] = getFieldConfigMinMax(fieldDisplay);
|
||||
@@ -50,24 +49,20 @@ export const RadialBarSegmented = memo(
|
||||
for (let i = 0; i < segmentCountAdjusted; i++) {
|
||||
const angleValue = min + ((max - min) / segmentCountAdjusted) * i;
|
||||
const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01;
|
||||
let segmentColor: string | undefined;
|
||||
if (angleValue >= value) {
|
||||
segmentColor = theme.colors.action.hover;
|
||||
} else if (!gradient) {
|
||||
segmentColor = displayProcessor(angleValue).color ?? FALLBACK_COLOR;
|
||||
}
|
||||
const segmentColor =
|
||||
angleValue >= value ? theme.colors.border.medium : (displayProcessor(angleValue).color ?? FALLBACK_COLOR);
|
||||
const colorProps = angleValue < value && gradient ? { gradient } : { color: segmentColor };
|
||||
|
||||
segments.push(
|
||||
<RadialArcPath
|
||||
key={i}
|
||||
arcLengthDeg={segmentArcLengthDeg}
|
||||
color={segmentColor}
|
||||
dimensions={dimensions}
|
||||
fieldDisplay={fieldDisplay}
|
||||
glowFilter={glowFilter}
|
||||
gradient={gradient}
|
||||
shape={shape}
|
||||
startAngle={segmentAngle}
|
||||
{...colorProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useId } from 'react';
|
||||
|
||||
import { DisplayValueAlignmentFactors, FieldDisplay, GrafanaTheme2, TimeRange } from '@grafana/data';
|
||||
import { DisplayValueAlignmentFactors, FALLBACK_COLOR, FieldDisplay, GrafanaTheme2, TimeRange } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
|
||||
@@ -13,6 +13,7 @@ import { RadialScaleLabels } from './RadialScaleLabels';
|
||||
import { RadialSparkline } from './RadialSparkline';
|
||||
import { RadialText } from './RadialText';
|
||||
import { ThresholdsBar } from './ThresholdsBar';
|
||||
import { buildGradientColors } from './colors';
|
||||
import { GlowGradient, MiddleCircleGlow, SpotlightGradient } from './effects';
|
||||
import { RadialShape, RadialTextMode } from './types';
|
||||
import { calculateDimensions, getValueAngleForValue } from './utils';
|
||||
@@ -112,7 +113,8 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
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 gradientStops = buildGradientColors(gradient, theme, displayValue);
|
||||
const color = displayValue.display.color ?? FALLBACK_COLOR;
|
||||
const dimensions = calculateDimensions(
|
||||
width,
|
||||
height,
|
||||
@@ -155,7 +157,7 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
segmentCount={segmentCount}
|
||||
segmentSpacing={segmentSpacing}
|
||||
shape={shape}
|
||||
gradient={gradient}
|
||||
gradient={gradientStops}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
@@ -170,7 +172,7 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
endpointMarkerGlowFilter={`url(#${spotlightGradientId})`}
|
||||
shape={shape}
|
||||
gradient={gradient}
|
||||
gradient={gradientStops}
|
||||
fieldDisplay={displayValue}
|
||||
endpointMarker={endpointMarker}
|
||||
/>
|
||||
@@ -233,7 +235,7 @@ export function RadialGauge(props: RadialGaugeProps) {
|
||||
roundedBars={roundedBars}
|
||||
glowFilter={`url(#${glowFilterId})`}
|
||||
shape={shape}
|
||||
gradient={gradient}
|
||||
gradient={gradientStops}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { FieldDisplay, Threshold } from '@grafana/data';
|
||||
|
||||
import { RadialArcPath } from './RadialArcPath';
|
||||
import { RadialGaugeDimensions, RadialShape } from './types';
|
||||
import { GradientStop, RadialGaugeDimensions, RadialShape } from './types';
|
||||
import { getFieldConfigMinMax } from './utils';
|
||||
|
||||
interface ThresholdsBarProps {
|
||||
@@ -14,7 +14,7 @@ interface ThresholdsBarProps {
|
||||
roundedBars?: boolean;
|
||||
glowFilter?: string;
|
||||
thresholds: Threshold[];
|
||||
gradient?: boolean;
|
||||
gradient?: GradientStop[];
|
||||
}
|
||||
|
||||
export function ThresholdsBar({
|
||||
@@ -50,20 +50,20 @@ export function ThresholdsBar({
|
||||
}
|
||||
|
||||
const lengthDeg = valueDeg - currentStart + startAngle;
|
||||
const color = gradient ? undefined : threshold.color;
|
||||
const colorProps = gradient ? { gradient } : { color: threshold.color };
|
||||
|
||||
paths.push(
|
||||
<RadialArcPath
|
||||
key={i}
|
||||
arcLengthDeg={lengthDeg}
|
||||
color={color}
|
||||
barEndcaps={shape === 'circle' && roundedBars}
|
||||
dimensions={thresholdDimensions}
|
||||
fieldDisplay={fieldDisplay}
|
||||
glowFilter={glowFilter}
|
||||
gradient={gradient}
|
||||
roundedBars={roundedBars}
|
||||
shape={shape}
|
||||
startAngle={currentStart}
|
||||
{...colorProps}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@@ -112,15 +112,15 @@ exports[`RadialGauge color utils buildGradientColors should return gradient colo
|
||||
exports[`RadialGauge color utils buildGradientColors should return gradient colors for fixed color mode in dark theme 1`] = `
|
||||
[
|
||||
{
|
||||
"color": "#210550",
|
||||
"color": "#37237a",
|
||||
"percent": 0,
|
||||
},
|
||||
{
|
||||
"color": "#442299",
|
||||
"percent": 0.33,
|
||||
"color": "#a146da",
|
||||
"percent": 0.75,
|
||||
},
|
||||
{
|
||||
"color": "#ffffff",
|
||||
"color": "#a146da",
|
||||
"percent": 1,
|
||||
},
|
||||
]
|
||||
@@ -129,15 +129,15 @@ exports[`RadialGauge color utils buildGradientColors should return gradient colo
|
||||
exports[`RadialGauge color utils buildGradientColors should return gradient colors for fixed color mode in light theme 1`] = `
|
||||
[
|
||||
{
|
||||
"color": "#9181d3",
|
||||
"color": "#a146da",
|
||||
"percent": 0,
|
||||
},
|
||||
{
|
||||
"color": "#442299",
|
||||
"percent": 0.33,
|
||||
"color": "#3e2b9a",
|
||||
"percent": 0.75,
|
||||
},
|
||||
{
|
||||
"color": "#210550",
|
||||
"color": "#3e2b9a",
|
||||
"percent": 1,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -4,13 +4,13 @@ import { colorManipulator, FALLBACK_COLOR, FieldDisplay, getFieldColorMode, Graf
|
||||
import { FieldColorModeId } from '@grafana/schema';
|
||||
|
||||
import { GradientStop, RadialShape } from './types';
|
||||
import { getFieldConfigMinMax, getFieldDisplayProcessor } from './utils';
|
||||
import { getFieldConfigMinMax, getFieldDisplayProcessor, getValuePercentageForValue } from './utils';
|
||||
|
||||
export function buildGradientColors(
|
||||
gradient = false,
|
||||
theme: GrafanaTheme2,
|
||||
fieldDisplay: FieldDisplay,
|
||||
baseColor = FALLBACK_COLOR
|
||||
baseColor = fieldDisplay.display.color ?? FALLBACK_COLOR
|
||||
): GradientStop[] {
|
||||
if (!gradient) {
|
||||
return [
|
||||
@@ -65,28 +65,31 @@ export function buildGradientColors(
|
||||
];
|
||||
}
|
||||
|
||||
// for fixed colors and other modes, we create a simple two-color gradient
|
||||
// we set the highest contrast color second based on the theme.
|
||||
const darkerColor = tinycolor(baseColor).spin(5).darken(20).saturate(25);
|
||||
const lighterColor = tinycolor(baseColor)
|
||||
.spin(-5)
|
||||
.brighten(theme.isDark ? 30 : 15)
|
||||
.lighten(theme.isDark ? 35 : 15);
|
||||
return [
|
||||
// For fixed / palette based color scales we can create a more hue and light
|
||||
// based linear gradient that we rotate with the value
|
||||
const darkerColor = tinycolor(baseColor)
|
||||
.spin(-20)
|
||||
.darken(theme.isDark ? 15 : 5);
|
||||
const lighterColor = tinycolor(baseColor).saturate(20).spin(20).brighten(10).lighten(10);
|
||||
|
||||
const underlyingGradient = [
|
||||
{ color: theme.isDark ? darkerColor.toString() : lighterColor.toString(), percent: 0 },
|
||||
{ color: baseColor, percent: 0.33 },
|
||||
{ color: theme.isDark ? lighterColor.toString() : darkerColor.toString(), percent: 1 },
|
||||
];
|
||||
}
|
||||
|
||||
function clamp(value: number, min = 0, max = 1) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (value < min || value > max) {
|
||||
console.error(`The value provided ${value} is out of range [${min}, ${max}].`);
|
||||
}
|
||||
}
|
||||
|
||||
return Math.min(Math.max(min, value), max);
|
||||
// rotate the gradient so that the highest contrasting point is the value, depending on theme.
|
||||
const valuePercent = getValuePercentageForValue(fieldDisplay);
|
||||
const startColor = theme.isDark
|
||||
? colorAtGradientPercent(underlyingGradient, 1 - valuePercent).toHexString()
|
||||
: underlyingGradient[0].color;
|
||||
const endColor = theme.isDark
|
||||
? underlyingGradient[1].color
|
||||
: colorAtGradientPercent(underlyingGradient, valuePercent).toHexString();
|
||||
return [
|
||||
{ color: startColor, percent: 0 },
|
||||
{ color: endColor, percent: valuePercent },
|
||||
{ color: endColor, percent: 1 },
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +107,7 @@ export function colorAtGradientPercent(stops: GradientStop[], percent: number):
|
||||
|
||||
// normalize and sort stops by percent. TODO: is this necessary? is gradientstops always sorted?
|
||||
const sorted = stops
|
||||
.map((s) => ({ color: s.color, percent: clamp(s.percent, 0, 1) }))
|
||||
.map((s) => ({ color: s.color, percent: Math.min(Math.max(0, s.percent), 1) }))
|
||||
.sort((a, b) => a.percent - b.percent);
|
||||
|
||||
// percent outside range
|
||||
|
||||
@@ -19,16 +19,20 @@ export function getFieldConfigMinMax(fieldDisplay: FieldDisplay) {
|
||||
return [min, max];
|
||||
}
|
||||
|
||||
export function getValuePercentageForValue(fieldDisplay: FieldDisplay, value = fieldDisplay.display.numeric) {
|
||||
const [min, max] = getFieldConfigMinMax(fieldDisplay);
|
||||
return (value - min) / (max - min);
|
||||
}
|
||||
|
||||
export function getValueAngleForValue(
|
||||
fieldDisplay: FieldDisplay,
|
||||
startAngle: number,
|
||||
endAngle: number,
|
||||
value = fieldDisplay.display.numeric
|
||||
) {
|
||||
const [min, max] = getFieldConfigMinMax(fieldDisplay);
|
||||
const angleRange = (360 % (startAngle === 0 ? 1 : startAngle)) + endAngle;
|
||||
|
||||
let angle = ((value - min) / (max - min)) * angleRange;
|
||||
let angle = getValuePercentageForValue(fieldDisplay, value) * angleRange;
|
||||
|
||||
if (angle > angleRange) {
|
||||
angle = angleRange;
|
||||
|
||||
@@ -32,6 +32,18 @@ export const plugin = new PanelPlugin<Options>(RadialBarPanel)
|
||||
},
|
||||
});
|
||||
|
||||
builder.addSliderInput({
|
||||
path: 'barWidthFactor',
|
||||
name: t('radialbar.config.bar-width', 'Bar width'),
|
||||
category,
|
||||
defaultValue: defaultOptions.barWidthFactor,
|
||||
settings: {
|
||||
min: 0.1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
},
|
||||
});
|
||||
|
||||
builder.addSliderInput({
|
||||
path: 'segmentCount',
|
||||
name: t('radialbar.config.segment-count', 'Segments'),
|
||||
@@ -87,18 +99,6 @@ export const plugin = new PanelPlugin<Options>(RadialBarPanel)
|
||||
showIf: (options) => options.barShape === 'rounded' && options.segmentCount === 1,
|
||||
});
|
||||
|
||||
builder.addSliderInput({
|
||||
path: 'barWidthFactor',
|
||||
name: t('radialbar.config.bar-width', 'Bar width'),
|
||||
category,
|
||||
defaultValue: defaultOptions.barWidthFactor,
|
||||
settings: {
|
||||
min: 0.1,
|
||||
max: 1,
|
||||
step: 0.01,
|
||||
},
|
||||
});
|
||||
|
||||
builder.addBooleanSwitch({
|
||||
path: 'sparkline',
|
||||
name: t('radialbar.config.sparkline', 'Show sparkline'),
|
||||
|
||||
Reference in New Issue
Block a user