I am having problem when generating 15 line-chars from 15 .csv files by using a for loop. Instead of locating each graph in a different div, 15 graphs all overlapped in the last div.
Thank you in advance.
for (var i = 0; i<15; i++) { var svg = d3.select("#graph_"+i) .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // Get the data d3.csv(folder.toString()+"/"+i+".csv", function(error, data) { data.forEach(function(d) { dx = +dx; dy = +dy; }); // Scale the range of the data x.domain(d3.extent(data, function(d) { return dx; })); y.domain([0, d3.max(data, function(d) { return dy; })]); // Add the valueline path. svg.append("path") .attr("class", "line") .attr("d", valueline(data)); // Add the X Axis svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); // Add the Y Axis svg.append("g") .attr("class", "y axis") .call(yAxis); }); }
You have a classic async
race condition. Think about your code:
for (var i = 0; i<15; i++) {
var svg = d3.select("#graph_"+i)
...
d3.csv(folder.toString()+"/"+i+".csv", function(error, data) {
...
d3.csv
is async ; when it completes it fires it's callback. By the time the first d3.csv
finishes, your for loop has already completed and your svg
variable is holding a reference to your last div.
The easiest way to fix your problem is with a closure:
for (var i = 0; i<15; i++) {
// closure around svg to keep the proper one in scope
(function() {
var svg = d3.select("#graph_"+i);
...
d3.csv(folder.toString()+"/"+i+".csv", function(error, data){
// svg is now what you are looking for
...
})
})();
}
Here's a quick demonstration of this approach.
Stuff like this is why I love JavaScript!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.