使用 d3.json 中的 d3.csv 组合多个 csv 文件数据输入的最佳方法是什么?
What is the best way to combine multiple csv files data input using d3.csv in d3.json ?
我还是 javascript 和 d3 的新手。我正在尝试找到将多个 csv 外部文件合并到 d3 中然后对其进行处理的最佳方法。目前我正在为一个文件使用如下脚本。
d3.csv("file1.csv",funciton(error,data) {
// do something
}
有什么方法可以连接 file1.csv + file2.csv + .. file9.csv
到一个文件中类似于此.. 在 d3 中?
d3.csv( concat("file1.csv","file2,csv",..file9.csv") ,function(error,data) {
// do something
}
我建议在您托管 javascript 的服务器上执行此操作,然后将单个文件提供给 d3。鉴于所有 csv 文件都是相同的格式,并且像您的示例一样按顺序命名,这是在 unix 命令行上加入它们的简单方法:
head -q -n 1 file1.csv > concat.csv #OVERWRITE with line 1 (headers)
tail -q -n +2 file*.csv >> concat.csv #APPEND lines 2+ from all matching files
编辑,暴力客户端方式,jquery:
var remaining = 0;
var collection = [];
$(document).ready(concatCSVs)
function concatCSVs(){
var uris = ['csv1.csv', 'csv2.csv'];
remaining = uris.length;
uris.forEach(function(uri){
getCSV(uri, collector)
})
}
function getCSV(uri, callback){
$.ajax(uri, {
success: callback
})
}
function collector(data){
if(remaining == 0){
throw new Error('Got more results than expected')
}
remaining -= 1;
collection.push(data);
if(remaining == 0){ // Finished!
d3init(collection);
}
}
function d3init(collection){
console.log('Proceeding to load d3 with');
console.log(collection);
}
按行拆分并将 header 行与内容行隔离作为 reader
的练习
这是一个只使用 d3 的解决方案。你可以看到它的实际效果 in this Plunkr.
Javascript代码是:
function multiCsv(files, callback) {
var results = [];
var error = "";
var filesLength = (files || []).length;
var callbackInvoked = false;
for (var i = 0; i < filesLength; i++) {
(function(url) {
d3.csv(url, function(data) {
if (data === null) {
error += "Error retrieving \"" + url + "\"\n";
} else {
results.push(data);
}
// all files retrieved or an error occurred
if (!callbackInvoked && (error || results.length === filesLength)) {
if (error) {
callback(error, null); // might want to send partial results here
} else {
callback(null, d3.merge(results));
}
callbackInvoked = true;
}
});
})(files[i]);
}
}
你可以这样使用它:
multiCsv(["file1.csv", "file2.csv", "file3.csv"], function (err, results) {
if (err) {
alert(err);
return;
}
var ul = document.createElement('ul');
for (var i = 0, len = results.length; i < len; i++) {
var li = document.createElement('li');
li.textContent = results[i].FirstName + ' ' + results[i].LastName + ', ' + results[i].Age;
ul.appendChild(li);
}
document.body.appendChild(ul);
});
(这只是将 <ul>
添加到包含合并数组内容的页面。
这个功能我还没有全面测试过,所以YMMV。但它适用于我在 Chrome.
中的简单测试用例
我还是 javascript 和 d3 的新手。我正在尝试找到将多个 csv 外部文件合并到 d3 中然后对其进行处理的最佳方法。目前我正在为一个文件使用如下脚本。
d3.csv("file1.csv",funciton(error,data) {
// do something
}
有什么方法可以连接 file1.csv + file2.csv + .. file9.csv 到一个文件中类似于此.. 在 d3 中?
d3.csv( concat("file1.csv","file2,csv",..file9.csv") ,function(error,data) {
// do something
}
我建议在您托管 javascript 的服务器上执行此操作,然后将单个文件提供给 d3。鉴于所有 csv 文件都是相同的格式,并且像您的示例一样按顺序命名,这是在 unix 命令行上加入它们的简单方法:
head -q -n 1 file1.csv > concat.csv #OVERWRITE with line 1 (headers)
tail -q -n +2 file*.csv >> concat.csv #APPEND lines 2+ from all matching files
编辑,暴力客户端方式,jquery:
var remaining = 0;
var collection = [];
$(document).ready(concatCSVs)
function concatCSVs(){
var uris = ['csv1.csv', 'csv2.csv'];
remaining = uris.length;
uris.forEach(function(uri){
getCSV(uri, collector)
})
}
function getCSV(uri, callback){
$.ajax(uri, {
success: callback
})
}
function collector(data){
if(remaining == 0){
throw new Error('Got more results than expected')
}
remaining -= 1;
collection.push(data);
if(remaining == 0){ // Finished!
d3init(collection);
}
}
function d3init(collection){
console.log('Proceeding to load d3 with');
console.log(collection);
}
按行拆分并将 header 行与内容行隔离作为 reader
的练习这是一个只使用 d3 的解决方案。你可以看到它的实际效果 in this Plunkr.
Javascript代码是:
function multiCsv(files, callback) {
var results = [];
var error = "";
var filesLength = (files || []).length;
var callbackInvoked = false;
for (var i = 0; i < filesLength; i++) {
(function(url) {
d3.csv(url, function(data) {
if (data === null) {
error += "Error retrieving \"" + url + "\"\n";
} else {
results.push(data);
}
// all files retrieved or an error occurred
if (!callbackInvoked && (error || results.length === filesLength)) {
if (error) {
callback(error, null); // might want to send partial results here
} else {
callback(null, d3.merge(results));
}
callbackInvoked = true;
}
});
})(files[i]);
}
}
你可以这样使用它:
multiCsv(["file1.csv", "file2.csv", "file3.csv"], function (err, results) {
if (err) {
alert(err);
return;
}
var ul = document.createElement('ul');
for (var i = 0, len = results.length; i < len; i++) {
var li = document.createElement('li');
li.textContent = results[i].FirstName + ' ' + results[i].LastName + ', ' + results[i].Age;
ul.appendChild(li);
}
document.body.appendChild(ul);
});
(这只是将 <ul>
添加到包含合并数组内容的页面。
这个功能我还没有全面测试过,所以YMMV。但它适用于我在 Chrome.
中的简单测试用例