D3を使用して複数のネストされていない要素を作成し、次のような構造を作成したいと思います。
<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>
ネスト構造を作成すると、次のようになります
d3.select('#parent').selectAll('p').data(data).enter().
append('p')...append('p')
しかし、追加後も元の選択を維持したいので、親要素に追加し続けることができます。ありがとうございました!
isネスティングを使用した理想的な方法:
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>
それでも機能しない場合は、選択内容を保存して繰り返し追加します。
var enterSelection = d3.select('#parent').selectAll('p').data(data).enter();
enterSelection.append('p')
enterSelection.append('p')
次に、追加したものをソートします。
d3.select('#parent').selectAll('p').sort(function(a, b){ return a.index - b.index; })
ソート順序を説明するindex
の各要素にdata
プロパティを追加する必要があります。通常のi
は特定の選択のコンテキストでのみ定義され、再選択すると失われます。
最初のアイテムにはappend()
を使用し、2番目のアイテムにはinsert()
を使用します。これにより、後でソートする必要がなくなります(これを指摘してくれた@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>
次のように、単一の選択/入力サイクルでこれを行うこともできます
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()
に新しいコンテンツを作成する関数をラップすることもできます
d3.select('#parent')
.selectAll('div')
.data(data)
.enter()
.append('div')
.html(function(d) {return "<p>" + from data[0] + "<p>" etc..... ;});
上記と似ていますが、異なるイディオムです。これは、ネストされた選択アプローチに忠実であり、ソートまたは挿入の必要性を排除します。
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)); });