# 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
```
## 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',
},
],
}
```