react实现动态图表
使用 Recharts 实现动态图表
Recharts 是一个基于 React 和 D3.js 的图表库,适合快速实现动态图表。安装依赖后,可以直接使用其组件。
安装 Recharts:
npm install recharts
示例代码:
import React, { useState, useEffect } from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
const DynamicChart = () => {
const [data, setData] = useState([]);
useEffect(() => {
const interval = setInterval(() => {
const newDataPoint = {
name: new Date().toLocaleTimeString(),
value: Math.floor(Math.random() * 100)
};
setData(prevData => [...prevData.slice(-9), newDataPoint]); // 保留最后10个数据点
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<LineChart width={500} height={300} data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="value" stroke="#8884d8" />
</LineChart>
);
};
export default DynamicChart;
使用 Chart.js 与 react-chartjs-2
Chart.js 是另一个流行的图表库,通过 react-chartjs-2 可以更方便地在 React 中使用。
安装依赖:
npm install chart.js react-chartjs-2
示例代码:
import React, { useState, useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import { Chart, registerables } from 'chart.js';
Chart.register(...registerables);
const DynamicChart = () => {
const [chartData, setChartData] = useState({
labels: [],
datasets: [{
label: '动态数据',
data: [],
borderColor: 'rgb(75, 192, 192)',
tension: 0.1
}]
});
useEffect(() => {
const interval = setInterval(() => {
const newLabel = new Date().toLocaleTimeString();
const newValue = Math.floor(Math.random() * 100);
setChartData(prev => ({
labels: [...prev.labels.slice(-9), newLabel],
datasets: [{
...prev.datasets[0],
data: [...prev.datasets[0].data.slice(-9), newValue]
}]
}));
}, 1000);
return () => clearInterval(interval);
}, []);
return <Line data={chartData} />;
};
export default DynamicChart;
使用 D3.js 实现高度定制化图表
D3.js 提供更底层的控制,适合需要高度自定义的场景。
安装 D3:
npm install d3
示例代码:
import React, { useState, useEffect, useRef } from 'react';
import * as d3 from 'd3';
const DynamicD3Chart = () => {
const svgRef = useRef();
const [data, setData] = useState([]);
useEffect(() => {
const interval = setInterval(() => {
setData(prev => [...prev.slice(-9), {
time: new Date(),
value: Math.random() * 100
}]);
}, 1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
if (data.length === 0) return;
const svg = d3.select(svgRef.current);
const margin = { top: 20, right: 30, bottom: 30, left: 40 };
const width = 500 - margin.left - margin.right;
const height = 300 - margin.top - margin.bottom;
svg.selectAll('*').remove();
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const x = d3.scaleTime()
.domain(d3.extent(data, d => d.time))
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
g.append('g')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
g.append('g')
.call(d3.axisLeft(y));
const line = d3.line()
.x(d => x(d.time))
.y(d => y(d.value));
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 1.5)
.attr('d', line);
}, [data]);
return (
<svg
ref={svgRef}
width={500}
height={300}
/>
);
};
export default DynamicD3Chart;
性能优化建议
对于高频更新的动态图表,建议限制数据点数量(如只保留最近100个点)。使用 React.memo 或 useMemo 避免不必要的渲染。
const MemoizedChart = React.memo(({ data }) => {
// 图表渲染逻辑
});
动画方面可以通过 CSS 或库内置的过渡效果实现平滑更新,避免直接操作 DOM。







