it-swarm.com.de

Anhängen mehrerer nicht geschachtelter Elemente für jedes Datenelement mit D3.js

Ich möchte mehrere nicht geschachtelte Elemente mit d3 erstellen, um eine Struktur wie folgt zu erstellen:

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

das Erstellen verschachtelter Strukturen würde ungefähr so ​​aussehen

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

ich möchte jedoch die ursprüngliche Auswahl auch nach dem Anfügen beibehalten, damit ich das übergeordnete Element anhängen kann. Vielen Dank!

42
user4815162342

Die idomatische Art zu tun ist mit Verschachtelung:

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

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

Was schafft:

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

Wenn dies nicht funktioniert, speichern Sie Ihre Auswahl und fügen Sie sie wiederholt hinzu:

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

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

dann sortieren, was Sie hinzugefügt haben:

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

Sie müssen jedem Element von index, das die Sortierreihenfolge beschreibt, eine data-Eigenschaft hinzufügen. Die normale Variable i wird nur im Kontext einer bestimmten Auswahl definiert, die bei einer erneuten Auswahl verloren geht. 

55
Adam Pearce

Verwenden Sie append() für das erste Element und insert() für das zweite Element. Dadurch entfällt die Notwendigkeit, nachträglich zu sortieren (dank @ scuerdas Kommentar zum Hervorheben) ( 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 + ']'})

Dadurch erhalten Sie genau die gewünschte Struktur:

<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>
14
Caleb Clark

Sie können dies auch in einem einzigen Auswahl-/Eingabezyklus wie folgt durchführen

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]')});
12
Karl Koster

Anstelle einer .append()

Sie können auch eine Funktion einschließen, die neuen Inhalt in einer .html() erstellt.

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

Ähnlich wie oben, aber in einer anderen Sprache. Dies ist für den Ansatz der verschachtelten Auswahl relevanter und macht das Sortieren oder Einfügen überflüssig:

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 + ']'; });

Eleganter (und wahrscheinlich schneller):

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