d3嵌套选择:如何访问数组数据 [英] d3 nested selection : how to access array data

查看:155
本文介绍了d3嵌套选择:如何访问数组数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过很多类似的帖子在这里关于嵌套的选择,但我没有成功将问题转移到我的情况。
我希望这可以作为一个单独的问题。



我有:
嵌套的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆