Chart.js 散点图(手把手讲解)

什么是 Chart.js 散点图?

如果你曾经用过 Excel 做过数据分析,应该对“散点图”不陌生。它就像是在一张纸上撒了一把彩色的点,每个点代表一个数据对,横轴和纵轴分别表示两个变量。这种图表特别适合发现数据之间的关系——比如,学习时间与考试成绩之间是否存在正相关?

Chart.js 散点图正是将这种直观的视觉分析能力带入网页中的利器。它基于 HTML5 的 Canvas 技术,能动态渲染出清晰、可交互的散点图,而且支持响应式设计,无论在手机、平板还是桌面端都能正常显示。

简单来说,Chart.js 散点图就是:

  • 用点表示数据
  • 横轴(X 轴)和纵轴(Y 轴)各代表一个变量
  • 通过点的分布,一眼看出两个变量之间的趋势或关联

想象一下,你在分析某公司员工的薪资和工龄关系。如果散点图上的点从左下向右上倾斜,说明“工龄越长,薪资越高”——这就是一个典型的正相关关系。这种洞察,比看表格直观多了。

如何引入 Chart.js?

在开始画图之前,必须先把 Chart.js 加入项目。这就像准备画布和颜料,没有它们,再好的构想也无法实现。

我们可以通过 CDN(内容分发网络)方式快速引入,适合初学者快速上手。打开你的 HTML 文件,在 <head> 标签中加入以下代码:

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

这段代码会自动从官方服务器加载最新版的 Chart.js。注意:CDN 地址中的版本号是动态的,如果你需要固定版本,可以指定具体版本号,例如:

<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>

引入完成后,你就可以在页面中创建图表了。但别急,先确保你的 HTML 结构中有一个可以放置图表的容器。

<canvas id="scatterChart" width="600" height="400"></canvas>

这个 <canvas> 元素就像是一个画布,Chart.js 会在这个区域绘制出你的散点图。记住:id 必须与后续 JavaScript 中引用的一致。

创建数组与初始化

在绘制图表前,我们需要准备数据。散点图的数据结构相对简单,每个点由一对坐标组成:X 值和 Y 值。

比如我们想分析 10 个学生的数学成绩(0~100)和英语成绩(0~100)之间的关系。我们可以这样定义数据:

// 存储散点图数据的数组,每个对象代表一个点
const scatterData = [
  { x: 85, y: 78 },  // 学生 1:数学 85,英语 78
  { x: 92, y: 88 },  // 学生 2:数学 92,英语 88
  { x: 70, y: 65 },  // 学生 3:数学 70,英语 65
  { x: 95, y: 90 },  // 学生 4:数学 95,英语 90
  { x: 60, y: 55 },  // 学生 5:数学 60,英语 55
  { x: 88, y: 82 },  // 学生 6:数学 88,英语 82
  { x: 75, y: 70 },  // 学生 7:数学 75,英语 70
  { x: 90, y: 85 },  // 学生 8:数学 90,英语 85
  { x: 65, y: 60 },  // 学生 9:数学 65,英语 60
  { x: 80, y: 75 }   // 学生 10:数学 80,英语 75
];

这里的关键是:每个数据点是一个对象,包含 xy 两个属性。这种结构是 Chart.js 散点图的“标准语言”,你必须严格遵守。

接下来,初始化图表。我们通过 JavaScript 获取 <canvas> 元素,并创建一个 Chart 实例:

// 获取画布元素
const ctx = document.getElementById('scatterChart').getContext('2d');

// 创建 Chart.js 实例,指定类型为 'scatter'
const scatterChart = new Chart(ctx, {
  type: 'scatter',  // 明确告诉 Chart.js:我要画散点图
  data: {
    datasets: [
      {
        label: '学生成绩分布',  // 图例名称
        data: scatterData,      // 数据数组
        backgroundColor: 'rgba(54, 162, 235, 0.6)',  // 点的颜色(带透明度)
        borderColor: 'rgba(54, 162, 235, 1)',       // 边框颜色
        pointRadius: 8,         // 点的大小
        pointHoverRadius: 12    // 鼠标悬停时点的放大尺寸
      }
    ]
  },
  options: {
    responsive: true,           // 图表自适应大小
    plugins: {
      legend: {
        position: 'top'         // 图例位置在顶部
      }
    },
    scales: {
      x: {
        title: {
          display: true,
          text: '数学成绩(分)'
        },
        min: 0,
        max: 100
      },
      y: {
        title: {
          display: true,
          text: '英语成绩(分)'
        },
        min: 0,
        max: 100
      }
    }
  }
});

这段代码是整个图表的核心。我们来逐行解释:

  • type: 'scatter':明确指定图表类型为散点图
  • data.datasets[0].data:填入我们定义好的数据数组
  • backgroundColorborderColor:控制点的颜色和边框
  • pointRadius:设置点的大小,越大越醒目
  • scales.xscales.y:分别设置横轴和纵轴的标题与范围

高级配置:趋势线与样式优化

光有散点还不够“高级”。我们常常希望在图中加入一条趋势线(Trend Line),帮助判断数据的整体走向。Chart.js 本身不直接支持趋势线,但我们可以借助插件 chartjs-adapter-date-fns 或手动添加一条线。

这里我们用一个简单方法:在数据集中添加一条模拟的趋势线。

// 添加趋势线数据:假设数学成绩每增加 10 分,英语成绩增加 8 分
const trendLineData = [];
for (let i = 0; i <= 100; i += 10) {
  // 线性关系:y = 0.8x + 10
  const y = 0.8 * i + 10;
  trendLineData.push({ x: i, y: y });
}

然后在 datasets 中添加第二条数据集:

datasets: [
  {
    label: '学生成绩分布',
    data: scatterData,
    backgroundColor: 'rgba(54, 162, 235, 0.6)',
    borderColor: 'rgba(54, 162, 235, 1)',
    pointRadius: 8,
    pointHoverRadius: 12
  },
  {
    label: '趋势线',
    data: trendLineData,
    type: 'line',                    // 指定为折线图
    borderColor: 'rgba(255, 99, 132, 1)',
    borderWidth: 2,
    fill: false,                     // 不填充区域
    pointRadius: 0,                  // 不显示点
    showLine: true
  }
]

这样,一条红色的趋势线就叠加在散点图上。它告诉你:如果数学成绩提高,英语成绩大概率也会提高,只是幅度略小。

你还可以通过调整 backgroundColor 的透明度(0.6)让点看起来更柔和,避免视觉干扰。

实际应用案例:分析销售与广告投入

让我们换一个真实场景:某电商公司想分析“广告投入金额”与“销售额”之间的关系。

假设我们有以下数据:

广告投入(万元) 销售额(万元)
2 15
5 30
8 50
10 60
15 85
20 100

我们用同样的方式创建图表:

const salesData = [
  { x: 2, y: 15 },
  { x: 5, y: 30 },
  { x: 8, y: 50 },
  { x: 10, y: 60 },
  { x: 15, y: 85 },
  { x: 20, y: 100 }
];

const ctx = document.getElementById('scatterChart').getContext('2d');
const chart = new Chart(ctx, {
  type: 'scatter',
  data: {
    datasets: [
      {
        label: '广告投入 vs 销售额',
        data: salesData,
        backgroundColor: 'rgba(75, 192, 192, 0.6)',
        pointRadius: 8
      }
    ]
  },
  options: {
    responsive: true,
    plugins: {
      legend: {
        position: 'top'
      }
    },
    scales: {
      x: {
        title: {
          display: true,
          text: '广告投入(万元)'
        },
        min: 0,
        max: 25
      },
      y: {
        title: {
          display: true,
          text: '销售额(万元)'
        },
        min: 0,
        max: 120
      }
    }
  }
});

运行后你会发现,这些点几乎沿着一条上升的线分布,说明广告投入和销售额之间存在显著正相关。这为公司制定下一年的营销预算提供了有力依据。

小结与建议

Chart.js 散点图不仅美观,更是一种强大的数据洞察工具。它把抽象的数据变成了可视化的“故事”,让非技术人员也能理解复杂的关系。

从引入库到配置坐标轴,再到添加趋势线,每一步都值得反复练习。建议你:

  • 从简单的数据开始,逐步增加点的数量
  • 尝试不同的颜色、大小和透明度,找到最清晰的视觉表达
  • 在真实项目中应用,比如分析用户活跃度与留存率、设备性能与响应时间等

记住,图表不是为了“好看”而存在,而是为了“说清事实”。当你用 Chart.js 散点图发现某个隐藏规律时,那种成就感,是代码和数据共同带来的真实回报。

掌握它,你就多了一双“数据之眼”。