Javascript D3.js:“我不知道你是谁。”;“在飞行中”;向数组中添加的元素不会刷新svg图形

Javascript D3.js:“我不知道你是谁。”;“在飞行中”;向数组中添加的元素不会刷新svg图形,javascript,d3.js,svg,data-visualization,Javascript,D3.js,Svg,Data Visualization,我有一排气泡,在任意给定的时间内我有6个气泡。该数组有6个json对象。代码仅显示加载时首次添加的圆。但是当我修改数组时,我想删除第一个气泡,并在行的右端添加一个气泡。我正在使用setInterval将一个元素插入数组以测试它。由于我正在记录阵列的状态,阵列正在正确更改,但是svg图形没有刷新。我只是不知道问题是否在于重新利用createElementGroup()或者在这种情况下如何删除节点(我看到常见的情况是使用exit()d3方法,但我不确定在这种特殊情况下在何处实现它) 此外,在移除和添

我有一排气泡,在任意给定的时间内我有6个气泡。该数组有6个json对象。代码仅显示加载时首次添加的圆。但是当我修改数组时,我想删除第一个气泡,并在行的右端添加一个气泡。我正在使用setInterval将一个元素插入数组以测试它。由于我正在记录阵列的状态,阵列正在正确更改,但是svg图形没有刷新。我只是不知道问题是否在于重新利用createElementGroup()或者在这种情况下如何删除节点(我看到常见的情况是使用exit()d3方法,但我不确定在这种特殊情况下在何处实现它)

此外,在移除和添加元素时,应将过渡放置在何处以使其平滑?。现场演示如下:

(您可以单击气泡以查看其展开并显示数据,这样我可以检查是否是正确的节点)

守则:

//listener that will be executed on setIntervalCheck to update the graphic   
setInterval(function(){
  moveForwardOnBubbleList();
  createElementGroup();
  }, 100000);



var profile_pic_url="https://scontent.fsst1-2.fna.fbcdn.net/v/t1.0-9/13680856_103268503450198_1479797031996897052_n.jpg?oh=f43bced91822fb210c8be8a410825da9&oe=58D46460";

var dataset = [{unique_followers: 5, profile_pic:profile_pic_url}, {unique_followers: 10, profile_pic:profile_pic_url},{ unique_followers: 15, profile_pic:profile_pic_url}, { unique_followers: 20, profile_pic:profile_pic_url}, { unique_followers: 25, profile_pic:profile_pic_url}, {unique_followers: 40, profile_pic:profile_pic_url} ];

var w=600,h=600;

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

//1st level:All circles group
var circlesGroup = svg.append("g").classed("general-group",true);
//2nd level: Group of circle and text
var elementGroup;

var circle;

var circleAttributes;
//create g's of existing data
createElementGroup();

elementGroup.on('click', function(d,i){
  var that=this;

  d3.selectAll('.element-group').each(function(d,i) {
    if(this.id!==that.id){
      d3.select(this).classed("selected",false);
    }
  });

  d3.select(this).classed("selected", !d3.select(this).classed("selected"));

  });

//adding circular background image to the circles
//var circlesSelection=svg.selectAll('circle');


function createElementGroup(){
  elementGroup = circlesGroup
  .selectAll('circle')
  .data(dataset)
  .enter()
  .append("g").classed("element-group",true);

  circle=elementGroup.append('circle');

  circleAttributes = circle
  .attr("r", 20)
  .attr("stroke","black")
  .attr("fill", "white")
  .classed("circle",true);

  //text to show
   elementGroup.append("text")
      .attr("text-anchor", "middle")
   .text(function(d) {
     return parseInt(d.unique_followers);
   })
     .style("pointer-events","none")
     .classed('tweet-number', true);

     //image to show as background

  //element group positioning for the text to be inside circle
  elementGroup.attr("transform", function(d,i){
    return "translate(" + (i*80+45) + "," + h/2 + ")"; 
});

  elementGroup.attr( "fill-opacity", 0 ).transition().duration(500).attr( "fill-opacity", 1 );
  elementGroup.attr("id", function(d, i) { return "c"+i; });


}

function addBubbleLast(){
    dataset.push({unique_followers: 40, profile_pic:profile_pic_url});
}

function removeFirstBubble(){
  dataset.shift();

}

function moveForwardOnBubbleList(){
  addBubbleLast();
  removeFirstBubble();
}



/*CSS*/
 body
        {
          /*padding-top: 50px;*/
          padding-left: 100px;
        }

        .tweet-number{
         opacity:0.25;
        }

        .circle{

        }


        .selected *{
          transform: scale(2);
          transition: all 0.5s ease, opacity 0.5s ease;
          opacity:1.0;
    }
编辑:修复了Gerardo Furtado的伟大建议后的代码。如果有人遇到类似问题,我会发布:

//listener that will be executed on setIntervalCheck to update the graphic   
setInterval(function(){
  moveForwardOnBubbleList();
  createElementGroup();
  }, 6000);



var profile_pic_url="https://scontent.fsst1-2.fna.fbcdn.net/v/t1.0-9/13680856_103268503450198_1479797031996897052_n.jpg?oh=f43bced91822fb210c8be8a410825da9&oe=58D46460";

var dataset = [{unique_followers: 5, profile_pic:profile_pic_url}, {unique_followers: 10, profile_pic:profile_pic_url},{ unique_followers: 15, profile_pic:profile_pic_url}, { unique_followers: 20, profile_pic:profile_pic_url}, { unique_followers: 25, profile_pic:profile_pic_url}, {unique_followers: 40, profile_pic:profile_pic_url} ];

var w=900,h=600;

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

//1st level:All circles group
var circlesGroup = svg.append("g").classed("general-group",true);
//2nd level: Group of circle and text
var elementGroup;

var circle;

var circleAttributes;
//create g's of existing data
createElementGroup();



//adding circular background image to the circles
//var circlesSelection=svg.selectAll('circle');


function createElementGroup(){
  elementGroup = circlesGroup
  .selectAll('.element-group')
  .data(dataset, function(d){ return d.unique_followers});
 //doesn't work the exit transition 
   var elementExit = elementGroup.exit().transition().duration(1000).style("opacity", 0).remove();

  var elementEnter = elementGroup.enter()
  .append("g").classed("element-group",true).style("opacity",0);

    elementEnter.merge(elementGroup).attr("transform", function(d,i){

   //option 1 generation by mod   
   if(i%2===0){   
    return "translate(" + (i*80+45) + "," + h/1.55 + ")"; 
   }else{
    return "translate(" + (i*80+45) + "," + h/1.45 + ")"; 

   }

  /*   
  //option 2 random
  var random= (Math.random() * (1.6 - 1.45) + 1.45).toFixed(4);

         return "translate(" + (i*80+45) + "," + h/random + ")";*/ 


}).transition().duration(2000).style("opacity", 1.0);

    circle=elementEnter.append('circle');



  circleAttributes = circle
  .attr("r", 20)
  .attr("stroke","black")
  .attr("fill", "white")
  .classed("circle",true);

  d3.selectAll('.element-group').on('click', function(d,i){
  var that=this;
  d3.selectAll('.element-group').each(function(d,i) {
    if(this.id!==that.id){
      d3.select(this).classed("selected",false);
    }
  });

  d3.select(this).classed("selected", !d3.select(this).classed("selected"));

  });

  //text to show
   var texts = elementEnter.append("text")
      .attr("text-anchor", "middle")
   .text(function(d) {
     return parseInt(d.unique_followers);
   })
     .style("pointer-events","none")
     .classed('tweet-number', true);

     //image to show as background

  //element group positioning for the text to be inside circle



}

function addBubbleLast(){

  var random=Math.floor(Math.random() * (40)) + 1;


    dataset.push({unique_followers: random, profile_pic:profile_pic_url});
}

function removeFirstBubble(){
  dataset.shift();

}

function moveForwardOnBubbleList(){
  addBubbleLast();
  removeFirstBubble();
}

//CSS

    body
    {
      /*padding-top: 50px;*/
      padding-left: 100px;
    }

    .tweet-number{
     opacity:0.25;
    }

    .circle{

    }

 .selected *{
      transform: scale(2);
      transition: all 0.5s ease;
      opacity:1.0;
}

.element-group *{
  transition: all 0.5s ease;
}

circle + text{
}
您需要“输入”、“退出”和“更新”选项

首先,我们绑定数据(使用一个键函数):

然后,我们设置输入选择:

var elementEnter = elementGroup.enter()
    .append("g").classed("element-group",true);
elementEnter.merge(elementGroup).attr("transform", function(d,i){
    return "translate(" + (i*80+45) + "," + h/2 + ")"; 
});
var elementExit = elementGroup.exit().remove();
现在有一个重要的注意事项:由于这是D3 v4.x,您需要修改这些选项以获得一个可用的更新选项:

var elementEnter = elementGroup.enter()
    .append("g").classed("element-group",true);
elementEnter.merge(elementGroup).attr("transform", function(d,i){
    return "translate(" + (i*80+45) + "," + h/2 + ")"; 
});
var elementExit = elementGroup.exit().remove();
最后,退出选择:

var elementEnter = elementGroup.enter()
    .append("g").classed("element-group",true);
elementEnter.merge(elementGroup).attr("transform", function(d,i){
    return "translate(" + (i*80+45) + "," + h/2 + ")"; 
});
var elementExit = elementGroup.exit().remove();

这是您的代码笔:

两个问题:1)您知道我的点击事件为何死亡吗?。它过去会将气泡扩大两倍,现在修改后就不起作用了2)为什么在数据集上使用“键函数”?为什么要将元素绑定到该数字?键函数“将数据点作为输入并返回相应的键:一个字符串,如名称,唯一标识数据点。”关于单击事件:我没有为您更改代码的其他部分,这是您现在的工作,我只是向您展示了如何处理选择。您必须相应地重写整个代码。谢谢,我必须看看出了什么问题,但我还有一个问题,是否每次在这里重新引用元素都是因为不知道正确的方式…因为我将创建退出和更新放在了要重新使用的函数上…单击事件是否与动态生成的元素有问题,就像以前在jquery中发生的那样??这就是我问你的原因是的,你可能会遇到一些问题。最佳做法是将单击事件放在“输入+更新”选择之后。谢谢…我已经修复了它。。。。。我在enter+update和选择器之后更改了它,而不是使用elementGroup。在('click')上,我使用了d3.selectAll('.element group')。在('click')上