// src/components/ChatBot/EChartsRenderer.js // ECharts 图表渲染组件 import React, { useEffect, useRef } from 'react'; import { Box, useColorModeValue } from '@chakra-ui/react'; import { echarts } from '@lib/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 ( ); };