d3.js如何根据对象子列表选择元素?

时间:2015-07-07 05:23:00

标签: javascript d3.js

我有一个巨大的层次结构作为输入数据。我使用(仅) d3.js 库管理可视化。在另一个视图旁边,我显示了一个数据表。 我需要根据事件修改行。

在下面的示例中,我想着色与所点击节点的子树相对应的

http://jsfiddle.net/dqpwgvmk/2/

var dataIN =
    {"name":"R","value":0,"children":[
     {"name":"F","value":42,"children":[]},
     {"name":"K","value":0,"children":[
      {"name":"H","value":10,"children":[
       {"name":"E","value":6,"children":[]},
       {"name":"D","value":4,"children":[]}
      ]},
      {"name":"J","value":0,"children":[
       {"name":"I","value":0,"children":[
        {"name":"C","value":3,"children":[]},
        {"name":"G","value":5,"children":[
         {"name":"B","value":2,"children":[]},
         {"name":"A","value":8,"children":[]}
        ]}
       ]}
      ]}
     ]}
    ]};
var nodes = d3.layout.treemap().nodes(dataIN);

/*create table*/
d3.select("body").append("table")
  .selectAll("tr").data(nodes).enter().append("tr")
  .attr("class",function(d){return "n"+d.name+"-"+d.value;})
  .attr("title",function(d){return d.name;})
  .selectAll("td").data(["name","value","button"]).enter().append("td")
    .attr("class",function(d){return d;});
//fill name
d3.selectAll(".name").data(nodes)
  .text(function(d){return d.name;});
//fill value
d3.selectAll(".value").data(nodes)
  .text(function(d){return d.value;});
//fill button
d3.selectAll(".button").data(nodes)
  .append("button").text("subtree")
  .on("click",function(d){return color(d);});

/*getsubtree*/
function getSubtree(n,ns) {
//get a list of all nodes in subtree of n, n included
 if(n.children) {
   n.children.forEach(function(c){
     ns = getSubtree(c,ns); 
   }); 
 }
 ns.push(n);
 return ns;
}

/*color*/
function color(n) {
    //reset
    d3.selectAll("tr").style("background-color","");
    //set
    var sub = getSubtree(n,[]);
    console.log("sub",sub);
    sub.forEach(function(d){
        d3.select(".n"+d.name+"-"+d.value)
          .style("background-color","#800080");
    });
}

我没有找到一个“短路”来用d3.js选择一个节点的所有后代。如你所见,我的DOM元素是“tr”,所以是平面列表。

为了解决这个问题,我的方法是“从数据中过滤”节点(带有层次结构)。 然后“选择对应的DOM元素”。

以下示例有效。我通过递归我的数据树中的walk来列出子树的节点。然后选择每个相应的DOM元素。

我的问题是在数据量很大的情况下,d3.select()循环中的sub.forEach()需要多次。

调查d3.select().filter()d3.select().data(values,Key()),但我找不到根据节点列表过滤DOM元素的解决方案。

d3有办法吗?

谢谢Maxime HEBRARD

0 个答案:

没有答案