我正在研究d3中的条形图,该条形图应该采用小型随机模拟模型的结果(在这种情况下,感染传染病的易感染恢复模型)并绘制新人数每天被感染为图表中条形的高度。
这在我第一次运行模型时工作正常,但随后在后续运行中(使用模拟()函数或html中的“单击我”按钮)应该替换的旧元素(即个人数量)在最后一次运行中第1天被感染的)没有出现在退出选择中,该选择始终为空。相反,新的条形图始终添加到最后,或涂在现有的条形图上。
我尝试了许多关键功能(包括没有键功能,并将整数倍转换为字符串)。我确定我做错了什么,但我不确定那是什么东西。所以任何建议都将不胜感激。
您还可以在此处找到此半工作代码的工作演示:
http://bl.ocks.org/jzelner/e06e2997429ada3534dc
谢谢!
var max_t = 20; N = 100; b = 1.1 total_id = 0;
function outbreak() {
var S = N-1;
var I = 1;
var done = 0;
var incidence = [{t:0, I:I, name: String(0)}];
for (t = 1; t < max_t; t++) {
var p_inf = 1.0-Math.exp(-b*I/N);
var new_I = 0;
for (i = 0; i < S; i++) {
if (Math.random() < p_inf) {
new_I++;
}
}
if (new_I == 0) {
break;
done = 1;
}
incidence.push({t:t, I:new_I, name:String(t)});
total_id++;
S -= new_I;
I = new_I;
}
return(incidence);
}
incidence = outbreak();
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Parse the date / time
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var svg = d3.select("body").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 + ")");
xvals = [];
for (i = 0; i <= 20; i++){
xvals.push(i);
}
x.domain(xvals);
y.domain([0, 20]);
function render(zz) {
console.log(zz)
var bar = svg.selectAll("bar")
.data(zz, function(d) { return d.name;});
bar.exit().remove();
bar.attr("class", "update")
.attr("x", function(d) { return x(d.t); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.I); })
.attr("height", function(d) { return height - y(d.I); });
console.log("UPDATE", bar)
console.log("ENTER", bar.enter())
bar.enter().append("rect")
.attr("class", "enter")
.attr("x", function(d) { return x(d.t); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.I); })
.attr("height", function(d) { return height - y(d.I); });
bar
.attr("x", function(d) { return x(d.t); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.I); })
.attr("height", function(d) { return height - y(d.I); });
}
render(incidence);
function simulate() {
render(outbreak());
}
答案 0 :(得分:0)
如评论中所述,这样做:
svg.selectAll("path")
.attr({
d: line(data)
});
而不是:
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", line);
解决了我的问题。