使用javascript/D3读取任意数量的csv



我正在构建一个Web应用程序,该应用程序接收文件名列表,并根据该输入读取文件、连接文件,并在各种图表中显示数据。这里的棘手之处在于,在提取相关信息之前,文件相当大(约6-10mb),我不知道用户会请求多少。(假设一个典型的请求将大于3但小于20。)

据我所知,没有明显的方法可以读取任意数量的d3文件。Mike Bostock在这里回答了一个类似的问题。这些解决方案的问题在于,它们要求您提前知道文件的数量——我没有这种奢侈。

我想做的是有一些递归函数,比如:

function concatFiles(fileNameArray) {
function recursiveConcat(fileNameArray, concatedFile) {
var temp;
if (fileNameArray.length === 0) {
return concatedFile;
} else {
d3.csv(fileNameArray.shift(), function(err, csv) {
temp = csv;
}
return recursiveConcat(fileNameArray, concatedFile.concat(temp));
}
}
return recursiveConcat(fileNameArray, []);
}

这种解决方案的好处是,我不必为每个文件创建一个变量,也不必将中间结果存储在数组中。然而,我不确定这件事是否能很好地利用Javascript的异步特性(我是Javascript的新手)。如何在arrayOfFileNames -> concatenatedFile之间有效映射?

d3-queue似乎非常适合这种情况。以下代码段应该足以处理任意数量文件的加载:

function loadFiles(files) {
// Create a new queue to handle the loading of all files.
var q = d3.queue();
// Iterate over the array of all files to be loaded.
files.forEach(function(f) {
// Add a loading task for each file to the queue.
q.defer(d3.csv, f)  
});
// When all loading tasks have finished, you may process the
// contents of all files.
q.awaitAll(function(error, contents) {
// Do your concatenation here.
// contents contains an array of the parsed results of all files
// console.log(contents);
})
}
var filesToLoad = ["file1.csv", "whatever.csv", "another.csv"];
loadFiles(filesToLoad);      // load all files in the array

请注意,这不会对数组filesToLoad中的文件数量做出任何假设。看看这个Plunk作为一个工作示例。

最新更新