Files
vf_react/src/components/ChatBot/EChartsRenderer.js
2025-11-30 18:55:35 +08:00

97 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/components/ChatBot/EChartsRenderer.js
// ECharts 图表渲染组件
import React, { useEffect, useRef } from 'react';
import { Box, useColorModeValue } from '@chakra-ui/react';
import * as echarts from 'echarts';
/**
* ECharts 图表渲染组件
* @param {Object} option - ECharts 配置对象
* @param {number} height - 图表高度(默认 400px
* @param {string} variant - 主题变体: 'light' | 'dark' | 'auto' (默认 auto)
*/
export const EChartsRenderer = ({ option, height = 400, variant = 'auto' }) => {
const chartRef = useRef(null);
const chartInstance = useRef(null);
// 系统颜色模式
const systemBgColor = useColorModeValue('white', 'transparent');
const systemIsDark = useColorModeValue(false, true);
// 根据 variant 决定实际使用的模式
const isDarkMode = variant === 'dark' ? true : variant === 'light' ? false : systemIsDark;
const bgColor = variant === 'dark' ? 'transparent' : variant === 'light' ? 'white' : systemBgColor;
useEffect(() => {
if (!chartRef.current || !option) {
console.warn('[EChartsRenderer] Missing chartRef or option');
return;
}
// 延迟初始化,确保 DOM 已渲染
const timer = setTimeout(() => {
try {
// 如果已有实例,先销毁
if (chartInstance.current) {
chartInstance.current.dispose();
}
// 初始化图表
chartInstance.current = echarts.init(chartRef.current, isDarkMode ? 'dark' : null);
// 深色模式下的样式调整
const darkModeStyle = isDarkMode ? {
backgroundColor: 'transparent',
textStyle: { color: '#e5e7eb' },
} : {};
// 合并配置
const finalOption = {
backgroundColor: 'transparent',
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
...darkModeStyle,
...option,
};
// 设置配置
chartInstance.current.setOption(finalOption);
console.log('[EChartsRenderer] Chart rendered successfully');
} catch (error) {
console.error('[EChartsRenderer] Failed to render chart:', error);
}
}, 100);
// 窗口 resize 处理
const handleResize = () => {
chartInstance.current?.resize();
};
window.addEventListener('resize', handleResize);
return () => {
clearTimeout(timer);
window.removeEventListener('resize', handleResize);
if (chartInstance.current) {
chartInstance.current.dispose();
chartInstance.current = null;
}
};
}, [option, isDarkMode]);
return (
<Box
ref={chartRef}
width="100%"
height={`${height}px`}
bg={bgColor}
borderRadius="md"
/>
);
};