D3.js d3js在选择新JSON文件时不删除上一个元素

D3.js d3js在选择新JSON文件时不删除上一个元素,d3.js,D3.js,我第一次尝试退出事件时遇到问题。下面的代码基于三个不同的JSON文件绘制了三个圆圈中的一个。默认为中等大小的圆。下拉菜单允许您选择下一步要绘制的小圆圈、中圆圈或大圆圈 我的问题是我没有正确编写退出模式。如果我将退出注释掉,那么每个选择都会出现在屏幕上,而不会像您所期望的那样删除前面的任何元素。如果退出模式未注释掉,则仅显示默认的中间圆圈。 这对于有D3JS经验的人来说可能非常明显。请帮助我了解我哪里出了问题。非常感谢! -提姆 拉尔斯和本的建议让我走上了正确的道路,解决方案有两个关键部分。第一个

我第一次尝试退出事件时遇到问题。下面的代码基于三个不同的JSON文件绘制了三个圆圈中的一个。默认为中等大小的圆。下拉菜单允许您选择下一步要绘制的小圆圈、中圆圈或大圆圈

我的问题是我没有正确编写退出模式。如果我将退出注释掉,那么每个选择都会出现在屏幕上,而不会像您所期望的那样删除前面的任何元素。如果退出模式未注释掉,则仅显示默认的中间圆圈。 这对于有D3JS经验的人来说可能非常明显。请帮助我了解我哪里出了问题。非常感谢! -提姆


拉尔斯和本的建议让我走上了正确的道路,解决方案有两个关键部分。第一个是理解exit作用于元素,而不是它们的数据值,我需要像上面建议的那样添加一个键。一旦我修复了这个问题,我仍然有一个问题,因为我在drawCirc函数中定义了我的svg容器,所以每次新的选择都会产生一个新的svg200x200容器。 在这里可以找到有关进入、更新和退出的详细信息 这里呢

《D3和AngularJS数据可视化》一书第1章第13-16页也很有帮助。 这是我修改过的代码

<body>
<select id = "opts">
  <option value="circle1">Small</option>
  <option value="circle2" selected="selected">Medium</option> 
  <option value="circle3">Large</option>
</select> 

<script>
    // var names correspond to the value of each drop down item
  var circle1 = "/MenuSelections/circle1.JSON";
  var circle2 = "/MenuSelections/circle2.JSON";
  var circle3 = "/MenuSelections/circle3.JSON";

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

  function drawCirc(newData){   
      console.log(newData);  // Confirms data source
      // Read in the JSON data
      d3.json(newData, function(dataset) {

    //ENTER
    var circle = svg.selectAll("circle")
                    .data(dataset.circle, function(d) {return d;});

    circle.enter().append("circle");

    circle.attr("cx", function (d) { 
                             console.log(d)                         
                               return d.x_axis; })
          .attr("cy", function (d) { return d.y_axis; })
          .attr("r", function (d) { return d.radius; })
          .style("fill", function(d) { return d.color; });

     //EXIT                     
     circle.exit().remove();
    });
}
drawCirc(circle2); // Initiate with default selection 

// handle on click event for the ID (opts) of the menu item
d3.select('#opts')
  .on('change', function() {
    var newData = eval(d3.select(this).property('value'));
   drawCirc(newData); // Call with new selection.
});
</script>
</body>

如果只有一个圆,那么就不需要使用D3的数据匹配。你可以在添加新的圆之前删除现有的圆。没错,拉尔斯。但是,我正在努力使这段代码正常工作,以便在选择不同的JSON文件的基础上,将相同的方法应用于一系列复杂的图形。选择一个JSON数据源,查看该图。选择一个不同的JSON文件并查看新的图形,等等。在本例中,请参阅第二次调用drawCirc,尤其是.data。。。调用时,新圆圈将在更新选择中绑定。您的代码仅在“输入”选项上运行。在这种情况下,退出选择将为空,因为您有一个数据值和一个圆元素,所以不需要删除任何内容。您可以通过为.data指定一个键函数来解决此问题。。。根据我对拉尔斯所联系问题的回答,致电。您还可以通过更新drawCirc函数中的更新选择来修复它,而不仅仅是输入选择。
<body>
<select id = "opts">
  <option value="circle1">Small</option>
  <option value="circle2" selected="selected">Medium</option> 
  <option value="circle3">Large</option>
</select> 

<script>
    // var names correspond to the value of each drop down item
  var circle1 = "/MenuSelections/circle1.JSON";
  var circle2 = "/MenuSelections/circle2.JSON";
  var circle3 = "/MenuSelections/circle3.JSON";

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

  function drawCirc(newData){   
      console.log(newData);  // Confirms data source
      // Read in the JSON data
      d3.json(newData, function(dataset) {

    //ENTER
    var circle = svg.selectAll("circle")
                    .data(dataset.circle, function(d) {return d;});

    circle.enter().append("circle");

    circle.attr("cx", function (d) { 
                             console.log(d)                         
                               return d.x_axis; })
          .attr("cy", function (d) { return d.y_axis; })
          .attr("r", function (d) { return d.radius; })
          .style("fill", function(d) { return d.color; });

     //EXIT                     
     circle.exit().remove();
    });
}
drawCirc(circle2); // Initiate with default selection 

// handle on click event for the ID (opts) of the menu item
d3.select('#opts')
  .on('change', function() {
    var newData = eval(d3.select(this).property('value'));
   drawCirc(newData); // Call with new selection.
});
</script>
</body>