
本文详解如何在 chart.js 的 scatter 图表中,为每个数据点(dot)按其 y 值区间(如 y ≤ 0、0 4)动态分配不同背景色,通过预计算颜色数组并赋值给 `backgroundcolor` 实现精准着色。
在 Chart.js 中,散点图(type: 'scatter')的数据点默认使用统一颜色。若需实现「颜色随数值变化」的视觉编码(例如:负值标红、低正值标蓝、高值标紫),关键在于将 backgroundColor 属性设为与数据点一一对应的颜色数组,而非单一字符串。
Chart.js 会自动将该数组中的每个颜色项映射到 data 数组中对应索引的数据点上——这是实现条件着色最简洁、高效的方式。
✅ 正确实现步骤
- 准备原始数据(如站点与对应数值);
- 基于 y 值生成颜色数组:使用 .map() 遍历数据,根据业务逻辑返回对应颜色;
- 将颜色数组传入 dataset.backgroundColor;
- 确保 x 轴类型为 'category' 并显式传入 labels(因散点图默认不自动解析字符串 x 值为分类轴)。
以下是完整可运行示例:
<canvas id="myChart" width="400" height="200"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('myChart');
const request = [
{ x: 'Station1', y: 5 },
{ x: 'Station2', y: 2 },
{ x: 'Station3', y: 1 },
{ x: 'Station4', y: 8 },
{ x: 'Station5', y: 7 },
{ x: 'Station6', y: -2 },
{ x: 'Station7', y: 10 },
{ x: 'Station8', y: 0 }
];
// 提取 x 轴标签
const labels = request.map(e => e.x);
// 动态生成颜色数组:严格按 request 顺序一一对应
const colors = request.map(e => {
if (e.y <= 0) return '#ff6384'; // 红色:≤ 0
else if (e.y <= 4) return '#36a2eb'; // 蓝色:0 < y ≤ 4
else return '#cc65fe'; // 紫色:> 4
});
new Chart(ctx, {
type: 'scatter',
data: {
labels: labels, // 必须提供,否则 category x 轴无法渲染
datasets: [{
label: 'Day to posts',
data: request,
backgroundColor: colors, // ✅ 核心:颜色数组
borderColor: '#999',
borderWidth: 1,
pointRadius: 6,
pointHoverRadius: 8
}]
},
options: {
responsive: true,
scales: {
x: {
type: 'category',
labels: labels // 显式声明 labels(与 data.labels 一致)
},
y: {
beginAtZero: false
}
},
plugins: {
legend: { display: true }
}
}
});
</script>⚠️ 注意事项
- backgroundColor 必须是数组:长度需与 data 数组完全一致,否则 Chart.js 会静默忽略或报错;
- 避免在 options 中配置颜色逻辑:backgroundColor 属于 dataset 配置项,不可放在 options.plugins.* 或 scales 中;
- 散点图 + 分类 X 轴需双 labels:data.labels 和 scales.x.labels 均需设置,否则横坐标显示异常;
- 扩展性建议:可将颜色逻辑封装为函数(如 getColorByValue(y)),便于复用和单元测试;
- 无障碍友好:搭配 pointStyle: 'circle'(默认)及足够对比度颜色,确保色觉障碍用户仍能区分趋势。
通过此方案,你不仅能实现多区间条件着色,还可轻松扩展为渐变色、阈值图标、甚至结合 borderColor 实现双色编码(如填充色表数值区间,边框色表异常状态)。图表语义表达力与专业度将显著提升。


















