gpt4 book ai didi

javascript - 使用 D3.js 加载和解析多个 csv 文件

转载 作者:行者123 更新时间:2023-11-28 00:12:32 25 4
gpt4 key购买 nike

我正在使用 D3.js 实现 map 可视化。我有许多 x csv 文件(矩阵)。我想加载它们并对所有文件中的所有值求和。

我在名称数组上实现了 for 循环,并使用 d3.text 加载和解析数据,但由于异步行为,我找不到方法来执行此操作(我得到首先来自 console.logundefined,然后是 for 循环的结果)。

我尝试使用 async.js 但我不知道如何允许 for 循环的流程。这是我的代码:

var total=[];
var matrix=[];

for(var i=0; i<filenames.length; i++){

d3.text(filenames[i], function(text){
matrix = d3.csv.parseRows(text).map(function (row){
return row.map(function(value){
return +value;
});
});
});

//sum the matrix pseudocode
for(...){
total = total + matrix;
}
}

//here I need the sum of all files and then do other stuffs with the total:
console.log(total);
...
...

我怎样才能实现这个目标?谢谢。

最佳答案

我建议您使用递归函数来完成此操作。

在下面的示例中,您可以像 d3.text() 一样使用 loadFilesAndCalculateSum(),但它不是一个字符串,而是一个字符串数组,并且回调获取计算出的总和而不是文件的文本。

/**
* load all files and calculate the sum of the values
* @param {Array} filenames Array with filenames as string
* @param {Function} cb Callback function, gets the sum as param
* @param {number} sum The initial sum
* @param {number} i Starting index for filenames
* @return {void}
*/
function loadFilesAndCalculateSum(filenames, cb, sum, i) {
sum = sum || 0;
i = i || 0;
d3.text(filenames[i], function(error, text) {
//parse the rows and reduce them
sum += d3.csv.parseRows(text).reduce(function(prev, curr) {
//return previous sum + this rows sum
return prev + d3.sum(curr, function(d){return +d;})
},0);

if(i < filenames.length - 1){
//load next file
loadFilesAndCalculateSum(filenames, cb, sum, i+1);
} else {
//call the callback with the final sum
cb(sum);
}
});
}

var filenames = ["file1.txt", "file2.txt", "file3.txt"];

loadFilesAndCalculateSum(filenames, function(sum){
//do something with the total sum
console.log(sum);
});

为了澄清这一点。您必须在回调函数内部对总和进行处理,我在其中添加了注释对总和进行处理。该函数仍在异步执行。这意味着,您在 loadFilesAndCalculateSum() 函数之后编写的所有内容都可能在回调内的代码之前执行。您可以找到async javascript here的更长一点的介绍。

//this is executed first
//....
loadFilesAndCalculateSum(filenames, function(sum){
//do something with the total sum
//this is executed third, when all files are loaded and the sum is calculated
console.log(sum);
});

//code after this point is executed second, while the files are being loaded.

如果您已经有一个对总和执行某些操作的函数,则可以将此函数作为第二个参数传递给 loadFilesAndCalculateSum。这是可能的,因为函数被称为 first class citizens :

var addthis = 5;

function doSomethingWithTheSum(sum) {
//everything you want to do with the sum goes inside this function.

//from here you could call other functions and pass the sum.
soSomethingDifferentWithTheSum(sum);

//or you use the sum inside this function
console.log(sum);
var newsum = sum + addthis;
console.log(sum);

d3.select("whatever")
.data([sum])
.enter()
.append("text")
.text(function(d){ return d;});
}

loadFilesAndCalculateSum(filenames, doSomethingWithTheSum);

您可以像传递任何其他变量一样传递函数。在第一个示例中,我调用了 loadFiles... 函数的第二个参数 cb,它是 callback 的常用缩写。如文档注释中所述,此参数应为 Function 类型。

loadFiles... 函数的末尾,回调函数被调用

....
//call the callback with the final sum
cb(sum);
....

这里将总和作为第一个参数提供给回调函数。因此,如果您传递一个函数,它应该采用单个参数,例如第一个示例中的匿名函数或上面示例中的 doSomethingWithTheSum 函数。

关于javascript - 使用 D3.js 加载和解析多个 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30766696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com