D3 CSV数据加载

17

我正在尝试将D3中一个简单的散点图程序适应于接受CSV文件。当我使用文件中的数据时,它可以正常工作,但是当我尝试加载CSV文件时,它就无法工作了。我是否遗漏了一些简单的东西?CSV文件"datatest.csv"的内容与代码中的数据集相同。我已经检查了浏览器是否加载了数据,而且所有数据都在那里。我想我可能只是错过了一步。

<!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>

这是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
3个回答

15

重要提示:

虽然这里的答案是有效的,但是还有一个内置方法 d3.csv.parseRows() 可以实现相同的结果。关于它的更多信息,请参见 @ryanmt 的答案(也在此页面上)。然而,请记住,无论使用哪种方法,如果您的 CSV 中包含数字,则需要将它们从字符串转换为 JavaScript 数字。您可以通过在解析后的值前面加上+来实现这一点。例如,在我提供的解决方案中 —— 它不使用 parseRows() —— 这个转换是通过 +d["x-coordinate"] 实现的。

答案:

CSV 解析器生成的是对象数组,而不是您所需的数组数组。它看起来像这样:

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

要转换它,你需要使用一个map()函数:

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

(注意,map() 在较旧版本的 IE 中不可用。如果这很重要,则可以使用 d3、jQuery 等许多解决方法)


Meetamit,感谢您的帮助。我已经在上面发布了CSV文件的内容。 - English Grad
@EnglishGrad,K,我认为这是解决方案(请查看编辑后的答案)。 - meetamit
+d 代表什么? - starcodex
这是一种将字符串强制转换为数字的技巧。由于这是一个CSV文件,所有值都作为需要被强制转换的字符串出现。我不能马上想起在这种方式下,非数字字符串是否会产生NaN或保留字符串(可能是前者),因此必须小心处理它。 - meetamit
1
@Selrac,听起来你的CSV文件托管在与你的网站(或本地主机)不同的域上,浏览器出于安全原因故意阻止这种情况。这与CSV解析的问题无关或更为普遍。你需要将CSV文件移动/复制到相同的域中,或者(更难)编写代理服务器。研究跨域请求。 - meetamit
显示剩余6条评论

7
D3提供了一个内置函数来完成这个任务。 不要在数据上调用.parse(),而是调用.parseRows。它仅提供数据的数组形式,而不是基于标题行的对象形式。 请参阅文档

4
能否举个例子演示使用.parseRows的方法?谢谢! - Racing Tadpole

0

使用d3.csvParseRows(假设D3 v5)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接