D3 - 尝试基于元素名称而不是值进行嵌套

时间:2014-03-03 19:00:20

标签: d3.js

我不确定这是否可行,但我尝试创建一个d3.nest对象,其中键是元素名称而不是该元素的值。这将用于堆积区域图表。

以下是原始数据示例:

{
        "_id" : {
                "month" : 2,
                "day" : 26,
                "year" : 2014
        },
        "total" : 34492,
        "failed" : 1,
        "skipped" : 0
}

我想根据total,failed和skipped元素名称创建一个nest对象,而不是它们的值(即:不是数字)。

生成的嵌套对象类似于:

[
    {
        key: "total",
        values: [
            {
                "date": "2014-02-26T05:00:00.000Z",
                "count": 34492
            },
            {
                "date": "2014-02-27T05:00:00.000Z",
                "count": 34495
            } 
        ]
    },
    {
        key: "failed",
        values: [
            {
                "date": "2014-02-26T05:00:00.000Z",
                "count": 1
            },
            {
                "date": "2014-02-27T05:00:00.000Z",
                "count": 0
            } 
        ]
    }
]

我可以控制原始数据的布局,所以我尝试在状态对象下添加total,failed和skipped元素,但这也没有用。

以下是我正在使用的一些代码:

data.result.forEach(function(d) {
    d.date = new Date(d._id.year, d._id.month-1, d._id.day);
    d.status = {
        "total": d.total,
        "failed": d.failed,
        "skipped": d.skipped
    };
});

var nested = d3.nest()
    .key(function(d) { return d.status; })
    //.key(function(d) { return d.total; })
    //.key(function(d) { return d.failed; })
    //.key(function(d) { return d.skipped; })
    .entries(data.result);

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这不是d3.nest的工作,但肯定可以做到。

如果要根据分组变量(或多个嵌套组)将长数组拆分为多个子数组,则使用嵌套函数。原始数组中的每个元素仅显示在其中一个子数组中。

你想要的是重复三次相同的数据对象数组,每次都提取不同的值。

从原始步骤开始解析Date值:

data.result.forEach(function(d) {
    d.date = new Date(d._id.year, d._id.month-1, d._id.day);
});

然后创建一个包含不同状态类型的数组,并将其作为单独的数据系列。你可以通过查看对象键从数据创建这个数组,但我在这里假设你知道选项应该是什么:

var statusTypes = ["total", "failed", "skipped"];

然后使用嵌套的array mapping functions

  1. 创建一个新数组,其中包含statusTypes数组中每个值的单独数据系列;和
  2. 对于每个数据系列,创建包含相应计数值的数据数组版本。
  3. 像这样:

    var dataSeries = statusTypes.map( function(type) {
    
              //for each type, create a mapped version of the data array
              return data.result.map( function(d) {
    
                          //for each entry in the data array,
                          //create a new data object based on the 
                          //specific type of count
                          return { date: d.date,
                                   count: d[type]
                                 };
                     } );
    
        });