Was ist der Unterschied zwischen D3-Datum und Daten?

199

Kann jemand bitte den Unterschied zwischen datum () und data () in D3.js erklären? Ich sehe beide verwendet und bin mir nicht sicher, warum Sie eine über die andere wählen sollten?

josephmisiti
quelle

Antworten:

164

Ich habe hier die richtige Antwort von Mike selbst gefunden:

D3 - Wie gehe ich mit JSON-Datenstrukturen um?

Wenn Sie Ihre Daten an ein einzelnes SVG-Element binden möchten, verwenden Sie

(...).data([data])

oder

(...).datum(data)

Wenn Sie Ihre Daten an mehrere SVG-Elemente binden möchten

(...).data(data).enter().append("svg")

..... .....

josephmisiti
quelle
Danke dafür! Die Tatsache, dass Sie Daten ([Daten]) übergeben und ein Array erstellen, hat mir nur geholfen, einen Fehler zu erkennen, den ich in der letzten Woche nicht herausfinden konnte! Vielen Dank ... immer so dumme Dinge, die falsch sind.
Adam
22
data () führt einen Join durch, datum () nicht.
s3-4v
Denken Sie daran, dass enter()d3 den Rest der Array-Elemente mit neu erstellten SVG-Elementen bindet , falls beim Binden von Daten mehr Datenarray-Elemente als SVG-Elemente vorhanden sind .
Aslantorret
49

Nachdem ich mich ein wenig damit befasst habe, habe ich festgestellt, dass die Antworten hier auf SO nicht vollständig sind, da sie nur den Fall abdecken, wenn Sie aufrufen selection.dataund selection.datumeinen Eingabeparameter verwenden data. Selbst in diesem Szenario verhalten sich die beiden anders, wenn die Auswahl ein einzelnes Element ist, als wenn sie mehrere Elemente enthält. Darüber hinaus können beide Methoden auch ohne Eingabeargumente aufgerufen werden, um die gebundenen Daten / Daten in der Auswahl abzufragen. In diesem Fall verhalten sie sich erneut unterschiedlich und geben unterschiedliche Dinge zurück.

Bearbeiten - gab ich eine etwas ausführlichere Antwort auf diese Frage hier , aber die Post unten ziemlich erfasst alle wichtigen Punkte in Bezug auf die beiden Methoden und wie sie sich voneinander unterscheiden.

Bei Angabe data als Eingabeargument

  • selection.data(data)wird versuchen, eine Datenverbindung zwischen den Elementen des dataArrays mit der Auswahl durchzuführen, die zur Erstellung von führt enter(), exit()und update()Auswahlen, mit denen Sie anschließend arbeiten können. Das Endergebnis davon ist, wenn Sie ein Array übergeben data = [1,2,3], wird versucht, jedes einzelne Datenelement (dh Datum) mit der Auswahl zu verbinden. An jedes Element der Auswahl ist nur ein einziges Bezugselement datagebunden.

  • selection.datum(data)Umgeht den Datenverbindungsprozess insgesamt. Dies ordnet einfach die Gesamtheit dataaller Elemente in der Auswahl als Ganzes zu, ohne sie wie bei Datenverknüpfungen aufzuteilen. Wenn Sie also ein ganzes Array data = [1, 2, 3]an jedes DOM-Element in Ihrem Element binden möchten selection, selection.datum(data)wird dies erreicht.

Warnung: Viele Leute glauben, dass diesselection.datum(data)gleichbedeutend ist,selection.data([data])aber dies gilt nur, wenn es selection ein einzelnes Element enthält . Wennselectionmehrere DOM-Elemente enthalten sind,selection.datum(data)wird die Gesamtheitdataan jedes einzelne Element in der Auswahl gebunden. Im Gegensatz dazuselection.data([data])bindet nur die Gesamtheitdata an das erste Element inselection. Dies steht im Einklang mit dem Datenverbindungsverhalten vonselection.data.

Bei Angabe kein dataEingabeargument

  • selection.data()nimmt das gebundene Datum für jedes Element in der Auswahl und kombiniert sie zu einem Array, das zurückgegeben wird. Also, wenn Ihr selectionbeinhaltet 3 DOM - Elemente mit den Daten "a", "b"und "c"an die jeweils gebundenen selection.data()Renditen ["a", "b", "c"]. Es ist wichtig zu beachten, dass, wenn selectiones sich um ein einzelnes Element handelt, an das (beispielsweise) das Datum "a"gebunden ist, dieses zurückgegeben selection.data()wird ["a"]und nicht "a"wie von einigen erwartet.

  • selection.datum()Dies ist nur für eine einzelne Auswahl sinnvoll, da definiert wird, dass das an das erste Element der Auswahl gebundene Datum zurückgegeben wird . So in dem obigen Beispiel mit der Auswahl aus DOM - Elementen mit gebundenem Bezug von "a", "b"und "c", selection.datum()würde einfach zurückkehren "a".

Beachten Sie, dass selbst wenn selectionein einzelnes Element hat, selection.datum()und selection.data()unterschiedliche Werte zurückgeben. Ersteres gibt das gebundene Datum für die Auswahl zurück ( "a"im obigen Beispiel), während letzteres das gebundene Datum innerhalb eines Arrays zurückgibt ( ["a"]im obigen Beispiel).

Hoffentlich hilft dies zu klären, wie selection.dataund selection.datum()sich voneinander unterscheiden, sowohl bei der Bereitstellung von Daten als Eingabeargument als auch bei der Abfrage des gebundenen Datums, indem keine Eingabeargumente angegeben werden.

PS - Der beste Weg, um zu verstehen, wie dies funktioniert, besteht darin, mit einem leeren HTML-Dokument in Chrome zu beginnen, die Konsole zu öffnen und dem Dokument einige Elemente hinzuzufügen und dann mit selection.dataund Daten zu binden selection.datum. Manchmal ist es viel einfacher, etwas durch Handeln zu "groken" als durch Lesen.

HamsterHuey
quelle
HamsterHuey hat dies bereits gezeigt, aber es könnte eine hilfreiche Erinnerung sein, sich daran zu erinnern, dass "Datum" Singular und "Daten" Plural ist. Daher gilt .datum für die zugehörigen Informationen eines einzelnen Elements.
Visio Guy
42

Hier sind einige gute Links:

Per letzterem:

# selection.data([values[, key]])

Verbindet das angegebene Datenarray mit der aktuellen Auswahl. Die angegebenen Werte sind ein Array von Datenwerten, z. B. ein Array von Zahlen oder Objekten, oder eine Funktion, die ein Array von Werten zurückgibt.

...

# selection.datum([value])

Ruft die gebundenen Daten für jedes ausgewählte Element ab oder legt diese fest. Im Gegensatz zur Methode selection.data berechnet diese Methode keinen Join (und berechnet daher keine Eingangs- und Ausgangsauswahl).

paulsm4
quelle
11
Angesichts dieser Definitionen - ich bin immer noch verwirrt, warum Sie jemals datum () benötigen würden / wollen
josephmisiti
Ein weiteres Beispiel, das helfen könnte, macht die Dinge klarer: ngokevin.com/blog/d3 . ANMERKUNGEN: 1) Kevins Definition: "Das Datum sind die Daten, die an das Element gebunden sind." 2) Beachten Sie, wie wir in Kevins Beispielen den Datensatz mit "data ()" "einbinden" ... aber eine Teilmenge "verwenden", indem wir auf ein "datum ()" verweisen.
Pauls4
5

Ich denke, die Erklärung von HamsterHuey ist die bisher beste. Um es zu erweitern und eine visuelle Darstellung der Unterschiede zu geben, habe ich ein Beispieldokument erstellt, das zumindest einen Teil der Unterschiede zwischen dataund veranschaulicht datum.

Die folgende Antwort ist eher eine Meinung, die aus der Verwendung dieser Methoden abgeleitet wurde, aber ich bin froh, korrigiert zu werden, wenn ich falsch liege.

Dieses Beispiel kann unten oder in dieser Geige ausgeführt werden .

const data = [1,2,3,4,5];
const el = d3.select('#root');

 el
  .append('div')
  .classed('a', true)
  .datum(data)
  .text(d => `node => data: ${d}`);

const join= el
.selectAll('div.b')
.data(data);

join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)

Ich denke, das datumist einfacher zu verstehen, da es keinen Join macht, aber das bedeutet natürlich auch, dass es verschiedene Anwendungsfälle gibt.

Für mich ist ein großer Unterschied - obwohl es noch mehr gibt - die Tatsache, dass dies datanur die natürliche Art ist, (Live-) Updates auf einem D3-Diagramm durchzuführen, da das gesamte Ein- / Aktualisierungs- / Ausstiegsmuster es einfach macht, sobald Sie es erhalten.

datumAndererseits scheint es mir eher für statische Darstellungen geeignet zu sein. Im folgenden Beispiel könnte ich zum Beispiel das gleiche Ergebnis erzielen, wenn ich das ursprüngliche Array durchschleife und über den Index wie folgt auf die Daten zugreife:

data.map((n, i) => {
 el
  .append('div')
  .classed('a', true)
  .datum(data)
  .text(d => `node-${n} => data: ${d[i]}`);
});

Probieren Sie es hier aus: https://jsfiddle.net/gleezer/e4m6j2d8/6/

Auch hier denke ich, dass dies viel einfacher zu verstehen ist, da Sie sich von der mentalen Belastung durch das Ein- / Aktualisierungs- / Ausstiegsmuster befreien, aber sobald Sie die Auswahl aktualisieren oder ändern müssen, ist es sicherlich besser, auf sie zurückzugreifen .data().

const data = [1,2,3,4,5];
const el = d3.select('#root');

 el
  .append('div')
  .classed('a', true)
  .datum(data)
  .text(d => `node => data: ${d}`);

const join= el
.selectAll('div.b')
.data(data);

join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)
/* Ignore all the css */
html {
  font-family: arial;
}

.l {
  width: 20px;
  height: 20px;
  display: inline-block;
  vertical-align: middle;
  margin: 10px 0;
}
.l-a {
  background: #cf58e4;
}
.l-b {
  background:  #42e4e4;
}

.a {
  border-bottom: 2px solid #cf58e4;
}

.b {
  border-bottom: 2px solid #42e4e4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.6.0/d3.min.js"></script>


<div style="margin-bottom: 20px;">
  <span class="l l-a"></span> .datum() <br />
  <span class="l l-b"></span> .data()
</div>

<div id="root"></div>

Nobita
quelle