使用d3嵌套的jQuery Accordions

时间:2014-06-10 19:15:42

标签: javascript jquery d3.js

我在尝试使用d3嵌套jQuery手风琴时遇到了令人沮丧的问题。这个问题似乎源于似乎无法(或至少是困难)尝试创建html结构,如下所示,递归地,并使用d3的嵌套和数据绑定机制:

<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

其中&#39; hmtlFun&#39;是一个preComputed函数数组,用于为给定的嵌套键级别生成内容。此代码适用于生成

等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

我们非常感谢任何帮助/建议(与解决方案相关):^)

1 个答案:

答案 0 :(得分:2)

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

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);
    });