jsc0218
jsc0218

Reputation: 482

Existing Triangles Cannot be Removed

I bind triangles with data in D3.js. But the triganle cannot be removed with the data. The rectangles are okay. Complete code is attached!

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

function render(data){       
  var tris = svg.selectAll("tri").data(data);
  tris.enter().append("path");
  tris.attr("d", function(d) {
    var x1 = (0.4 - 0.2 * (d - 1)) * 250, y1 = 0.3 * 250;
    var x2 = (0.5 - 0.2 * (d - 1)) * 250, y2 = 0.1 * 250;
    var x3 = (0.6 - 0.2 * (d - 1)) * 250, y3 = 0.3 * 250;
    return "M" + x1 + " " + y1 + " L" + x2 + " " + y2 + " L" + x3 + " " + y3 + "Z";
    });
  tris.exit().remove();
        
  var rects = svg.selectAll("rect").data(data);
  rects.enter().append("rect");
  rects.attr("y", 50)
    .attr("width",  20)
    .attr("height", 20)
    .attr("x", function(d) { return d * 40; });
  rects.exit().remove();
}
render([1, 2, 3]);
render([1, 2]); 
render([1]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 1

Views: 37

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102198

There is no SVG element called <tri>. Your enter selection works because you can select anything in your data binding function. As there is nothing named "tri" in the whole DOM (be it a tag, a class, an ID, whatever...), your enter selection is never empty and your exit selection is never populated.

That being said, an easy solution is selecting by class...

var tris = svg.selectAll(".tri").data(data);

And setting this class in your enter selection:

tris.enter().append("path").attr("class", "tri");

Here is your code with the changes:

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

function render(data){       
  var tris = svg.selectAll(".tri").data(data);
  tris.enter().append("path").attr("class","tri");
  tris.attr("d", function(d) {
    var x1 = (0.4 - 0.2 * (d - 1)) * 250, y1 = 0.3 * 250;
    var x2 = (0.5 - 0.2 * (d - 1)) * 250, y2 = 0.1 * 250;
    var x3 = (0.6 - 0.2 * (d - 1)) * 250, y3 = 0.3 * 250;
    return "M" + x1 + " " + y1 + " L" + x2 + " " + y2 + " L" + x3 + " " + y3 + "Z";
    });
  tris.exit().remove();
        
  var rects = svg.selectAll("rect").data(data);
  rects.enter().append("rect");
  rects.attr("y", 50)
    .attr("width",  20)
    .attr("height", 20)
    .attr("x", function(d) { return d * 40; });
  rects.exit().remove();
}

render([1, 2, 3]);
setTimeout(() => render([1, 2]), 1000); 
setTimeout(() => render([1]), 2000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 2

Related Questions