我正在构建一个 Web 应用程序,它接收文件名列表,并根据该输入读取文件,连接它们,并在各种图表中显示数据。这里棘手的是,在提取相关信息之前,文件相当大(~6-10mb),而且我不知道用户到底会请求多少。 (假设一个典型的请求大于 3 但小于 20。)
据我所知,没有明显的方法可以使用 d3 读取任意数量的文件。 Mike Bostock 回答了类似的问题 here 。这些解决方案的问题在于它们要求您提前知道文件的数量 - 我没有那么奢侈。
我想做的是某种递归函数,例如:
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一个工作示例。
关于javascript - 使用 javascript/D3 读取任意数量的 csv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37710825/