我有一个嵌套的数据数组,我用它来创建一个分组的条形图。我无法为嵌套数组的datajoin分配密钥。
下面是输入数据,顶层的工作数据连接,以及我想要完成的两个部分实现。我很亲密!
// input data
var data = [
{"key":"cat1","value":[{"key":"subcatA","value":100},{"key":"subcatB","value":200}]},
{"key":"cat2","value":[{"key":"subcatA","value":150},{"key":"subcatB","value":250}]}
];
要访问顶级并构建主要类别,请执行以下操作:
// top level (all good)
var plot = d3.select('#plot');
plot.selectAll(".category")
.data(data,function(d) {return d.key;}) // <-- return key on datajoin
.enter().append("g")
.attr("class", "category")
在datajoin上返回d.key
会跟踪每个类别,使得enter()和exit()不是一大堆动画。有关向数据连接添加密钥的参考信息,请参阅Mike Bostock的General Update Pattern, II。
要绘制第二级,我会这样做:
// second level (plots but no key is assigned)
plot.selectAll(".category").selectAll(".bar")
.data(function (d) {return d.value; }) // <-- is this right?
.enter().append("rect")
.attr("class","bar")
没有分配密钥,因此d3相当随机地处理更新。如果我这样做,我可以得到我想要的第一次迭代:
// second level (key is assigned but first iteration only)
plot.selectAll(".g-category").selectAll(".bar")
.data(data[0].value, function (d) {return d.key; }) // <-- first category only
.enter().append("rect")
.attr("class","bar")
完美除了我需要迭代data
,而不只是data[0]
。我的问题是,一旦我尝试,我就会与d3.selectAll
发生利益冲突并使事情陷入混乱。
这个问题的答案可能很简单,但我错过了:如何在d3中正确选择和分配嵌套数组的键?
答案 0 :(得分:2)
第二级中的数据方法只有一个参数:
.data(function (d) {
return d.value;
});
要分配键功能,您必须传递第二个参数。例如:
.data(function(d) {
return d.value
}, function(d) {
return d.key
});
你可以在一行中更好地看到它:
.data(function(d) { return d.value }, function(d) { return d.key });
//2nd arg after the comma ----------^
但是,为了方便人类阅读,我建议你为1级和2级使用不同的属性名称。现在一切都是value
和key
,这很难理解(但不是为了机器。例如,在上面的代码片段中,value
指的是第一级数组,而key
指的是第二级数组,而不是第一级数组......你看到这个混乱吗?
以下是您的数据演示:
var data = [{
"key": "cat1",
"value": [{
"key": "subcatA",
"value": 100
}, {
"key": "subcatB",
"value": 200
}]
},
{
"key": "cat2",
"value": [{
"key": "subcatA",
"value": 150
}, {
"key": "subcatB",
"value": 250
}]
}
];
var body = d3.select("body");
var outer = body.selectAll(null)
.data(data, function(d) {
return d.key
})
.enter()
.append("div")
.attr("class", "outer");
var inner = outer.selectAll(null)
.data(function(d) {
return d.value
}, function(d) {
console.log("the key is: " + d.key)
return d.key
})
.enter()
.append("div")
.html(function(d) {
return d.key + " - " + d.value
});
<script src="https://d3js.org/d3.v4.min.js"></script>