如何为每个for循环迭代创建单独的标记?

时间:2018-04-16 06:17:07

标签: javascript html d3.js

我正在使用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";
                    });
        })
}

1 个答案:

答案 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>,您可以保留外部计数器,就像我在这里做的那样,但仅作为示例(它不是一个好方法)。