Javascript 与d3.js版本3的选择相混淆

Javascript 与d3.js版本3的选择相混淆,javascript,d3.js,Javascript,D3.js,我正在玩d3.js版本3(抱歉,它不是4。),对它的嵌套选择感到困惑 在下面的代码中,我打算为包含当前时间的三层二叉树单元设置动画: <!doctype html> <html> <head> <script src="http://d3js.org/d3.v3.min.js"></script> </head> <body> <script> functio

我正在玩d3.js版本3(抱歉,它不是4。),对它的嵌套选择感到困惑

在下面的代码中,我打算为包含当前时间的三层二叉树单元设置动画:

<!doctype html>
<html>
  <head>
    <script src="http://d3js.org/d3.v3.min.js"></script>
  </head>
  <body>

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

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

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

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

      setInterval("f()", 1000);
    </script>
  </body>
</html>

函数f(){
var ps0=d3.选择(“主体”);
var ps1=ps0.selectAll(“div”).data([new Date(),new Date()]);
ps1.enter().append(“div”).style(“背景”、“红色”);
文本(函数(x){return“red”+x;});
ps1.exit().remove();
var ps2=ps1.selectAll(“div”).data([new Date(),new Date()]);
ps2.enter().append(“div”).style(“背景”、“绿色”);
文本(函数(x){返回“绿色”+x;});
ps2.exit().remove();
var ps3=ps2.selectAll(“div”).data([new Date(),new Date()]);
ps3.enter().append(“div”).style(“背景”、“蓝色”);
文本(函数(x){返回“蓝色”+x;});
ps3.exit().remove();
}
设置间隔(“f()”,1000);
在第一次调用时,它精确地绘制了我想要的内容:2个红色单元格、4个绿色单元格和8个蓝色单元格。但从第二个球开始,它只在上半场打成平局,而下半场则被踢出

我想我误解了d3的嵌套选择,但仍然无法找到它为什么会这样工作以及如何修复它。感谢您的帮助

执行此操作时:

var ps1 = ps0.selectAll("div")...
var ps2 = ps1.selectAll("div")...
var ps3 = ps2.selectAll("div")...
您正在选择预先存在的div,并将数据绑定到它们。那不是你想要的

解决方案:对于每个选择,仅选择属于该选择的div。一种简单的方法是按类设置和选择:

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 --^
以下是您的更新代码:

函数f(){
var ps0=d3.选择(“主体”);
var ps1=ps0.selectAll(“.ps1”).data([new Date(),new Date()]);
ps1.enter().append(“div”).style(“背景”,“红色”).attr(“类”,“ps1”);
ps1.文本(函数(x){
返回“红色”+x;
});
ps1.exit().remove();
var ps2=ps1.selectAll(“.ps2”).data([new Date(),new Date()]);
输入().append(“div”).style(“背景”、“绿色”).attr(“类”、“ps2”);
ps2.文本(函数(x){
返回“绿色”+x;
});
ps2.exit().remove();
var ps3=ps2.selectAll(“.ps3”).data([new Date(),new Date()]);
输入().append(“div”).style(“背景”,“蓝色”).attr(“类”,“ps3”);
ps3.文本(函数(x){
返回“蓝色”+x;
});
ps3.exit().remove();
}
设定间隔(f,1000)
执行此操作时:

var ps1 = ps0.selectAll("div")...
var ps2 = ps1.selectAll("div")...
var ps3 = ps2.selectAll("div")...
您正在选择预先存在的div,并将数据绑定到它们。那不是你想要的

解决方案:对于每个选择,仅选择属于该选择的div。一种简单的方法是按类设置和选择:

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 --^
以下是您的更新代码:

函数f(){
var ps0=d3.选择(“主体”);
var ps1=ps0.selectAll(“.ps1”).data([new Date(),new Date()]);
ps1.enter().append(“div”).style(“背景”,“红色”).attr(“类”,“ps1”);
ps1.文本(函数(x){
返回“红色”+x;
});
ps1.exit().remove();
var ps2=ps1.selectAll(“.ps2”).data([new Date(),new Date()]);
输入().append(“div”).style(“背景”、“绿色”).attr(“类”、“ps2”);
ps2.文本(函数(x){
返回“绿色”+x;
});
ps2.exit().remove();
var ps3=ps2.selectAll(“.ps3”).data([new Date(),new Date()]);
输入().append(“div”).style(“背景”,“蓝色”).attr(“类”,“ps3”);
ps3.文本(函数(x){
返回“蓝色”+x;
});
ps3.exit().remove();
}
设定间隔(f,1000)

现在我了解了selectAll不仅从上到下遍历直接子节点,而且还遍历当前选择的所有子节点。现在我了解了selectAll不仅从上到下遍历直接子节点,而且从上到下遍历当前选择的所有子节点。