d3js在选择新的JSON文件时不删除前一个元素

时间:2015-06-17 18:09:44

标签: d3.js

我第一次尝试退出活动时出现问题。下面的代码根据三个不同的JSON文件绘制三个圆圈中的一个。默认为中等大小的圆圈。下拉菜单允许您选择下一个要绘制的小圆,中圆或大圆。

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

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

<script>
    // data sources for small, med, large circles
  var circle1 = "/MenuSelections/circle1.JSON";
  var circle2 = "/MenuSelections/circle2.JSON";
  var circle3 = "/MenuSelections/circle3.JSON";

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

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

    //ENTER
    var circles = svgContainer.selectAll("circle")
                            .data(dataset.circle)
                            .enter()
                            .append("circle");

    var circleAttributes = circles
                         .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 - NOT WORKING. Original remains, no new graph.
   // if this section commented out: new circles draw in without remove of prev.
    d3.select("body").selectAll("circle")
       .data(dataset.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'));
    // console.log(newData); 
   drawCirc(newData); // Call with new selection.
});

1 个答案:

答案 0 :(得分:0)

Lars和Ben的建议让我走上正轨,解决方案有两个关键部分。第一个是理解exit()作用于元素,而不是它们的数据值,我需要按照上面的建议添加一个键。一旦我修复了我仍然有问题因为我在drawCirc函数中定义了我的svg容器,所以每次新的选择都会产生一个新的SVG 200x200容器。
有关Enter,Update,Exit的详细信息,请点击此处 http://bost.ocks.org/mike/circles/http://bl.ocks.org/mbostock/3808218

“使用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>