import tinycolor from 'tinycolor2'; import type { ComponentType } from '../../jsx'; import { Defs, Ellipse, Group } from '../../jsx'; import { ItemLabel } from '../components'; import { getItemProps } from '../utils'; import { registerItem } from './registry'; import type { BaseItemProps } from './types'; export interface CircleNodeProps extends BaseItemProps { width?: number; height?: number; } export const CircleNode: ComponentType = (props) => { const [ { indexes, datum, themeColors, positionH = 'normal', width = 240, height = width, }, restProps, ] = getItemProps(props, ['width', 'height']); const size = Math.min(width, height); const innerCircleSize = size * 0.7; const innerCircleOffset = (size - innerCircleSize) / 2; const labelSize = (innerCircleSize * Math.sqrt(2)) / 2; const labelOffset = (size - labelSize) / 2; const base = tinycolor(themeColors.colorPrimary); const colorOuterStart = fadeWithWhite(base, 80, 0.2); const colorOuterEnd = fadeWithWhite(base, 20, 0.8); const colorInnerStart = fadeWithWhite(base, 75, 0.32); const colorInnerEnd = fadeWithWhite(base, 45, 0.4); const colorText = base.clone().darken(5).toRgbString(); const outerGradientId = `${themeColors.colorPrimary}-${positionH}-outer`; const innerGradientId = `${themeColors.colorPrimary}-${positionH}-inner`; const gradientDirection = positionH === 'flipped' ? { x1: '0%', y1: '0%', x2: '100%', y2: '0%' } : { x1: '100%', y1: '0%', x2: '0%', y2: '0%' }; return ( {datum.label} ); }; registerItem('circle-node', { component: CircleNode, composites: ['label'], }); function fadeWithWhite( color: tinycolor.Instance, mixPct: number, alpha: number, ) { return tinycolor.mix(color, '#ffffff', mixPct).setAlpha(alpha).toRgbString(); }