user4815162342 user4815162342 - 1 month ago 13
Javascript Question

Appending multiple non-nested elements for each data member with D3.js

I would like to create multiple non-nested elements using d3 to create a structure like this:

<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>


creating nested structures would go something like

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


but I would like to maintain the original selection even after the append, so I could continue appending to the parent element. Thank you!

Answer

The idomatic way of doing is with nesting:

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

divs.append('p')
divs.append('p')

Which creates:

<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>

If that won't work, save your selection and repeatedly append:

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

enterSelection.append('p')
enterSelection.append('p')

then sort what you've added:

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

You'll need to add an index property to each element of data that describes the sort order. The normal i is only defined in the context of a particular selection, which is lost when we reselect.