
本文详解如何将来自数据库的扁平化 json 数据(含多个 order 分组、统一日期序列)自动分组、重构为 chart.js 所需的多数据集格式,并实现动态渲染与图表更新。
本文详解如何将来自数据库的扁平化 json 数据(含多个 order 分组、统一日期序列)自动分组、重构为 chart.js 所需的多数据集格式,并实现动态渲染与图表更新。
在使用 Chart.js 展示项目工时趋势时,后端常返回类似以下结构的扁平化数组:每个对象包含 DATE、HOURS 和 ORDER 字段,不同订单(ORDER)的数据按时间混排,但所有订单共享完全一致的日期范围(如 2023-04-09 至 2023-04-11)。手动为每个 ORDER 创建独立数组(如 HOURS1, HOURS2)虽可行,却无法应对动态订单数量——这正是本教程要解决的核心问题。
✅ 正确的数据重组逻辑
关键在于:不依赖动态变量名(如 window['HOURS' + i]),而是构造符合 Chart.js datasets 格式的数组对象列表。推荐使用 Array.reduce() 或 Map 进行高效分组:
// 步骤 1:提取唯一 ORDER 列表与标准化日期标签(确保顺序一致)
const uniqueOrders = [...new Set(data.map(item => item.ORDER))];
const dateLabels = [...new Set(data.map(item => item.DATE))].sort(); // 按日期升序排列
// 步骤 2:按 ORDER 分组并生成对应 HOURS 数组(严格对齐 dateLabels 顺序)
const datasets = uniqueOrders.map(order => {
// 为当前 ORDER 构建按 dateLabels 顺序排列的 HOURS 值数组
const hoursArray = dateLabels.map(date => {
const record = data.find(item => item.ORDER === order && item.DATE === date);
return record ? parseFloat(record.HOURS) || 0 : 0; // 安全转换,缺失值补 0
});
return {
label: `ORDER ${order}`,
data: hoursArray,
borderColor: `hsl(${Math.random() * 360}, 70%, 60%)`,
backgroundColor: `hsla(${Math.random() * 360}, 70%, 60%, 0.1)`,
fill: false,
tension: 0.3
};
});? 构建完整 Chart.js 配置
将上述 datasets 与日期标签组合,即可直接用于初始化或更新图表:
const config = {
type: 'line',
data: {
labels: dateLabels, // 如 ['2023-04-09', '2023-04-10', '2023-04-11']
datasets: datasets // 上一步生成的动态数据集数组
},
options: {
responsive: true,
plugins: {
title: { display: true, text: '各订单工时趋势' }
}
}
};
// 初始化图表
const ctx = document.getElementById('myChart').getContext('2d');
const chart = new Chart(ctx, config);⚠️ 注意事项与最佳实践
- 日期对齐是关键:务必先提取并排序 dateLabels,再为每个 ORDER 按此顺序查找对应 HOURS,否则 X 轴数据错位;
- 避免浮点精度陷阱:parseFloat() 可处理字符串数字(如 '1.8'),但需检查 null/undefined 并提供默认值(如 0);
-
更新已有图表:若需动态刷新数据(如切换项目),请勿重新创建 Chart 实例,而应:
chart.data.labels = dateLabels; chart.data.datasets = datasets; chart.update('active'); // 触发重绘,'active' 模式支持动画 - 性能优化:对大数据量,建议用 Map 预处理索引(Map<ORDER, Map<DATE, HOURS>>),避免嵌套循环中的重复 find();
通过该方法,无论数据库返回 2 个还是 200 个不同 ORDER,代码均能自动生成结构正确、顺序一致、样式可定制的 Chart.js 数据集,真正实现“一次编写,动态适配”。


















