web-dev-qa-db-fra.com

Quelle est la différence entre le datum D3 et les données?

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?

184
josephmisiti

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

.....

155
josephmisiti

Voici quelques bons liens:

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

37
paulsm4

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 si selection contient un seul élément . Si selection contient plusieurs éléments DOM, alors selection.datum(data) liera l'intégralité de data à chacun des éléments de la sélection. En revanche, selection.data([data]) ne lie l'intégralité de data qu'au premier élément de selection. 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() et selection.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.

35
HamsterHuey

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