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.data
und selection.datum
einen 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 data
Arrays 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 data
gebunden.
selection.datum(data)
Umgeht den Datenverbindungsprozess insgesamt. Dies ordnet einfach die Gesamtheit data
aller 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 esselection
ein einzelnes Element enthält . Wennselection
mehrere DOM-Elemente enthalten sind,selection.datum(data)
wird die Gesamtheitdata
an 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 data
Eingabeargument
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 selection
beinhaltet 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 selection
es 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
selection
ein 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.data
und 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.data
und 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 data
und 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 datum
ist 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 data
nur 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.
datum
Andererseits 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>