我正在为时间报告应用程序开发d3.js可视化。 我在包含项目时间报告(简化)的数组 actuals 中有行数据:
[{ resource: "John Smith",
reporting_period: "2012/04/1",
project: "Java implementation",
hours: 8}
... }]
我正在尝试使用 d3.nest 运算符按项目,资源和期间按层次结构分组项目实际值。一切都很好但我找不到使用 nest.rollup()运算符在分组的中间级别获取小时小计的方法。
我有类似的东西:
actuals_by_prj_rsrc_period = d3.nest()
.key(function(d) { return d["project"]; })
.key(function(d) { return d["resource"]; })
.key(function(d) { return d["reporting_period"]; })
.rollup(function(rows) {return {
tot_hours:d3.sum(rows, function(d) {return d["hours"];}),
actuals: rows
};})
.entries(actuals);
但它仅在叶级别返回 tot_hours 。 关于如何仅使用 d3.nest ?
进行处理的任何建议答案 0 :(得分:5)
来自docs:
nest.rollup(功能)
指定要应用于 leaf 的每个组的汇总函数 元素。汇总函数的返回值将替换 由...返回的关联数组中的叶值数组 map运算符,或者返回的每个条目的values属性 条目运营商。
正如您所见,汇总与叶元素一起使用。你可以通过将数据嵌套在多个级别来绕过这个:
function nest(keys, data, rollupFunc) {
var nst = d3.nest();
keys.forEach(function(key) {
nst.key(function(d) { return d[key]; });
});
if (rollupFunc) {
nst.rollup(rollupFunc);
}
return nst.entries(data);
}
var rollupFunction = function(d) {
return {
"total_hours": d3.sum(d, function(dd) { return dd["hours"]})
}
}
var rez1 = nest(["project", "resource"], actuals);
var rez2 = nest(["project"], actuals, rollupFunction);
var rez3 = nest(["project", "resource"], actuals, rollupFunction);
但对于较大的数据集来说,效率非常低。否则我建议使用nest()
函数来创建所有中间级别。然后,您可以使用自己的递归函数聚合总小时数。伪代码:
function aggregate(node) {
if (node has property total_hours) {
return total_hours
}
sum = 0
foreach child in data.values {
sum += aggregate(child)
}
node.total_hours = sum
return node.total_hours
}