D3.js使用多个键汇总嵌套运算符

Pao*_*ola 11 javascript d3.js

我正在为时间报告应用程序开发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来解决这个问题的任何建议?

Žil*_*nis 5

来自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)