我正在尝试使用for循环动态地将图形添加到我的网页。每个图表在一个表的单独行中。 但只显示最后一个图表。对于其他人来说,g元素没有被添加。
这是最后一个图的层次结构(成功的一个): - tr - > td - > svg - > g(变换) - > g(x轴) - > g(y轴) - >路径
另一方面是: - tr - > td - > svg - >克(变换)
在进一步分析中,我发现在成功的图形中,路径,x和y轴被添加了很多次,因为循环正在运行。
这是我的代码: -
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d[xA]); })
.y(function(d) { return y(d[yA]); });
for(var i = 0; i < yAV.length; i++){
var yA = yAV[i];
// Adds the svg canvas
chart1 = d3.select("#graph table")
.append("tr")
.append("td")
.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.json("graphdata.json", function(error, data) {
data.forEach(function(d) {
d[xA] = +d[xA];
d[yA] = +d[yA];
});
x.domain(d3.extent(data, function(d) { return d[xA]; }));
y.domain(d3.extent(data, function(d) { return d[yA]; }));
// Add the X Axis
chart1.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart1.append("g")
.attr("class", "y axis")
.call(yAxis);
// Add the valueline path.
chart1.append("path")
.attr("class", "line")
.attr("d", valueline(data));
});
}
请帮我解决这个问题。
答案 0 :(得分:0)
d3.json中的回调是异步。你期望它像这样运行:
loop iteration 1:
chart1 = add new svg/g
d3.json add stuff to chart1
loop iteration 2:
chart1 = add new svg/g
d3.json add stuff to chart1
loop iteration 3: etc
但d3.json回调仅在数据加载时运行,而基于浏览器的javascript只在javascript完成当前代码(整个循环)时运行 - 请参阅Javascript asynchronous execution: will a callback interrupt running code?。
所以你会得到的是:
loop iteration 1:
chart1 = add svg/g
loop iteration 2:
chart1 = add svg/g
loop iteration3: etc
end of loop
then
a set of d3.json callbacks adding stuff to last value of chart1
最后一行就是为什么你只看到d3.json回调中的元素添加到一个svg
要修复它,你需要在d3.json回调中添加一个计数器,该回调在每次运行时递增以访问svg元素和数据集的正确索引(认为它似乎每次都是相同的数据集?)< / p>