D3 stack()vs嵌套对象

时间:2017-02-04 10:54:22

标签: d3.js

在尝试使用D3v4实现标准化堆叠条形图时,我遇到了问题 出现问题的原因是我的数据格式包含在服务器端动态填充的嵌套对象数组。

var data = [{x:"data1", y:[{name:"red", value:10}, {name:"green", value:20}]},
            {x:"data2", y:[{name:"red", value:30}, {name:"green", value:5}]}];

对此调用d3.stack()将不起作用,因为d3不知道如何遍历对象数组y。 (https://jsfiddle.net/xv1qgqjg/
有没有办法告诉d3.stack()哪里可以找到与其他地方使用的.data(function(d){ return d.y; })类似的相关数据?

1 个答案:

答案 0 :(得分:3)

似乎不可能。根据有关 stack(data [,arguments ...])的文档,

  

任何其他参数都是任意的;它们只是与此对象一起传播到访问器。

因此,您必须更改数据,创建一个可以传递给d3.stack()的数组,例如:

[{red:10,green:20},
{red:30,green:5}]

鉴于您的问题中的数据数组,有几种方法可以创建上述数组。这是我的解决方案(新数组称为newData):

newData = [];

data.forEach(d => {
    var tempObj = {}
    d.y.forEach(e => {
        tempObj[e.name] = e.value;
    })
    newData.push(tempObj);
});

这是一个演示:

var data = [{x:"data1", y:[{name:"red", value:10}, {name:"green", value:20}]},
            {x:"data2", y:[{name:"red", value:30}, {name:"green", value:5}]}];

newData = [];

data.forEach(d => {
    var tempObj = {}
    d.y.forEach(e => {
        tempObj[e.name] = e.value;
    })
    newData.push(tempObj);
});

var stack = d3.stack()
    .keys(["red", "green"])
    .order(d3.stackOrderNone)
    .offset(d3.stackOffsetExpand);

var series = stack(newData);
console.dir(series);
<script src="https://d3js.org/d3.v4.min.js"></script>