简体   繁体   English

更新时未从d3条形图中删除旧元素

[英]old elements not removed from d3 bar chart on update

I'm working on a bar chart in d3 that is supposed to take the results of a small stochastic simulation model (in this case, the susceptible-infected-recovered model of infectious disease transmission) and plot the number of new people infected on each day as the height of the bars in the chart. 我正在使用d3中的条形图,该条形图应该采用小的随机模拟模型(在这种情况下,是传染病传播的易感感染恢复模型)的结果,并绘制每个图上感染的新人的数量天为图表中条形的高度。

This works fine when I run the model the first time, but then on subsequent runs (using the simulate() function or 'click me' button in the html) the old elements that should be replaced (ie the number of individuals infected on day 1 in the last run) are not showing up in the exit selection, which is always empty. 当我第一次运行模型时,这种方法效果很好,但随后的运行(使用simulate()函数或html中的“单击我”按钮)则应替换旧元素(即,当日感染的个体数量) 1)(最后一次运行中的1)未显示在退出选择中,退出选择始终为空。 Instead, new bars are consistently added to the end or are painted over existing bars. 取而代之的是,将新的条形图始终添加到末尾或在现有条形图上进行绘制。

I have tried a number of key functions (including no key function, and converting the integer times to strings). 我尝试了许多键函数(包括没有键函数,并将整数倍转换为字符串)。 I'm sure I'm doing something wrong, but am not sure what that something is. 我确定我做错了什么,但是不确定那是什么。 So any advice would be greatly appreciated. 因此,任何建议将不胜感激。

You can also find a working demo of this semi-working code here: 您还可以在这里找到此半工作代码的工作演示:

http://bl.ocks.org/jzelner/e06e2997429ada3534dc http://bl.ocks.org/jzelner/e06e2997429ada3534dc

Thanks! 谢谢!

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());
}

As explained in the comments, doing this: 如评论中所述,执行以下操作:

svg.selectAll("path")
    .attr({
      d: line(data)
    });

instead of this: 代替这个:

svg.append("path")
    .data([data])
    .attr("class", "line")
    .attr("d", line);

solved my problem. 解决了我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM