D3.js中将CSV转换为数组

41

我正在使用这个来解析一个CSV文件,并创建一个符合d3文档规定的数组数据:

d3.csv("afile.csv", function(data) {
    data.forEach(function(d) {
    d.date = formatDate.parse(d.date);
    d.price = +d.price;
});
然而,如果我在此方法之后尝试调用data[0],它会显示未定义。这是因为data是一个引用,一旦d3.csv()超出范围就会被销毁吗?如果是这样,我该如何克服这个问题。我需要引用d3.csv()外部的数据。
5个回答

138

d3.csv是一个异步方法。这意味着回调函数内部的代码将在数据加载时运行,但是回调函数之后和外部的代码将在请求发出时立即运行,此时数据尚不可用。换句话说:

first();
d3.csv("path/to/file.csv", function(rows) {
  third();
});
second();

如果你想使用由d3.csv加载的数据,你需要将那段代码放在回调函数内(在上面的third处):

d3.csv("path/to/file.csv", function(rows) {
  doSomethingWithRows(rows);
});

function doSomethingWithRows(rows) {
  // do something with rows
}

或者,您可以将它保存为窗口上的全局变量,稍后可以引用它:

var rows;

d3.csv("path/to/file.csv", function(loadedRows) {
  rows = loadedRows;
  doSomethingWithRows();
});

function doSomethingWithRows() {
  // do something with rows
}

如果你愿意的话,你也可以将加载的数据明确地分配给window对象,而不是声明一个变量,然后管理两个不同的名称:

d3.csv("path/to/file.csv", function(rows) {
  window.rows = rows;
  doSomethingWithRows();
});

function doSomethingWithRows() {
  // do something with rows
}

@SGaber 我认为将您的数据库凭据传递给用户并不是一个好主意。 - Neurotransmitter

3

我认为你的问题是时间问题,因为这是一个异步调用。所以,按照你的方式加载数据,但在d3代码中调用函数(Mike在'doSomethingWithRows()'处)。不要在d3代码后面跟随任何其他处理(Mike在'second()'处),将该代码移动到'doSomethingWithRows()'函数中。它将有可用的数据,然后你就可以继续操作了...


0

我认为问题已经解决了,但我遇到了类似的问题,上面的讨论并没有帮助我。所以我来分享一下我是如何解决这个问题的:在这里,data[0] 未定义的原因可能是因为浏览器本身没有读取数据。这种读取失败很可能是由于直接加载数据(csv)文件,即使用以下命令 d3.csv("myCSVfile.csv",....)。这种方法可能行不通,因为Web应用程序通常需要从Web服务器加载文件(不确定为什么会这样)。因此,需要放置一个本地Web服务器。使用此论坛学习如何操作:如何使用Python设置本地HTTP服务器。如果您使用Python 3创建本地Web服务器,则更新的代码将是:d3.csv("http://localhost:8000/myCSVfile.csv",.....)


0
then(function(data)) 回调函数中,您将获得保持数组。
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, ...} ....]
});

-2
你可以在回调函数外声明一个变量,然后将其赋值为来自 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;
});

然后在回调函数之外使用csv_data


但这正是我的问题所在。每当我在回调函数之外引用csv_data时,我得到的都是未定义的值。在回调函数内部则没有问题。这就是为什么我认为csv_data具有数据的引用,因此一旦函数超出范围,引用就会被销毁。尽管如此,我已经通过采用完全不同的方法解决了这个问题。感谢您的答案。 - George Eracleous
1
好的,很抱歉最终没有提供帮助,但如果您的解决方案或方法变更对其他用户有用,请考虑发布以供将来参考。 - msonsona
2
这种完全不同的方法是什么? - d-cubed
1
@GeorgeEracleous:您介意分享一下最终是如何解决这个问题的吗?谢谢! - Cleb

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