Files
ALL-teach_sys/frontend_大健康/src/pages/InterviewSimulationPage/components/RadarChart/index.jsx

195 lines
5.4 KiB
React
Raw Normal View History

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 <div ref={chartRef} className={className} />;
}