Chart.js 散点图
在 React 项目中使用 Chart.js 创建散点图(Scatter Chart)是一种有效的数据可视化方式,适合展示二维数据点之间的关系,例如销售额与广告支出的相关性。结合 react-chartjs-2
库,散点图可以通过 React 组件化方式快速实现。本文以中文讲解 Chart.js 散点图的创建过程,涵盖基本用法、动态数据、样式定制、与 React Router 和 Tailwind CSS 的结合,以及注意事项,力求简洁清晰,避免重复之前的内容,并提供实用示例。
1. 散点图概述
散点图(Scatter Chart)通过在二维坐标系中绘制数据点展示变量之间的关系,每个点表示一个数据点的 x 和 y 坐标。Chart.js 的散点图支持:
- 多数据集:展示多组数据点,区分不同类别。
- 交互效果:支持悬停提示、点击事件。
- 响应式:自动适配容器大小。
- 高度可定制:调整点样式、颜色、轴等。
在 React 中,使用 react-chartjs-2
的 <Scatter />
组件渲染散点图。
2. 基本散点图实现
以下是在 React 中使用 Chart.js 创建一个简单散点图的示例,展示销售额与广告支出的关系。
示例代码
import { Scatter } from 'react-chartjs-2';
import { Chart as ChartJS, LinearScale, PointElement, Tooltip, Legend } from 'chart.js';
// 注册必要模块
ChartJS.register(LinearScale, PointElement, Tooltip, Legend);
function ScatterChart() {
// 数据配置
const data = {
datasets: [
{
label: '产品数据',
data: [
{ x: 100, y: 50 }, // x: 广告支出, y: 销售额
{ x: 150, y: 70 },
{ x: 200, y: 60 },
{ x: 250, y: 80 },
{ x: 300, y: 90 },
],
backgroundColor: 'rgba(59, 130, 246, 0.6)', // 点填充颜色
borderColor: 'rgba(59, 130, 246, 1)', // 点边框颜色
pointRadius: 6, // 点半径
},
],
};
// 选项配置
const options = {
responsive: true,
plugins: {
legend: {
position: 'top',
labels: { font: { size: 12 } },
},
tooltip: {
backgroundColor: '#1f2937', // 提示框背景
callbacks: {
label: (context) => {
const { x, y } = context.raw;
return `${context.dataset.label}: (广告: ${x} 万元, 销售: ${y} 万元)`;
},
},
},
title: {
display: true,
text: '广告支出与销售额关系',
font: { size: 16 },
},
},
scales: {
x: {
title: { display: true, text: '广告支出 (万元)' },
grid: { color: '#e5e7eb' }, // 网格颜色
min: 0,
},
y: {
title: { display: true, text: '销售额 (万元)' },
beginAtZero: true,
grid: { color: '#e5e7eb' },
},
},
};
return (
<div className="w-full max-w-3xl mx-auto p-6 bg-white rounded-lg shadow-md">
<Scatter data={data} options={options} />
</div>
);
}
export default ScatterChart;
说明
- 注册模块:
LinearScale
:散点图使用线性刻度(X/Y 轴均为数值)。PointElement
:支持数据点的绘制。Tooltip
、Legend
:交互和图例支持。- 数据(data):
- 不需要
labels
(X 轴由数据点的x
值决定)。 datasets.data
:数组中的每个对象包含x
和y
坐标。pointRadius
:设置数据点大小。- 选项(options):
responsive: true
:适配容器大小。tooltip.callbacks.label
:自定义提示框,显示坐标值。scales
:配置 X/Y 轴标题、网格和范围。- 容器:使用 Tailwind CSS 类(如
bg-white
、rounded-lg
)美化容器。
3. 多数据集散点图
散点图支持多个数据集,展示不同类别的数据点。
示例:多数据集散点图
function MultiScatterChart() {
const data = {
datasets: [
{
label: '产品 A',
data: [
{ x: 100, y: 50 },
{ x: 150, y: 70 },
{ x: 200, y: 60 },
],
backgroundColor: 'rgba(59, 130, 246, 0.6)',
borderColor: 'rgba(59, 130, 246, 1)',
pointRadius: 6,
},
{
label: '产品 B',
data: [
{ x: 120, y: 55 },
{ x: 180, y: 80 },
{ x: 220, y: 65 },
],
backgroundColor: 'rgba(255, 99, 132, 0.6)',
borderColor: 'rgba(255, 99, 132, 1)',
pointRadius: 6,
},
],
};
const options = {
responsive: true,
plugins: {
legend: { position: 'top' },
title: { display: true, text: '产品 A vs 产品 B 销售分析' },
},
scales: {
x: { title: { display: true, text: '广告支出 (万元)' }, min: 0 },
y: { title: { display: true, text: '销售额 (万元)' }, beginAtZero: true },
},
};
return (
<div className="w-full max-w-3xl mx-auto p-6 bg-white rounded-lg shadow-md">
<Scatter data={data} options={options} />
</div>
);
}
说明
- 多数据集:每个
dataset
表示一组数据点,颜色区分不同产品。 - 视觉效果:通过
backgroundColor
和borderColor
区分数据集。 - 应用场景:比较不同类别的数据点关系。
4. 动态数据更新
结合 React 的 useState
和 useEffect
Hooks,实现散点图的动态更新,适合实时数据展示。
示例:动态散点图
import { useState, useEffect } from 'react';
import { Scatter } from 'react-chartjs-2';
import { Chart as ChartJS, LinearScale, PointElement, Tooltip, Legend } from 'chart.js';
ChartJS.register(LinearScale, PointElement, Tooltip, Legend);
function DynamicScatterChart() {
const [data, setData] = useState({
datasets: [
{
label: '实时数据',
data: [
{ x: 100, y: 50 },
{ x: 150, y: 70 },
{ x: 200, y: 60 },
],
backgroundColor: 'rgba(34, 197, 94, 0.6)',
borderColor: 'rgba(34, 197, 94, 1)',
pointRadius: 6,
},
],
});
useEffect(() => {
const interval = setInterval(() => {
setData(prev => ({
...prev,
datasets: [
{
...prev.datasets[0],
data: prev.datasets[0].data.map(() => ({
x: Math.random() * 300,
y: Math.random() * 100,
})),
},
],
}));
}, 3000); // 每 3 秒更新
return () => clearInterval(interval);
}, []);
const options = {
responsive: true,
plugins: {
legend: { position: 'top' },
title: { display: true, text: '实时数据散点图' },
},
scales: {
x: { min: 0, max: 300, title: { display: true, text: 'X 轴' } },
y: { min: 0, max: 100, title: { display: true, text: 'Y 轴' } },
},
};
return (
<div className="w-full max-w-3xl mx-auto p-6 bg-white rounded-lg shadow-md">
<Scatter data={data} options={options} />
</div>
);
}
说明
- 动态更新:
useEffect
每 3 秒生成随机坐标,更新散点图。 - 性能优化:可用
useMemo
缓存data
:
const memoizedData = useMemo(() => data, [data]);
- 范围限制:通过
scales.x.min/max
设置坐标轴范围。
5. 与 React Router 结合
将散点图嵌入 React Router 页面,适合数据分析仪表盘。
示例
import { Routes, Route, NavLink } from 'react-router-dom';
import ScatterChart from './ScatterChart';
import MultiScatterChart from './MultiScatterChart';
function App() {
return (
<div className="p-6">
<nav className="mb-6 space-x-4">
<NavLink
to="/scatter"
className={({ isActive }) =>
isActive ? 'text-blue-500 font-bold' : 'text-gray-500'
}
>
标准散点图
</NavLink>
<NavLink
to="/multi-scatter"
className={({ isActive }) =>
isActive ? 'text-blue-500 font-bold' : 'text-gray-500'
}
>
多数据集散点图
</NavLink>
</nav>
<Routes>
<Route path="/scatter" element={<ScatterChart />} />
<Route path="/multi-scatter" element={<MultiScatterChart />} />
</Routes>
</div>
);
}
说明
- NavLink:切换不同散点图页面,动态添加激活样式。
- Routes:映射散点图组件到路由路径。
6. 与 Tailwind CSS 结合
散点图渲染在 Canvas 上,外部容器可用 Tailwind CSS 美化。
示例
function ScatterChart() {
const data = { /* 同上 */ };
const options = { /* 同上 */ };
return (
<div className="bg-white p-6 rounded-lg shadow-md max-w-3xl mx-auto">
<h2 className="text-xl font-semibold mb-4 text-center">广告与销售分析</h2>
<Scatter data={data} options={options} />
</div>
);
}
说明
- 容器样式:Tailwind 类(如
bg-white
、rounded-lg
)美化容器。 - Canvas 样式:散点图内部样式由
data
和options
控制。
7. 自定义散点图样式
通过 options
和 data
自定义散点图的外观。
示例:自定义样式
const options = {
responsive: true,
plugins: {
legend: { position: 'bottom', labels: { font: { size: 12 } } },
tooltip: {
backgroundColor: '#111827',
callbacks: {
label: (context) => {
const { x, y } = context.raw;
return `${context.dataset.label}: (X: ${x}, Y: ${y})`;
},
},
},
title: { display: true, text: '自定义散点图', font: { size: 16 } },
},
scales: {
x: { min: 0, max: 400, grid: { display: false }, title: { display: true, text: 'X 轴' } },
y: { min: 0, max: 100, grid: { color: '#e5e7eb' }, title: { display: true, text: 'Y 轴' } },
},
elements: {
point: {
radius: 6, // 默认点大小
hoverRadius: 8, // 悬停时放大
backgroundColor: 'rgba(59, 130, 246, 0.6)',
hoverBackgroundColor: 'rgba(59, 130, 246, 1)',
},
},
};
说明
- 点样式:
elements.point
控制点大小、悬停效果和颜色。 - Tooltip:自定义提示框内容和样式。
- 坐标轴:
scales
设置范围、网格和标题。
8. 注意事项
- 模块注册:
- 确保注册
LinearScale
和PointElement
,否则报错(如“Linear is not a registered scale”)。
- 数据格式:
- 每个数据点需包含
x
和y
属性。 - 检查数据有效性,避免空数组或无效值。
- 性能优化:
- 使用
useMemo
缓存data
和options
:jsx const memoizedData = useMemo(() => data, [data]);
- 动态更新时限制数据点数量,避免性能瓶颈。
- 容器尺寸:
- 确保容器有足够宽高,可通过 CSS 或
options
设置:jsx options: { maintainAspectRatio: false, height: 400 }
- 调试:
- 检查浏览器开发者工具,确保 Canvas 渲染正常。
- 验证
data.datasets
格式,排除配置错误。
9. 资源
- Chart.js 散点图文档:https://www.chartjs.org/docs/latest/charts/scatter.html
- react-chartjs-2 示例:https://react-chartjs-2.js.org/examples/scatter-chart
- 中文社区:搜索“Chart.js 散点图 中文教程”或参考掘金、知乎。
如果需要更详细的讲解(如复杂散点图配置、插件集成或交互优化),请告诉我!