我正在为时间报告应用程序开发d3.js可视化.我在包含项目时间报告的数组实际中有行数据(简化):
[{ resource: "John Smith",
reporting_period: "2012/04/1",
project: "Java implementation",
hours: 8}
... }]
Run Code Online (Sandbox Code Playgroud)
我试图使用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);
Run Code Online (Sandbox Code Playgroud)
但它仅在叶级返回tot_hours.关于如何仅使用d3.nest来解决这个问题的任何建议?
来自docs:
nest.rollup(功能)
指定要应用于每组叶 元素的汇总函数.汇总函数的返回值将替换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);
Run Code Online (Sandbox Code Playgroud)
但是对于较大的数据集来说这非常低效.否则我会建议使用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
}
Run Code Online (Sandbox Code Playgroud)