score:2

Accepted answer

When you do this:

var ps1 = ps0.selectAll("div")...
var ps2 = ps1.selectAll("div")...
var ps3 = ps2.selectAll("div")...

You are selecting pre-existing divs, and binding data to them. That's not what you want.

Solution: for each selection, select only the divs belonging to that selection. An easy way to do that is setting and selecting by class:

var ps1 = ps0.selectAll(".ps1")
    //select by class -----^
    .data([new Date(), new Date()]);

ps1.enter().append("div")
    .style("background", "red")
    .attr("class", "ps1");
    //set the class --^

Here is your updated code:

function f() {
  var ps0 = d3.select("body");

  var ps1 = ps0.selectAll(".ps1").data([new Date(), new Date()]);
  ps1.enter().append("div").style("background", "red").attr("class", "ps1");
  ps1.text(function(x) {
    return "red " + x;
  });
  ps1.exit().remove();

  var ps2 = ps1.selectAll(".ps2").data([new Date(), new Date()]);
  ps2.enter().append("div").style("background", "green").attr("class", "ps2");
  ps2.text(function(x) {
    return "green " + x;
  });
  ps2.exit().remove();

  var ps3 = ps2.selectAll(".ps3").data([new Date(), new Date()]);
  ps3.enter().append("div").style("background", "blue").attr("class", "ps3");
  ps3.text(function(x) {
    return "blue " + x;
  });
  ps3.exit().remove();
}

setInterval(f, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


Related Query

More Query from same tag