我正在使用d3和javascript在html页面的列中显示来自csv文件的数据。对于一个csv来说,一切都运行良好和花花公子 (html输出看起来像这样)
<div class="column" style="background-color:#aaa;">
<h2>Column 1</h2>
// p tags generated from csv here
</div>
对于多列,html应该如下所示:
<div class="column" style="background-color:#aaa;">
<h2>Column 1</h2>
// p tags generated from csv here
</div>
<div class="column" style="background-color:#aaa;">
<h2>Column 2 </h2>
// p tags generated from csv 2 here
</div>
<div class="column" style="background-color:#aaa;">
<h2>Column n </h2>
// p tags generated from csv n here
</div>
但是,尝试在循环中生成标记时的输出只是:
<div class="column" style="background-color:#aaa;">
<h2>Column n </h2>
// p tags generated from csv n here
</div>
只有最后一个csv被写入dom,我不知道为什么。到目前为止,我的代码看起来像这样:
var i;
array = ["72.csv", "122.csv", "124.csv", "12.csv",]
for (i = 0; i < 4; i++) {
document.getElementById("inner").innerHTML="<div class=\"column\" style=\"background-color:#aaa;\">";
var dataPath = array[i]
d3.csv(dataPath, function (error, data){
var myData = data;
var booksExtent = d3.extent(myData, function(d) {
return parseInt(d.score)
});
var scale = d3.scaleLinear()
.range([9, 20])
.domain([12,85])
d3.select(".column")
.selectAll("p")
.data(myData)
.enter()
.append("p")
.text(function(d){
return d.word;
})
.style("font-size", function (d)
{
return scale(parseInt(d.score)) + "pt";
});
})
}
答案 0 :(得分:1)
这里存在一个基本问题,即使用 for loop 和异步函数。它根本不会工作。
这就是问题所在:
d3.csv
是一个异步函数,即代码不等待响应(如果你正在使用D3 v4,则为XHR,如果您使用D3 v5则承诺)来自d3.csv
,其余部分继续运行。因此,for
循环在进行下一次迭代之前不会等待每个d3.csv
个完成:事实上,for
循环将运行到最后几毫秒。
因此,您必须重构所有代码。
有几种方法可以解决此问题。这是一个可能的解决方案,它不是最优雅的,但它很容易理解:执行4个单独的d3.csv
调用,每个CSV一个,并将数据传递给附加元素的函数: / p>
d3.csv("72.csv", createElements);
d3.csv("122.csv", createElements);
d3.csv("124.csv", createElements);
d3.csv("12.csv", createElements);
var counter = 0;
function createElements(myData) {
counter++;
var div = d3.select("#inner")
.append("div")
.attr("class", "column")
.style("background-color", "#aaa");
div.append("h1")
.text("Column " + counter);
var booksExtent = d3.extent(myData, function(d) {
return parseInt(d.score)
});
var scale = d3.scaleLinear()
.range([9, 20])
.domain([12, 85]);
div.selectAll(null)
.data(myData)
.enter()
.append("p")
.text(function(d) {
return d.word;
})
.style("font-size", function(d) {
return scale(parseInt(d.score)) + "pt";
});
}
要创建<h1>
,您可以保留外部计数器,就像我在这里做的那样,但仅作为示例(它不是一个好方法)。