2014-06-10 136 views
0

我在尝试使用d3嵌套jQuery手风琴时遇到了令人沮丧的问题。这个问题似乎从看似无力阻止试图创建HTML结构像下面,递归,并使用D3的巢和数据绑定机制(或至少难度):使用d3嵌套jQuery手风琴

<div> 
    <h1>  // accordion 1 header 
    <div>  // accordion 1 content 
     <h1>   // nested accordion header 
     <div>   // nested accordion content    
     </div> 
    </div> 
    <h1>  // accordion 2 header 
    <div>  // accordion 2 content 
    </div> 
</div> 

D3的方法我已经失败试过迄今是基于以下的,非手风琴友好,嵌套/绑定代码:

var nest = d3.nest() 
      .key(//someFun) 
      .key(//someFun) 
      ... // undetermined number of keys 
      .entries(someData); 

d3.select(someNode) 
      .selectAll("div") 
       .data(nest) 
       .enter() 
       .append("div") 
       .html(htmlFun[0]) 
      .selectAll("div") 
       .data(function(d){return d.values}) 
       .enter() 
       .append("div") 
       .html(htmlFun[1]) 
      .selectAll("div") 
       .data(function(d){return d.values}) 
       .enter() 
       .append("div") 
       .html(htmlFun[2]) 
         ... // repeat for each key 

其中“hmtlFun”是函数的预先计算的阵列,以产生用于给定嵌套级关键内容。此代码适用于生成html结构,如

<div> 
    <div> 
     <div>      
     </div> 
    </div> 
</div> 

但jQuery Accordion需要在每个div下包含混合/交错元素的基本html短语,例如,

<div> 
    <h1> 
    <div/> 

    <h1> 
    <div/> 

    ... 

</div> 

我知道下面将无法正常工作,但我很想能够做到像:

d3.select(someNode) 
      .selectAll("div") 
       .data(nest) 
       .enter() 
       .append("div") 
       .each(function(d) { 
        d3.select(this).append("h1") 
         .text(htmlFun[0]); 
        d3.select(this).append("div") 
       }) 
      .selectAll("div") 
       .data(function(d){return d.values}) 
       .enter() 
       .append("div") 
       .each(function(d) { 
        d3.select(this).append("h1") 
         .text(htmlFun[1]); 
        d3.select(this).append("div") 
       }) 
      .selectAll("div") 
       .data(function(d){return d.values}) 
       .enter() 
       .append("div") 
       .each(function(d) { 
        d3.select(this).append("h1") 
         .text(htmlFun[2]); 
        d3.select(this).append("div") 
       }) 
         ... // repeat for each key 
      .selectAll("div") 
       .data(function(d){return d.values}) 
       .enter() 
       .append("div") 
       // at bottom of key recursion append leaf content 

任何帮助/建议(与解决方案)中不胜感激提前:^)

+0

@isherwood:我真的可以在小学里用你的帮助!日Thnx。 – jb1

+0

这将有助于查看要绑定到此层次结构的一些数据。这一切都有点理论。这应该很容易实现:D3的圆形打包和四叉树都使用递归概念。 –

回答

2

对于任何感兴趣的人,这里有一个基于深度优先遍历的工作解决方案,nestDFT(不包括),它在遍历期间遇到的每个嵌套节点上调用nestNodeFilter。有一点需要注意,d.unid指的是在运行nestDFT之前为每个嵌套节点生成的唯一节点标识。

function nestNodeFilter(rootDiv, d){ 
     var node  = d, 
      container = d3.select(rootDiv); 
     if(h==0 && d.values == undefined){ // nest root 
     } else if(d.values != undefined && Array.isArray(d.values)) { 
      node  = d.values; 
      container = d3.select('#div_'+d.unid); 
     } else if(!Array.isArray(d.values)){ 
      // generate leaf content at bottom of nest 
      return 
     } 
     node.forEach(function(d){ 
      this.append("h1") 
       .attr('id','h1_'+d.unid) 
       .text(accordFuns[h](d)); 
      this.append("div") 
       .attr('id','div_'+d.unid); 
     }, container); 
    });