41 votes

Convertir le csv en tableau dans d3.js

Je l'utilise pour analyser un fichier csv et créer un tableau de données tel que spécifié dans la documentation de d3 :

d3.csv("unfichier.csv", function(data) {
    data.forEach(function(d) {
    d.date = formatDate.parse(d.date);
    d.price = +d.price;
});

Cependant, si après cette méthode j'essaie d'appeler data[0], il indique qu'il est indéfini. Est-ce parce que data est une référence et qu'une fois d3.csv() hors de portée, il est détruit ? Si c'est le cas, comment puis-je surmonter cela ? J'ai besoin de faire référence aux données en dehors de d3.csv()

138voto

mbostock Points 25336

D3.csv est une méthode asynchrone. Cela signifie que le code à l'intérieur de la fonction de rappel est exécuté lorsque les données sont chargées, mais le code après et en dehors de la fonction de rappel sera exécuté immédiatement après la requête, lorsque les données ne sont pas encore disponibles. En d'autres termes :

first();
d3.csv("chemin/vers/fichier.csv", function(rows) {
  third();
});
second();

Si vous souhaitez utiliser les données chargées par d3.csv, vous devez soit mettre ce code à l'intérieur de la fonction de rappel (où se trouve third, ci-dessus) :

d3.csv("chemin/vers/fichier.csv", function(rows) {
  faireQuelqueChoseAvecLesLignes(rows);
});

function faireQuelqueChoseAvecLesLignes(rows) {
  // faire quelque chose avec les lignes
}

Ou vous pouvez les enregistrer en tant que variable globale sur la fenêtre à laquelle vous pourrez ensuite vous référer ultérieurement :

var lignes;

d3.csv("chemin/vers/fichier.csv", function(lignesChargées) {
  rows = lignesChargées;
  faireQuelqueChoseAvecLesLignes();
});

function faireQuelqueChoseAvecLesLignes() {
  // faire quelque chose avec les lignes
}

Si vous le souhaitez, vous pouvez également assigner explicitement les données chargées à l'objet window, plutôt que de déclarer une variable et de gérer deux noms différents :

d3.csv("chemin/vers/fichier.csv", function(rows) {
  window.rows = rows;
  faireQuelqueChoseAvecLesLignes();
});

function faireQuelqueChoseAvecLesLignes() {
  // faire quelque chose avec les lignes
}

3voto

Andrew NZ Points 320

Je pense que votre problème est lié au timing car il s'agit d'un appel asynchrone. Donc, chargez les données comme vous le faites habituellement mais appelez la fonction à l'intérieur du code d3 (là où Mike a 'doSomethingWithRows()'). Ne suivez pas votre code d3 avec d'autres traitements (là où Mike a 'second()'), déplacez ce code dans la fonction 'doSomethingWithRows()'. Les données seront disponibles et vous pourrez continuer...

0voto

Maneet Points 51

Je pense que le problème est déjà résolu mais j'ai rencontré un problème similaire et la discussion ci-dessus n'a pas été aussi utile. Je partage donc comment j'ai trouvé une solution à ce problème: Ici, la raison pour laquelle data[0] est indéfini est probablement parce que les données elles-mêmes ne sont pas lues par le navigateur. Cette impossibilité de lecture est probablement due au chargement direct du fichier de données (csv), c'est-à-dire en utilisant la commande suivante d3.csv("monFichierCSV.csv",....). Cette approche peut ne pas fonctionner car les applications web nécessitent généralement le chargement de fichiers à partir de serveurs web (je ne sais pas pourquoi c'est le cas). Il est donc nécessaire de mettre en place un serveur web local. Utilisez ce forum pour apprendre comment faire: Comment configurer un serveur HTTP local en utilisant Python. Le code mis à jour, si vous utilisez Python 3 pour créer un serveur web local, sera : d3.csv("http://localhost:8000/monFichierCSV.csv",.....).

0voto

Daniel Points 414

Dans le callback then(function(data)), vous obtiendrez le tableau complet.

d3.csv("afile.csv", function(row) {
  return {name1: row.name1, name2: row.name2, ...}
}).then(function(d){
   console.log(d) // => [{{name1: row.name1, name2: row.name2, ...}}, {name1: row.name1, name2: row.name2, ...} ....]
});

-2voto

msonsona Points 845

Vous pourriez déclarer une variable en dehors de la fonction de rappel et ensuite lui attribuer les valeurs du csv :

var csv_data;
d3.csv("afile.csv", function(data) {
  data.forEach(function(d) {
    d.date = formatDate.parse(d.date);
    d.price = +d.price;
  csv_data = data;
});

et ensuite utiliser csv_data en dehors de la fonction de rappel

0 votes

Mais c'est exactement mon problème. Chaque fois que je fais référence à csv_data en dehors du rappel, tout ce que je reçois est indéfini. À l'intérieur du rappel, c'est très bien. C'est pourquoi j'ai supposé que csv_data a une référence de données et donc une fois que la fonction sort de la portée, la référence est détruite. Néanmoins, j'ai résolu le problème en suivant une approche totalement différente. Merci pour la réponse.

1 votes

D'accord, désolé de ne pas avoir aidé à la fin, mais envisagez de publier votre solution ou votre changement d'approche si cela est utile pour référence future aux autres utilisateurs.

2 votes

Quelle était l'approche entièrement différente?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X