我在尝试使用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
我们非常感谢任何帮助/建议(与解决方案相关):^)
答案 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);
});