用D3.js为每个数据成员附加多个非嵌套元素

我想用d3创build多个非嵌套元素来创build一个像这样的结构:

<div id="parent"> <p> from data[0] </p> <p> from data[0] </p> <p> from data[1] </p> <p> from data[1] </p> <p> from data[2] </p> <p> from data[2] </p> </div> 

创build嵌套结构会像这样

  d3.select('#parent').selectAll('p').data(data).enter(). append('p')...append('p') 

但我想保持原来的select,即使在追加,所以我可以继续追加到父元素。 谢谢!

这种习惯性的做法嵌套:

 var divs = d3.select('#parent').selectAll('p').data(data).enter().append('div'); divs.append('p') divs.append('p') 

这创造:

 <div id="parent"> <div> <p> from data[0] </p> <p> from data[0] </p> </div> <div> <p> from data[1] </p> <p> from data[1] </p> </div> <div> <p> from data[2] </p> <p> from data[2] </p> </div> </div> 

如果这不起作用,请保存您的select并反复附加:

 var enterSelection = d3.select('#parent').selectAll('p').data(data).enter(); enterSelection.append('p') enterSelection.append('p') 

然后对你添加的内容进行sorting:

 d3.select('#parent').selectAll('p').sort(function(a, b){ return a.index - b.index; }) 

您需要将index属性添加到描述sorting顺序的每个data元素。 正常的i只是在一个特定select的背景下定义的,当我们重新select的时候这个select是丢失的。

第一个项目使用append() ,第二个使用insert() 。 这消除了任何需要后来sorting(感谢@ scuerda的评论指出这一点)( JSFiddle ):

 data = [{}, {}, {}]; var enterSelection = d3.select('#parent').selectAll('p').data(data).enter() enterSelection.append('p').text(function(d, i) {return 'from data[' + i + ']'}) enterSelection.insert('p').text(function(d, i) {return 'from data[' + i + ']'}) 

这将给你所要求的确切结构:

 <p>from data[0]</p> <p>from data[0]</p> <p>from data[1]</p> <p>from data[1]</p> <p>from data[2]</p> <p>from data[2]</p> 

您也可以在单个select/input循环中按如下所示进行操作

 d3.select('#parent').selectAll('p').data(data).enter(). append('p').text(function(d) {return 'from data[0]')}). select(function() { return this.parentNode; }). append('p').text(function(d) {return 'from data[0]')}); 

而不是.append()

你也可以在.html()包装一个创build新内容的函数。

 d3.select('#parent') .selectAll('div') .data(data) .enter() .append('div') .html(function(d) {return "<p>" + from data[0] + "<p>" etc..... ;}); 

与上面类似,但用不同的习语。 这对于嵌套select方法更加真实,并且不需要sorting或插入:

 var divs = d3.select('#parent'); var ps = divs.selectAll('#parent > div') .data(d3.range(3)).enter().append('div'); ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; }); ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; }); 

更优雅(可能更快):

 var divs = d3.select('#parent'); var ps = divs.selectAll('#parent > div') .data(d3.range(3)).enter().append('div'); ps.append('p').html(function(d,i) { return 'from data[' + i + ']'; }) .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); });