Javascript 如何使用d3在散点图上逐个绘制/添加节点?

Javascript 如何使用d3在散点图上逐个绘制/添加节点?,javascript,d3.js,scatter-plot,Javascript,D3.js,Scatter Plot,我对D3.js和Javascript都很陌生。对不起,如果你问了一些愚蠢的问题。 我刚刚完成了D3教程,现在可以绘制保存在我的csv文件中的所有数据了(通过D3.csv函数加载) 我很好奇,有没有可能一点一点地画出来,而不是一次画出来 var dataset; d3.csv("testcase.csv", function(data) { dataset = data; var w = $(window).width(); var h = $(window).heigh

我对D3.js和Javascript都很陌生。对不起,如果你问了一些愚蠢的问题。 我刚刚完成了D3教程,现在可以绘制保存在我的csv文件中的所有数据了(通过
D3.csv
函数加载)

我很好奇,有没有可能一点一点地画出来,而不是一次画出来

var dataset;
d3.csv("testcase.csv", function(data) { 
    dataset = data;
    var w = $(window).width();
    var h = $(window).height();

    var svg = d3.select("body")
                .append("svg")
                .attr({
                    width: w,
                    height: h,
                });

    function draw(data){
        var circle = svg.selectAll("circle")
                    .data(data);

        circle.enter().append("circle")
              .attr({
                  "cx": data["x"],
                  "cy": data["y"],
                  "r": data["r"],
                  "fill": "rgb(0,0,0)",
              });
    }

    draw(dataset[0]);

    var index = 1;
    setInterval(function() {
        if(index<dataset.length){
          draw(dataset[index]);
          index++;
        }
     }, 1500);
var数据集;
d3.csv(“testcase.csv”,函数(数据){
数据集=数据;
var w=$(window.width();
var h=$(window.height();
var svg=d3.选择(“主体”)
.append(“svg”)
艾特先生({
宽度:w,
高度:h,,
});
函数图(数据){
var circle=svg.selectAll(“circle”)
.数据(数据);
circle.enter().append(“circle”)
艾特先生({
“cx”:数据[“x”],
“cy”:数据[“y”],
“r”:数据[“r”],
“填充”:“rgb(0,0,0)”,
});
}
绘制(数据集[0]);
var指数=1;
setInterval(函数(){

如果(index因此,您遇到了d3中新出现的一个相当常见的逻辑错误。每次调用draw函数时,您也会重新绑定数据。然而,除了告诉d3有关新数据的信息外,这也会清除d3对旧数据的记忆。因此,您实际上是在告诉d3:新数据是真实的,忘记我在中告诉过您的任何数据过去

好的,上面有点简单化了

d3实际上并没有忘记您已经告诉它的内容。但是,它需要一种方法来了解什么是新的,什么是已经存在的,什么是旧的。为此,
.data
根据数据数组中的索引为每个数据分配一个键。因为每次您只绑定一个元素,它总是会得到一个0的键。因此,d3从不认为您是一个我们要求它绑定新的东西

要解决此问题,请将一个键函数传递给
数据

然后,您的代码应该遵循以下几行:

function draw(data, key){
    var circle = svg.selectAll("circle")
                .data(data, function(d){ return key; });

    circle.enter().append("circle")
          .attr({
              "cx": data["x"],
              "cy": data["y"],
              "r": data["r"],
              "fill": "rgb(0,0,0)",
          });
}

draw(dataset[0], 0);

var index = 1;
setInterval(function() {
    if(index<dataset.length){
      draw(dataset[index], index);
      index++;
    }
 }, 1500);
功能图(数据、键){
var circle=svg.selectAll(“circle”)
.data(数据,函数(d){返回键;});
circle.enter().append(“circle”)
艾特先生({
“cx”:数据[“x”],
“cy”:数据[“y”],
“r”:数据[“r”],
“填充”:“rgb(0,0,0)”,
});
}
绘制(数据集[0],0);
var指数=1;
setInterval(函数(){

如果(索引遵循Matthew的答案,如果您使用d3转换而不是setInterval,那么您不必构建单独处理节点的循环,也可以避免他描述的问题(至少在第一次通过时,以后添加更多节点,您将再次需要数据键)

var data=“x,y,r\n”+
“100100,50\n”+
“200100,30\n”+
“400300,20\n”+
“500400,50\n”+
“470800,40\n”+
“400600,40\n”
;
var dataset=d3.csv.parse(数据);
var svg=d3.选择(“主体”)
.append(“svg”)
艾特先生({
宽度:600,
身高:400,
});
var circle=svg.selectAll(“circle”)
.数据(数据集);
circle.enter().append(“circle”)
.每个(功能(d,i){
d3.选择(this).transition()

.delay(i*1200)//谢谢分享!我将浏览文档并尝试修复它!这看起来很神奇!真的感谢你的回答!我将尝试浏览文档并稍后再试!@Casmo这是迄今为止实现你预期目标的最佳解决方案。谢谢,你给了我一个类似的解决方案的想法。我正在研究。:)@好的!谢谢分享:D
     var data = "x,y,r\n"+
"100,100,50\n"+
"200,100,30\n"+
"400,300,20\n"+
"500,400,50\n"+
"470,800,40\n"+
"400,600,40\n"
;

var dataset = d3.csv.parse (data);

var svg = d3.select("body")
.append("svg")
.attr({
  width: 600,
  height: 400,
});

var circle = svg.selectAll("circle")
.data(dataset);

circle.enter().append("circle")
  .each (function (d,i) {
  d3.select(this).transition()
    .delay(i * 1200)  // <- this does what you intended setinterval to do
    .attr({
    "cx": d.x,
    "cy": d.y,
    "r": d.r,
    "fill": "rgb(0,0,0)",
  });

});
;