# ChartPanel 组件 ## 组件说明 图表面板组件,基于 ECharts 封装,用于展示数据可视化图表。支持折线图、柱状图、饼图、环形图等多种图表类型,适合在仪表盘、监控面板、数据分析页面中使用。 ## 组件位置 ``` src/components/ChartPanel/ChartPanel.jsx src/components/ChartPanel/ChartPanel.css ``` ## 参数说明 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | type | string | 否 | 'line' | 图表类型:line/bar/pie/ring | | title | string | 否 | - | 图表标题 | | data | ChartData | 是 | - | 图表数据 | | height | number | 否 | 200 | 图表高度(像素) | | option | object | 否 | {} | 自定义 ECharts 配置项 | | className | string | 否 | '' | 自定义类名 | ### ChartData 数据格式 #### 折线图 / 柱状图数据格式 ```typescript { xAxis: string[] // X 轴数据(时间、类别等) series: Array<{ name: string // 系列名称 data: number[] // Y 轴数据 color?: string // 自定义颜色(可选) }> } ``` #### 饼图 / 环形图数据格式 ```typescript { data: Array<{ name: string // 数据项名称 value: number // 数据值 color?: string // 自定义颜色(可选) }> } ``` ### 图表类型说明 | 类型 | 适用场景 | 数据维度 | |------|---------|---------| | line | 趋势展示、时序数据、性能监控 | 多系列、时间轴 | | bar | 对比分析、排名展示、统计数据 | 多系列、分类轴 | | pie | 占比分析、分布展示 | 单维度、百分比 | | ring | 占比分析(带中心文字) | 单维度、百分比 | ## 使用示例 ### 折线图 ```jsx import ChartPanel from '../components/ChartPanel/ChartPanel' const lineData = { xAxis: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'], series: [ { name: 'CPU 使用率', data: [30, 45, 65, 50, 70, 55], color: '#1677ff', }, { name: '内存使用率', data: [20, 35, 55, 45, 60, 50], color: '#52c41a', }, ], } ``` ### 柱状图 ```jsx const barData = { xAxis: ['周一', '周二', '周三', '周四', '周五'], series: [ { name: '新增用户', data: [120, 200, 150, 180, 220], color: '#1677ff', }, { name: '活跃用户', data: [80, 150, 120, 140, 180], color: '#52c41a', }, ], } ``` ### 饼图 ```jsx const pieData = { data: [ { name: '运行中', value: 45, color: '#52c41a' }, { name: '已停止', value: 20, color: '#8c8c8c' }, { name: '错误', value: 5, color: '#ff4d4f' }, { name: '待部署', value: 30, color: '#faad14' }, ], } ``` ### 环形图 ```jsx const ringData = { data: [ { name: '在线', value: 85 }, { name: '离线', value: 15 }, ], } ``` ### 自定义 ECharts 配置 ```jsx ``` ### 配合 SideInfoPanel 使用 ```jsx import SideInfoPanel from '../components/SideInfoPanel/SideInfoPanel' import ChartPanel from '../components/ChartPanel/ChartPanel' , content: ( <> ), }, { key: 'distribution', title: '状态分布', icon: , content: ( <> ), }, ]} /> ``` ## DOM 结构层级 ```html
{title && (
{title}
)}
``` ## ECharts 配置说明 ### 折线图默认配置 ```javascript { tooltip: { trigger: 'axis', backgroundColor: 'rgba(0, 0, 0, 0.7)', }, legend: { bottom: 0, left: 'center', }, grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true, }, xAxis: { type: 'category', data: data.xAxis, boundaryGap: false, }, yAxis: { type: 'value', }, series: data.series.map(s => ({ name: s.name, type: 'line', data: s.data, smooth: true, itemStyle: { color: s.color }, })), } ``` ### 柱状图默认配置 ```javascript { tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, }, legend: { bottom: 0, left: 'center', }, grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true, }, xAxis: { type: 'category', data: data.xAxis, }, yAxis: { type: 'value', }, series: data.series.map(s => ({ name: s.name, type: 'bar', data: s.data, itemStyle: { color: s.color }, })), } ``` ### 饼图默认配置 ```javascript { tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)', }, legend: { bottom: 0, left: 'center', }, series: [ { type: 'pie', radius: '70%', center: ['50%', '45%'], data: data.data.map(item => ({ name: item.name, value: item.value, itemStyle: { color: item.color }, })), emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)', }, }, }, ], } ``` ### 环形图默认配置 ```javascript { tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)', }, legend: { bottom: 0, left: 'center', }, series: [ { type: 'pie', radius: ['50%', '70%'], // 环形图特征:内外半径 center: ['50%', '45%'], data: data.data.map(item => ({ name: item.name, value: item.value, itemStyle: { color: item.color }, })), label: { show: false, // 环形图默认不显示标签 }, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)', }, }, }, ], } ``` ## 组件生命周期 ### 初始化流程 1. 组件挂载时,通过 `useRef` 获取 DOM 容器 2. 使用 `echarts.init()` 初始化 ECharts 实例 3. 根据 `type` 和 `data` 生成配置项 4. 调用 `setOption()` 渲染图表 ### 更新流程 1. 当 `type`、`data`、`option` 变化时触发 `useEffect` 2. 复用已有的 ECharts 实例 3. 重新生成配置项并调用 `setOption()` 更新图表 ### 响应式处理 1. 监听 `window.resize` 事件 2. 调用 `chartInstance.resize()` 自动调整图表尺寸 3. 组件卸载时移除事件监听并销毁 ECharts 实例 ```javascript useEffect(() => { const handleResize = () => { if (chartInstance.current) { chartInstance.current.resize() } } window.addEventListener('resize', handleResize) return () => { window.removeEventListener('resize', handleResize) if (chartInstance.current) { chartInstance.current.dispose() } } }, []) ``` ## 样式定制 组件提供以下 CSS 类名供自定义样式: - `.chart-panel` - 面板容器 - `.chart-panel-title` - 图表标题 - `.chart-panel-chart` - ECharts 容器 ### 自定义样式示例 ```css /* 修改标题样式 */ .chart-panel-title { font-size: 16px; font-weight: 600; color: #1677ff; } /* 修改面板背景 */ .chart-panel { background: #f5f5f5; border-radius: 8px; padding: 16px; } /* 修改图表容器 */ .chart-panel-chart { background: #ffffff; } ``` ## 使用场景 1. **性能监控面板** - 展示 CPU、内存、网络等实时性能数据 2. **数据分析仪表盘** - 展示业务指标、用户统计、销售数据 3. **状态分布展示** - 展示系统状态、设备状态、任务状态的占比 4. **趋势对比分析** - 展示多个指标的时序变化和对比 ## 注意事项 1. **数据格式**: - 确保数据格式与图表类型匹配 - 折线图/柱状图使用 xAxis + series 格式 - 饼图/环形图使用 data 数组格式 - 数据更新时会自动重新渲染 2. **图表高度**: - 默认高度 200px,建议根据内容调整 - 折线图/柱状图:200-400px - 饼图/环形图:200-300px - 避免高度过小导致显示不清 3. **颜色使用**: - 可在数据中指定 color 属性自定义颜色 - 不指定时使用 ECharts 默认配色 - 建议使用语义化颜色(绿色=正常,红色=错误) - 同一页面保持配色风格一致 4. **性能优化**: - 大数据量时考虑数据采样 - 避免频繁更新图表(建议间隔 > 1s) - 组件卸载时会自动销毁 ECharts 实例 - 窗口 resize 时会自动调整图表尺寸 5. **响应式**: - 图表会自动适应容器宽度 - 窗口大小变化时自动 resize - 小屏幕时建议减小图表高度 6. **自定义配置**: - 使用 option 参数传入自定义 ECharts 配置 - 自定义配置会与默认配置深度合并 - 可完全覆盖默认配置实现高度定制 7. **标题使用**: - title 为可选参数 - 在 SideInfoPanel 中使用时,section 已有标题,可省略 ChartPanel 标题 - 独立使用时建议添加标题增强可读性 ## 配合使用的组件 - **SideInfoPanel** - 侧边信息面板(推荐) - **StatCard** - 统计卡片(配合使用) - **SplitLayout** - 分栏布局 - **PageTitleBar** - 页面标题栏 ## ECharts 依赖 本组件依赖 ECharts 库,确保已安装: ```bash npm install echarts # 或 yarn add echarts ``` 导入方式: ```javascript import * as echarts from 'echarts' ``` ## 示例数据结构参考 ### 性能监控数据 ```javascript const performanceData = { xAxis: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'], series: [ { name: 'CPU', data: [30, 45, 65, 50, 70, 55], color: '#1677ff', }, { name: '内存', data: [20, 35, 55, 45, 60, 50], color: '#52c41a', }, ], } ``` ### 状态分布数据 ```javascript const statusData = { data: [ { name: '运行中', value: 45, color: '#52c41a' }, { name: '已停止', value: 20, color: '#8c8c8c' }, { name: '错误', value: 5, color: '#ff4d4f' }, { name: '待部署', value: 30, color: '#faad14' }, ], } ``` ### 区域分布数据 ```javascript const regionData = { xAxis: ['华东', '华南', '华北', '西南', '西北'], series: [ { name: '服务器数量', data: [120, 80, 95, 65, 45], color: '#1677ff', }, ], } ```