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,46 +81,15 @@ 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; | ||||
| 
 | ||||
|   const { angle } = getValueAngleForValue(primaryValue, startAngle, endAngle); | ||||
| 
 | ||||
|   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;
 | ||||
|   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); | ||||
| 
 | ||||
|     let displayProcessor = getDisplayProcessor(); | ||||
| 
 | ||||
|  | @ -128,86 +97,111 @@ export function RadialGauge(props: RadialGaugeProps) { | |||
|       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) { | ||||
|               return ( | ||||
|       graphics.push( | ||||
|         <RadialBarSegmented | ||||
|           dimensions={dimensions} | ||||
|                   key={barIndex} | ||||
|                   gaugeId={gaugeId} | ||||
|           fieldDisplay={displayValue} | ||||
|           angleRange={angleRange} | ||||
|           startAngle={startAngle} | ||||
|                   endAngle={endAngle} | ||||
|           color={barColor} | ||||
|                   spotlight={spotlight} | ||||
|                   glow={glowBar} | ||||
|           glowFilter={`url(#${glowFilterId})`} | ||||
|           segmentCount={segmentCount} | ||||
|           segmentSpacing={segmentSpacing} | ||||
|           displayProcessor={displayProcessor} | ||||
|           gradient={gradient} | ||||
|         /> | ||||
|       ); | ||||
|             } | ||||
| 
 | ||||
|             return ( | ||||
|     } else { | ||||
|       graphics.push( | ||||
|         <RadialBar | ||||
|           dimensions={dimensions} | ||||
|           key={barIndex} | ||||
|                 gaugeId={gaugeId} | ||||
|                 fieldDisplay={displayValue} | ||||
|           angle={angle} | ||||
|           angleRange={angleRange} | ||||
|           startAngle={startAngle} | ||||
|                 endAngle={endAngle} | ||||
|           color={barColor} | ||||
|           roundedBars={roundedBars} | ||||
|                 spotlight={spotlight} | ||||
|                 glow={glowBar} | ||||
|           spotlightStroke={`url(#${spotlightGradientId})`} | ||||
|           glowFilter={`url(#${glowFilterId})`} | ||||
|         /> | ||||
|       ); | ||||
|           })} | ||||
|         </g> | ||||
|         <g> | ||||
|           {glowCenter && <MiddleCircle fill={`url(#circle-glow-${gaugeId})`} dimensions={dimensions} />} | ||||
|           {primaryValue && ( | ||||
|     } | ||||
| 
 | ||||
|     // 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={primaryValue.display} | ||||
|           displayValue={displayValue.display} | ||||
|           dimensions={dimensions} | ||||
|           theme={theme} | ||||
|           shape={shape} | ||||
|         /> | ||||
|           )} | ||||
|         </g> | ||||
|       </svg> | ||||
|       {primaryValue && primaryValue.sparkline && ( | ||||
|       ); | ||||
| 
 | ||||
|       if (displayValue.sparkline) { | ||||
|         sparklineElement = ( | ||||
|           <RadialSparkline | ||||
|           sparkline={primaryValue.sparkline} | ||||
|             sparkline={displayValue.sparkline} | ||||
|             dimensions={dimensions} | ||||
|             theme={theme} | ||||
|             color={color} | ||||
|             shape={shape} | ||||
|           /> | ||||
|       )} | ||||
|     </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} /> | ||||
|     <div className={styles.vizWrapper} style={{ width, height }}> | ||||
|       <svg width={width} height={height}> | ||||
|         <defs>{defs}</defs> | ||||
|         {graphics} | ||||
|       </svg> | ||||
|       {sparklineElement} | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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