import { useRef, useEffect } from "react"; import * as echarts from "echarts"; export default function RadarChart({ data = [5, 8, 5, 8], value = null, indicator = [ { name: "Sales", max: 6500 }, { name: "Administration", max: 16000 }, { name: "Information Technology", max: 30000 }, { name: "Marketing", max: 25000 }, ], className = "", lineClolr = "#DCDFFF", areaColor = "#CCCDFC", areaBorderColor = "#BDB5FF", isGreenTheme = false, // 新增参数:是否使用绿色主题 }) { const chartRef = useRef(null); const chartInstance = useRef(null); // 获取实际数据值 const actualData = value || data; // 创建渐变色配置 const gradientColor = isGreenTheme ? { type: 'radial', x: 0.5, y: 0.5, r: 0.5, colorStops: [{ offset: 0, color: 'rgba(34, 197, 94, 0.3)' // 绿色中心 }, { offset: 1, color: 'rgba(34, 197, 94, 0.8)' // 绿色边缘 }] } : { type: 'radial', x: 0.5, y: 0.5, r: 0.5, colorStops: [{ offset: 0, color: 'rgba(189, 181, 255, 0.3)' // 紫色中心 }, { offset: 1, color: 'rgba(189, 181, 255, 0.8)' // 紫色边缘 }] }; // 为指标添加分数显示 const indicatorWithScore = indicator.map((item, index) => ({ ...item, name: item.name, value: actualData[index] // 存储分数值 })); const option = { tooltip: { show: false }, grid: { show: false }, radar: [ { center: ["50%", "50%"], indicator: indicatorWithScore, radius: "45%", // 调小半径以确保文字和分数不超出容器 nameGap: 35, // 增大间距,让文字距离雷达图更远 shape: "circle", // 设置雷达图外圈为圆形 // 网格线样式配置 splitLine: { lineStyle: { color: lineClolr, // 网格线颜色 width: 2, type: "solid", // 线条类型:solid, dashed, dotted }, }, splitArea: { show: false }, axisName: { color: "#4E5969", fontSize: 12, fontWeight: "900", // 更粗的文字 lineHeight: 20, align: 'center', // 文本居中对齐 rich: { score: { fontSize: 18, fontWeight: 'bold', color: isGreenTheme ? '#22c55e' : '#8b5cf6', padding: [0, 0, 8, 0], align: 'center', lineHeight: 24 }, name: { fontSize: 12, color: '#4E5969', fontWeight: '900', align: 'center', lineHeight: 16 } }, formatter: function(value, indicator) { const index = indicatorWithScore.findIndex(item => item.name === value); const score = actualData[index]; // 已经包含换行符的处理 if (value.includes('\n')) { const parts = value.split('\n'); return '{score|' + score + '}\n{name|' + parts.join('\n') + '}'; } // 对较长的文本进行换行处理 if (value.length > 8) { const line1 = value.substring(0, 8); const line2 = value.substring(8); return '{score|' + score + '}\n{name|' + line1 + '\n' + line2 + '}'; } return '{score|' + score + '}\n{name|' + value + '}'; }, }, axisLine: { lineStyle: { color: "#E5E6EB", }, }, }, ], series: [ { type: "radar", radarIndex: 0, data: [{ value: value || data, label: { show: false, // 关键:隐藏雷达图内的标签 }, emphasis: { label: { show: false, // 确保 hover 时也不显示 }, fontSize: 12, color: "#333", }, areaStyle: { color: gradientColor, // 使用渐变色 }, // 关键:显示面积 lineStyle: { color: isGreenTheme ? '#22c55e' : areaBorderColor, // 连接线颜色(边框颜色) width: 3, // 连接线宽度 type: "solid", // 线条类型 }, symbol: "circle", // 显示端点 symbolSize: 6, // 端点大小 itemStyle: { color: "#fff", // 端点颜色 borderColor: isGreenTheme ? '#22c55e' : areaBorderColor, // 端点边框颜色 borderWidth: 2, // 端点边框宽度 }, }], }, ], }; useEffect(() => { if (!chartRef.current) return; // 如果实例不存在,则初始化 if (!chartInstance.current) { chartInstance.current = echarts.init(chartRef.current); } // 设置或更新配置,使用 notMerge: false 来避免重新触发动画 chartInstance.current.setOption(option, { notMerge: false, lazyUpdate: true, silent: false, }); const handleResize = () => { chartInstance.current?.resize(); }; window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [data, value, indicator]); // 组件卸载时清理 useEffect(() => { return () => { chartInstance.current?.dispose(); }; }, []); return
; }