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?
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?
Antworten:
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")
..... .....
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 .
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 dies
selection.datum(data)gleichbedeutend ist,selection.data([data])aber dies gilt nur, wenn esselectionein 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 Gesamtheitdataan 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()undselection.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.
Hier sind einige gute Links:
Gute Diskussion zu D3 "data ()": Verstehen, wie D3.js Daten an Knoten bindet
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).
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>