Quelqu'un peut-il s'il vous plaît expliquer la différence entre datum () et data () dans D3.js? Je vois les deux être utilisés et je ne suis pas sûr de savoir pourquoi vous devriez choisir l'un sur l'autre?
J'ai trouvé la bonne réponse de Mike lui-même:
D3 - comment traiter les structures de données JSON?
Si vous souhaitez lier vos données à un seul élément SVG, utilisez
(...).data([data])
ou
(...).datum(data)
Si vous souhaitez lier vos données à plusieurs éléments SVG
(...).data(data).enter().append("svg")
.....
Voici quelques bons liens:
Bonne discussion sur D3 "data ()": Comprendre comment D3.js lie les données aux nœuds
Par ce dernier:
# selection.data([values[, key]])
Joint le tableau de données spécifié à la sélection actuelle. Les valeurs spécifiées sont un tableau de valeurs de données, tel qu'un tableau de nombres ou d'objets, ou une fonction qui renvoie un tableau de valeurs.
...
# selection.datum([value])
Obtient ou définit les données liées pour chaque élément sélectionné. Contrairement à la méthode selection.data, cette méthode ne calcule pas de jointure (et ne calcule donc pas les sélections d'entrée et de sortie).
Après avoir examiné cela un peu, j'ai constaté que les réponses ici sur SO ne sont pas complètes car elles ne couvrent que le cas où vous appelez _selection.data
_ et _selection.datum
_ avec une entrée data
paramètre. Même dans ce scénario, les deux se comportent différemment si la sélection est un seul élément par rapport à plusieurs éléments. De plus, ces deux méthodes peuvent également être invoquées sans aucun argument d'entrée afin d'interroger les données/données liées dans la sélection, auquel cas elles se comportent à nouveau différemment et renvoient des éléments différents.
Edit - J'ai posté une réponse un peu plus détaillée à cette question ici , mais l'article ci-dessous résume à peu près tous les points clés concernant les deux méthodes et la façon dont elles diffèrent l'une de l'autre.
lors de la fourniture data
sous la forme d'un argument d'entrée
selection.data(data)
essaiera de réaliser une jointure de données entre les éléments du tableau data
avec la sélection entraînant la création de enter()
, exit()
et update()
sélections. que vous pourrez ensuite opérer. Le résultat final de ceci est que si vous passez dans un tableau _data = [1,2,3]
_, une tentative est faite pour joindre chaque élément de données individuel (c'est-à-dire le datum) à la sélection. Chaque élément de la sélection n'aura qu'un seul élément de donnée de data
qui lui est lié.
selection.datum(data)
contourne complètement le processus de jointure de données. Ceci affecte simplement l'intégralité de data
à tous les éléments de la sélection dans son ensemble sans le fractionner, comme dans le cas des jointures de données. Donc, si vous souhaitez lier un tableau entier _data = [1, 2, 3]
_ à chaque élément DOM de votre selection
, alors selection.datum(data)
y parviendra.
Avertissement: Beaucoup de gens croient que
selection.datum(data)
est équivalent àselection.data([data])
mais cela n'est vrai que siselection
contient un seul élément . Siselection
contient plusieurs éléments DOM, alorsselection.datum(data)
liera l'intégralité dedata
à chacun des éléments de la sélection. En revanche,selection.data([data])
ne lie l'intégralité dedata
qu'au premier élément deselection
. Cela est cohérent avec le comportement de jointure de données de _selection.data
_.
Lorsque vous ne fournissez aucun argument d'entrée data
selection.data()
prendra les données liées pour chaque élément de la sélection et les combinera dans un tableau renvoyé. Ainsi, si votre selection
comprend 3 éléments DOM avec les données _"a"
_, _"b"
_ et _"c"
_ liées à chacun, selection.data()
renvoie _["a", "b", "c"]
_. Il est important de noter que si selection
est un élément unique auquel (à titre d'exemple) le datum _"a"
_ est lié, alors selection.data()
renverra _["a"]
_ et non _"a"
_ comme certains peuvent s’y attendre.
selection.datum()
n'a de sens que pour une sélection unique car il est défini comme renvoyant la donnée liée au premier élément de la sélection. Ainsi, dans l'exemple ci-dessus avec une sélection d'éléments DOM avec une donnée liée de _"a"
_, _"b"
_ et _"c"
_, selection.datum()
renverrait simplement _"a"
_.
Notez que même si
selection
n'a qu'un seul élément,selection.datum()
etselection.data()
renvoient des valeurs différentes. Le premier retourne la donnée liée pour la sélection (_"a"
_ dans l'exemple ci-dessus), tandis que le second renvoie la donnée liée dans un tableau (_["a"]
_ dans l'exemple ci-dessus).
Espérons que cela aide à préciser la différence entre _selection.data
_ et selection.datum()
à la fois lors de la fourniture de données en tant qu'argument d'entrée et lors de la recherche du datum lié en ne fournissant aucun argument en entrée.
PS - La meilleure façon de comprendre comment cela fonctionne est de commencer avec un document HTML vierge dans Chrome, d'ouvrir la console, d'essayer d'ajouter quelques éléments au document, puis de commencer à lier les données à l'aide de _selection.data
_. et _selection.datum
_. Parfois, il est beaucoup plus facile de "groker" quelque chose en agissant qu'en lisant.
Je pense que l'explication donnée par HamsterHuey est la meilleure à ce jour. Pour développer et donner une représentation visuelle des différences, j'ai créé un exemple de document illustrant au moins une partie des différences entre data
et datum
.
La réponse ci-dessous est plus une opinion dérivée de l'utilisation de ces méthodes, mais je suis heureux d'être corrigé si je me trompe.
Cet exemple peut être exécuté ci-dessous ou dans ce violon .
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}`)
Je pense que datum
est plus simple à comprendre car il ne fait pas de jointure, mais bien sûr, cela signifie aussi qu'il a différents cas d'utilisation.
Pour moi, une grande différence - bien qu’il y en ait plus - est le fait que data
est simplement la manière naturelle d’effectuer des mises à jour (en direct) sur un graphique d3, car le modèle entier entrée/mise à jour/sortie le rend simple, une fois. vous l'obtenez.
datum
me semble en revanche plus adapté aux représentations statiques. Dans l'exemple ci-dessous, par exemple, je pourrais obtenir le même résultat: boucler sur le tableau d'origine et accéder aux données par index, comme suit:
data.map((n, i) => {
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node-${n} => data: ${d[i]}`);
});
Essayez-le ici: https://jsfiddle.net/gleezer/e4m6j2d8/6/
Encore une fois, je pense que c’est beaucoup plus facile à comprendre car vous vous libérez du fardeau mental découlant du modèle entrée/mise à jour/sortie, mais dès que vous aurez besoin de mettre à jour ou de modifier la sélection, vous aurez sûrement intérêt à recourir à .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>