D3堆叠柱状图异常求助:某日期出现堆叠重复问题
你的堆叠柱状图重复堆叠问题分析与修复
看起来你的堆叠柱状图在特定日期出现重复堆叠的问题,大概率就是这段reduce代码里的几个细节问题导致的,我帮你拆解并修复:
代码里的核心问题
直接引用原始对象导致的潜在异常
当遇到新日期时,你直接把原始obj推入dataset并赋值给res[key]。这意味着后续对res[key]的字段修改会直接改动dataset里的对象——如果原始obj缺少某些uniq_enames中的字段,这些字段会以undefined存在,后续累加时会变成NaN,这会让图表计算堆叠高度时出错,表现为看似重复的堆叠。未初始化所有目标字段
新日期对应的对象直接使用原始obj,如果原始数据里的条目没有包含所有uniq_enames的字段,缺失字段没有初始值,累加时会出现undefined + 数值 = NaN的情况,这是图表数据错乱的常见诱因。全局变量
i导致循环异常
你的for循环里的i没有用var/let/const声明,会变成全局变量。如果页面其他代码也用到i,会干扰这个循环的执行,导致部分字段未被正确累加,最终图表表现异常。
修复后的代码
var dataset = []; data.reduce(function(res, obj) { var key = obj.Date; // 初始化新日期的对象:包含Date和所有uniq_enames字段,初始值为0 if (!res[key]) { var newEntry = { Date: key }; uniq_enames.forEach(function(name) { newEntry[name] = 0; }); res[key] = newEntry; dataset.push(newEntry); } // 累加当前obj的字段值,处理obj中字段不存在的情况 uniq_enames.forEach(function(name) { res[key][name] += (obj[name] || 0); }); return res; }, {});
修复说明
- 每次遇到新日期时,创建全新的对象,并将所有
uniq_enames字段初始化为0,彻底避免字段缺失或引用原始数据的问题。 - 累加时用
(obj[name] || 0)处理原始obj中可能没有该字段的情况,确保不会出现NaN。 - 用
forEach替代普通for循环,避免全局变量i的干扰(如果习惯用for循环,记得加上let i声明局部变量)。
如果修复后仍有异常,可以检查原始data里对应日期的条目是否有格式问题,比如日期字符串不一致(例如'2024-01-01'和'2024/01/01'会被识别为不同的key)。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

