web-dev-qa-db-fra.com

d3 csv chargement

J'essaie d'adapter un programme de dispersion simple en D3 pour accepter un fichier CSV. Lorsque j'utilise les données du fichier, cela fonctionne parfaitement, mais lorsque j'essaie de charger le fichier CSV, cela ne fonctionne tout simplement pas. Y a-t-il quelque chose de simple qui me manque? Le contenu du fichier CSV "datatest.csv" est identique à l'ensemble de données du code. J'ai vérifié que le navigateur est en train de charger les données, et tout semble être là. Je suppose que je manque simplement un pas. 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>D3 Demo: Linear scales</title>
    <script type="text/javascript" src="../d3/d3.v3.js"></script>
    <style type="text/css">
        /* No style rules here yet */       
    </style>
</head>
<body>
    <script type="text/javascript">

        //Width and height
        var w = 900;
        var h = 500;
        var padding = 20;
        var dataset = [];

//          var dataset = [
//                          [5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
//                          [410, 12], [475, 44], [25, 67], [85, 21], [220, 88],
//                          [600, 150]
//                        ];

        d3.csv("datatest.csv", function(data) {
        dataset=data
        });



        //Create scale functions
        var xScale = d3.scale.linear()
                             .domain([0, d3.max(dataset, function(d) { return d[0]; })])
                             .range([padding, w - padding * 2]);

        var yScale = d3.scale.linear()
                             .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                             .range([h - padding, padding]);

        var rScale = d3.scale.linear()
                             .domain([0, d3.max(dataset, function(d) { return d[1]; })])
                             .range([2, 5]);

        //Create SVG element
        var svg = d3.select("body")
                    .append("svg")
                    .attr("width", w)
                    .attr("height", h);

        svg.selectAll("circle")
           .data(dataset)
           .enter()
           .append("circle")
           .attr("cx", function(d) {
                return xScale(d[0]);
           })
           .attr("cy", function(d) {
                return yScale(d[1]);
           })
           .attr("r", function(d) {
                return rScale(d[1]);
           });
    </script>
</body>
</html>

Voici le contenu du fichier CSV:

x-coordinate, y-coordinate
5,20
480,90
250,50
100,33
330,95
410,12
475,44
25,67
85,21
220,88
600,150
17
English Grad

IMPORTANT:

Bien que la réponse fonctionne ici, il existe une méthode intégrée d3.csv.parseRows(), qui permet d'obtenir le même résultat. Pour cela, voir la réponse de @ ryanmt (également sur cette page). Cependant, gardez à l'esprit que, quelle que soit la méthode utilisée, si votre CSV contient des chiffres, vous devez les convertir de chaînes en numéros javascript. Vous pouvez le faire en préfixant les valeurs analysées avec un +. Par exemple, dans la solution que j'ai fournie ici - qui n'utilise pas parseRows() - cette conversion est réalisée via +d["x-coordinate"].

LA RÉPONSE:

L'analyseur CSV produit un tableau d'objets plutôt que le tableau de tableaux dont vous avez besoin. Cela ressemble à ceci:

[
  {"x-coordinate":"5"," y-coordinate":"20"},
  {"x-coordinate":"480"," y-coordinate":"90"},
  {"x-coordinate":"250"," y-coordinate":"50"},
  {"x-coordinate":"100"," y-coordinate":"33"},
  ...
]

Pour le transformer, vous devez utiliser une fonction map():

d3.csv("datatest.csv", function(data) {
  dataset = data.map(function(d) { return [ +d["x-coordinate"], +d["y-coordinate"] ]; });
});

(Remarque, map() n'est pas disponible dans les versions antérieures d'IE. Si cela compte, il existe de nombreuses solutions de contournement avec d3, jQuery, etc.)

15
meetamit

D3 fournit un construit pour cette chose même.

Au lieu d'appeler .parse() sur vos données, appelez .parseRows. Cela fournit uniquement les données sous forme de tableau plutôt que d'objet (basé sur la ligne d'en-tête).

voir la Documentation .

7
Ryanmt

Utilisation de d3.csvParseRows (en supposant que D3 v5)

d3.text('/data/output.csv')
  .then( text => d3.csvParseRows(text) )
  .then( d => console.log(d) );
0
Garfield