d3嵌套选择:如何访问数组数据 [英] d3 nested selection : how to access array data
问题描述
我已经看过很多类似的帖子在这里关于嵌套的选择,但我没有成功将问题转移到我的情况。
我希望这可以作为一个单独的问题。
我有:
嵌套的json结构,代表一个系统发育树
{
name:Sauria,
children:[
{
domains:[
{
name:BRCA2,
domain_start:100,
domain_stop:240
}
],
common_name:NaN,
seq_length:200,
duplication:N,
name: ENSMGAP00000010132,
class:leaf,
bootstrap:NaN,
taxon:Meleagris_gallopavo
},
{
domains:[
{
name:BRCA2,
domain_start:100,
domain_stop:240
} b $ b],
common_name:NaN,
seq_length:200,
duplication:N,
name:ENSACAP00000006049 ,
class:leaf,
bootstrap:NaN,
taxon:Anolis_carolinensis
}
] bbootstrap:15,
taxon:null,
common_name:NaN
要获取所有节点并绑定我的数据,我会
var node = d3.select #tree svg)。selectAll(g.node)。data(nodes,function(d){return d.id || (d.id = ++ i); });然后我使用向每个节点添加组。
pre> var nodeEnter = node.enter()。append(svg:g)
.attr(class,node)
.attr transform,function(d){returntranslate(+ source.y0 +,+ source.x0 +);});
我为每个叶子绘制一个矩形如下
var div3 = nodeEnter.append(rect)
.attr(x,192)
.attr(y,160)
.attr(width,function(d){return d.children?:10;})
.attr(height,function(d){
return d.children?:domainOnlyScale(d.seq_length);
})
.attr(transform,function(d){return d.children?:rotate 100);})
.attr(fill,function(d){return d.children?:grey;});
现在棘手的事情。我想使用每个叶子的域中的数据绘制矩形上的东西,因此这部分
:[
{
name:BRCA2,
domain_start:100,
domain_stop:240
}
]
我不知道如何迭代所有的叶子和domains数组的每个元素注意这个数组可以有几个条目)。所以当我尝试使用每个
div3.each(function(d){
[d.domains ] .each(function(dom){
d3.select(this)
.append(rect)
.attr(x,230)
.attr y,175)
.attr(rx,5)
.attr(ry,5)
。 12;})
.attr(height,function(d){
console.log(here we go again:+ d.name +has length:+ .seq_stop - d.domains.seq_start));
// var randomnumber = Math.floor(Math.random()* 11)
return dom.domain_start;
})
.attr(fill,function(d){return d.children?:red;})
})
});
d3告诉我Object [object Object]没有方法'each' d.domains是一个数组。
你能帮我访问这个嵌套的域信息吗?
非常感谢!
在嵌套选择中,您应该将嵌套数据作为参数传递给 data()
选择的函数。因此,不是 div3.each
,它看起来像这样。
div3.selectAll(rect)。data(function(d){return d.domains;})enter()
.append(rect)
... $ b b
您应该可以使用其他代码保持不变。
I have had a look at many similar posts here about nested selections, but I wasn't successful transferring the problem to my case. I hope it's ok to ask this as a separate question.
I have: nested json structure that represents a phylogenetic tree (with species)
{
"name" : "Sauria",
"children" : [
{
"domains" : [
{
"name" : "BRCA2",
"domain_start" : 100,
"domain_stop" : 240
}
],
"common_name" : "NaN",
"seq_length" : 200,
"duplication" : "N",
"name" : "ENSMGAP00000010132",
"class" : "leaf",
"bootstrap" : "NaN",
"taxon" : "Meleagris_gallopavo"
},
{
"domains" : [
{
"name" : "BRCA2",
"domain_start" : 100,
"domain_stop" : 240
}
],
"common_name" : "NaN",
"seq_length" : 200,
"duplication" : "N",
"name" : "ENSACAP00000006049",
"class" : "leaf",
"bootstrap" : "NaN",
"taxon" : "Anolis_carolinensis"
}
],
"bootstrap" : "15",
"taxon" : null,
"common_name" : "NaN"
To get all nodes and bind my data I do
var node = d3.select("#tree svg").selectAll("g.node").data(nodes, function(d) { return d.id || (d.id = ++i); });
Then I add groups to each node using
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; });
I draw a rectangle for each leaf like this
var div3 = nodeEnter.append("rect")
.attr("x", 192)
.attr("y", 160)
.attr("width", function(d){return d.children ? "":"10";})
.attr("height", function(d){
return d.children ? "": domainOnlyScale(d.seq_length);
})
.attr("transform", function(d){return d.children ? "":"rotate(-90 100 100)";})
.attr("fill", function(d){return d.children ? "":"grey";});
Now the tricky thing. I would like to draw something onto the rectangle using the data in "domains" that each leaf has, so this part
"domains" : [
{
"name" : "BRCA2",
"domain_start" : 100,
"domain_stop" : 240
}
],
I simply don't know how to iterate over all leaves and over each element of the domains array (note that this array can have several entries). So when I try to use "each"
div3.each(function(d) {
[d.domains].each(function(dom){
d3.select(this)
.append("rect")
.attr("x", 230)
.attr("y", 175)
.attr("rx", 5)
.attr("ry", 5)
.attr("width", function(d){return "12";})
.attr("height", function(d){
console.log("here we go again: "+d.name+" has length: "+(d.domains.seq_stop - d.domains.seq_start));
//var randomnumber=Math.floor(Math.random()*11)
return dom.domain_start;
})
.attr("fill", function(d){return d.children ? "":"red";})
})
});
d3 tells me that "Object [object Object] has no method 'each' ", but I though d.domains was an array.
Can you help me to access this nested "domain" information?
Thanks a lot!
In a nested selection, you should pass the nested data as an argument to the data()
function of a selection. So instead of doing div3.each
, it would look something like this.
div3.selectAll("rect").data(function(d) { return d.domains; }).enter()
.append("rect")
...
You should be able to use the rest of the code unchanged.
这篇关于d3嵌套选择:如何访问数组数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!