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

时间:2012-11-01 21:16:53

标签: javascript d3.js

我正在为时间报告应用程序开发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

进行处理的任何建议

1 个答案:

答案 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 
}