
本文详解 chart.js 中向两个折线图每秒添加实时数据时常见的 cannot read properties of undefined (reading 'push') 错误原因及两种可靠修复方案,涵盖数据结构匹配、数组索引访问和配置一致性要点。
本文详解 chart.js 中向两个折线图每秒添加实时数据时常见的 cannot read properties of undefined (reading 'push') 错误原因及两种可靠修复方案,涵盖数据结构匹配、数组索引访问和配置一致性要点。
在使用 Chart.js 实现双图表实时数据可视化时(例如每秒推送传感器读数),一个常见错误是直接调用 myChart.data.datasets.data.push() 导致运行时异常:Uncaught TypeError: Cannot read properties of undefined (reading 'push')。根本原因在于 datasets 始终是一个数组(即使仅含一个数据集),而错误写法将其误当作普通对象访问。
✅ 正确做法一:通过索引访问数据集(推荐)
Chart.js 的 data.datasets 是数组类型,每个元素为一个数据集对象。因此,必须使用下标 [0] 明确指定首个(或对应)数据集:
function addData(label, data0, data1) {
// 向第一个图表添加标签和 WEIGHT 数据
myChart0.data.labels.push(label);
myChart0.data.datasets[0].data.push(data0); // ✅ 正确:datasets[0].data
// 向第二个图表添加标签和 SENSOR-1 数据
myChart1.data.labels.push(label);
myChart1.data.datasets[0].data.push(data1); // ✅ 正确:datasets[0].data
// 触发重绘
myChart0.update();
myChart1.update();
}
⚠️ 注意:若后续扩展为多数据集(如一个图表显示多个传感器),可按需使用 datasets[1]、datasets[2] 等索引精确控制。
✅ 正确做法二:修改初始化配置(不推荐,易引发兼容性问题)
另一种方式是将 datasets 改为单个对象(而非数组),但这违反 Chart.js 官方 API 规范(v3+ 强制要求 datasets 为数组),且可能导致插件失效、响应式异常或未来版本兼容问题,仅作原理理解参考:
// ❌ 不推荐:破坏 Chart.js 标准结构
const plotData0 = {
labels: [],
datasets: { // ← 错误:应为数组,如 [{ ... }]
data: [],
label: "WEIGHT",
borderColor: 'red',
borderWidth: 2,
tension: 0,
fill: false
}
};
? 补充建议与最佳实践
- 数据长度同步:确保 labels 与各 datasets[0].data 长度一致,否则图表渲染异常;
-
性能优化:高频更新(如每秒多次)时,可限制标签数量(如保留最近 60 秒数据),避免内存膨胀:
if (myChart0.data.labels.length > 60) { myChart0.data.labels.shift(); myChart0.data.datasets[0].data.shift(); } - Chart.js 版本注意:本文示例基于 Chart.js v3.x;若使用 v2.x,options.scales.yAxes 写法正确,但 v3+ 应改用 options.scales.y —— 请根据实际版本调整配置;
- 错误调试技巧:在控制台打印 console.log(myChart0.data.datasets) 可直观确认其结构(必为数组)。
通过修正数据访问路径,你即可稳定实现双图表毫秒级同步刷新,为工业监控、IoT 仪表盘等场景提供可靠可视化支撑。











