d3.js 更新前 exit().remove() 不会删除旧图表

exit().remove() doesn't remove old charts before update in d3.js

我有一个代码,用于在同一页面上使用 .each 函数和第一个 svg 创建多个图表。

 var svg = svg1.enter().append("svg:svg")
  svg.attr("class", "r_chart")
     .attr("width", left_width + width)
     .attr("height", height)
     .attr('viewBox', '0 0 350 310')
     .attr('perserveAspectRatio', 'xMinYMid')
    .each(function(d,no){
       var base = d3.select(this); 
       base.selectAll("g").data(d.values);
      ....
    })

谁能指出为什么在使用 jQuery change 函数更新 select 之前没有从 DOM 中删除旧图表?我在函数末尾有 svg1.exit().remove();

`svg1.exit().remove();`

这是在页面加载时显示的 JSON 数据

[{"name":"A","tid":"54","image":"img","measure":32,"group":"53"},
{"name":"B","tid":"55","image":"img","measure":45,"group":"53"},
{"name":"R","tid":"59","image":"img","measure":40,"group":"23"},
{"name":"T","tid":"29","image":"img","measure":20,"group":"23"}]

更新时

[{"name":"G","tid":"14","image":"img","measure":78,"group":"53"},
 {"name":"S","tid":"85","image":"img","measure":25,"group":"55"},
 {"name":"U","tid":"44","image":"img","measure":78,"group":"53"}, 
 {"name":"K","tid":"29","image":"img","measure":32.6,"group":"55"}, 
 {"name":"Y","tid":"53","image":"img","measure":30,"group":"24"},
 {"name":"O","tid":"26","image":"img","measure":25,"group":"24"}]

完整代码:

var width = 350,
    height = 310,
    barHeight = 80,
    left_width = 80,
    fo_height = 70;
var x = d3.scale.linear().range([0, width / 1.5]);
    y = d3.scale.ordinal().rangeBands([0, height]);

function chart(array){
  array = JSON.parse(array);
  console.log(array);
  var colors = ['#222','red','blue'];
  var nested_data = d3.nest().key(function(d) { return d.group; }).entries(array);
  ymax = d3.max(nested_data,function(d){
     return d.values.map(function(t){
         return t.measure;
     })
  });
  nested_data.forEach(function(nd){
    nd.values.forEach(function(d){      
      d.measure = +d.measure;
    }) 

  })
  var diff = 2;
  var tickno = 5
  var ymax = d3.max(nested_data, function(nd,k) { 
   return d3.max(nd.values,function(p,l){
      return p.measure ;
   }); 
  });
  var ymin = d3.min(nested_data, function(nd,k) { 
   return d3.min(nd.values,function(p,l){
      return p.measure - 2;
   }); 
  });

  x.domain([ymin ,ymax]);
  console.log(nested_data);
  var svg1 = d3.select('.chart').selectAll("svg").data(nested_data)
  var svg = svg1.enter().append("svg:svg")
  svg.attr("class", "r_chart")
     .attr("width", left_width + width)
     .attr("height", height)
     .attr('viewBox', '0 0 350 310')
     .attr('perserveAspectRatio', 'xMinYMid')
    .each(function(d,no){
       var count = 1;
       var base = d3.select(this); 
       var bar1 =  base.selectAll("g").data(d.values);
       var bar = bar1.enter().append("g")
           .attr("transform", function(t, i) {  
               return "translate("+left_width * count+"," + (i+0.5) * barHeight + ")"; 
               count++; 
           });

       var rule1 = base.selectAll(".rule")
        .data(x.ticks(5));
       var rule = rule1.enter().append("text");
       rule.attr("class", "rule changeprice")
        .attr("x", function(d) { return x(d) + left_width ; })
        .attr("y", barHeight /2)
        .attr("dy", -6)
        .attr("text-anchor", "middle")
        .attr("font-size", 10)
        .text(String);

       var rect =  bar.append("rect") 
            .style("fill", function(v,l) {
              return colors[l] 
            })
            .attr("width", 0)
            .attr("height", barHeight - 20)
            .attr("rx", 2)
            .attr("width", function(t){ 
              return x(t.measure) + 'px'; 
            })

           bar.append("text")
            .attr("dx", - left_width)
            .attr("dy", fo_height )
            .style("font-size",'10px') 
            .text(function(t) { return t.name; })
    }) // each fucntion
    svg1.exit().remove();
}
var array = $('#a2').text();
chart(array);

$('select').on('change',function(){
  var get = $(this).val();
  var data = $('#a'+get).text();
  chart(data)
});

给你:jsfiddle

请告知这是否是您所需要的。我改变了创建 svg1 var 的方式。更改后立即删除项目通常效果更好。我也遇到了 exit().remove() 的问题,并在很长一段时间后发现了这个问题。虽然这不是 d3 的使用方式,但效果很好。

css:

.data{display:none}

html:
<select><option>Select</option><option value='1'>1</option><option value='2'>2</option></select>
        <div class="chart"></div>
        <div id='a2' class="data">[{"name":"A","tid":"54","image":"img","measure":32,"group":"53"},{"name":"B","tid":"55","image":"img","measure":45,"group":"53"},{"name":"R","tid":"59","image":"img","measure":40,"group":"23"},{"name":"T","tid":"29","image":"img","measure":20,"group":"23"}]</div>

        <div id='a1' class='data'>[{"name":"G","tid":"14","image":"img","measure":78,"group":"53"},{"name":"S","tid":"85","image":"img","measure":25,"group":"55"},
         {"name":"U","tid":"44","image":"img","measure":78,"group":"53"}, {"name":"K","tid":"29","image":"img","measure":32.6,"group":"55"}, {"name":"Y","tid":"53","image":"img","measure":30,"group":"24"},{"name":"O","tid":"26","image":"img","measure":25,"group":"24"}]</div>


js:
    var width = 350,
        height = 310,
        barHeight = 80,
        left_width = 80,
        fo_height = 70;
    var x = d3.scale.linear().range([0, width / 1.5]);
        y = d3.scale.ordinal().rangeBands([0, height]);

    function chart(array){
      array = JSON.parse(array);
      console.log(array);
      var colors = ['#222','red','blue'];
      var nested_data = d3.nest().key(function(d) { return d.group; }).entries(array);
      ymax = d3.max(nested_data,function(d){
         return d.values.map(function(t){
             return t.measure;
         })
      });
      nested_data.forEach(function(nd){
        nd.values.forEach(function(d){      
          d.measure = +d.measure;
        }) 

      })
      var diff = 2;
      var tickno = 5
      var ymax = d3.max(nested_data, function(nd,k) { 
       return d3.max(nd.values,function(p,l){
          return p.measure ;
       }); 
      });
      var ymin = d3.min(nested_data, function(nd,k) { 
       return d3.min(nd.values,function(p,l){
          return p.measure - 2;
       }); 
      });

      x.domain([ymin ,ymax]);
      console.log(nested_data);
      svg1 = d3.select('.chart').selectAll("svg").data(nested_data)

      var svg = svg1.enter().append("svg:svg")
      svg.attr("class", "r_chart")
         .attr("width", left_width + width)
         .attr("height", height)
         .attr('viewBox', '0 0 350 310')
         .attr('perserveAspectRatio', 'xMinYMid')
        .each(function(d,no){
           var count = 1;
           var base = d3.select(this); 
           var bar1 =  base.selectAll("g").data(d.values);
           var bar = bar1.enter().append("g")
               .attr("transform", function(t, i) {  
                   return "translate("+left_width * count+"," + (i+0.5) * barHeight + ")"; 
                   count++; 
               });

           var rule1 = base.selectAll(".rule")
            .data(x.ticks(5));
           var rule = rule1.enter().append("text");
           rule.attr("class", "rule changeprice")
            .attr("x", function(d) { return x(d) + left_width ; })
            .attr("y", barHeight /2)
            .attr("dy", -6)
            .attr("text-anchor", "middle")
            .attr("font-size", 10)
            .text(String);

           var rect =  bar.append("rect") 
                .style("fill", function(v,l) {
                  return colors[l] 
                })
                .attr("width", 0)
                .attr("height", barHeight - 20)
                .attr("rx", 2)
                .attr("width", function(t){ 
                  return x(t.measure) + 'px'; 
                })

               bar.append("text")
                .attr("dx", - left_width)
                .attr("dy", fo_height )
                .style("font-size",'10px') 
                .text(function(t) { return t.name; })
        }) // each fucntion

    }
    var array = $('#a2').text();
    var svg1;
    chart(array);

    $('select').on('change',function(){
      var get = $(this).val();
      var data = $('#a'+get).text();
      svg1.remove();
      chart(data)
    });