Nav
Nav

Reputation: 20658

d3.js. How to exit() by value?

I've been trying to understand how exit() works (already seen Mike's explanations), and when I tried the below program, I noticed that the exit() does not take into account the fact that I've removed 3 from dat. It just sees that now there's one element less, and removes the last circle which it attached.

Is this how exit() was really meant to work? simply comparing the number of elements in the array and removing the last few? I thought it'd understand which values it's dealing with. How can exit() be programmed to recognize that the third circle has to be removed and not the fifth one? ie: How to make exit() recognize values in the array?

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node { cursor: move; fill: #ccc; stroke: #000; stroke-width: 1.5px; }
</style>
<body>
<script src="d3/d3.v3.min.js"></script>
<script>
var dat = [1,2,3,4,5];
var svg = d3.select("body").append("svg").attr("width",1000).attr("height", 1000);

redraw(svg);
dat = [1,2,4,5];
redraw(svg);

function redraw(layer)
{
layer.selectAll("circle").data(dat).exit().remove("circle");
layer.selectAll("circle").data(dat).enter().append("circle")
      .attr("class", "node")
      .attr("r", function(d) {console.log(d*10);return d*10;})
      .attr("cx", function(d) {return d*100;})
      .attr("cy", function(d) {return 100;});
}
</script>
</body>

Upvotes: 0

Views: 52

Answers (1)

Nav
Nav

Reputation: 20658

Ok, solved it myself. The solution is in using Object Constancy. You have to specify an id which will help D3 remember which data value goes where. The add a function in the data() call which will return the id.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node { cursor: move; fill: #ccc; stroke: #000; stroke-width: 1.5px; }
</style>
<body>
<script src="d3/d3.v3.min.js"></script>
<script>
var dat = [{id:"a", val: 1}, {id:"b", val: 2}, {id:"c", val: 3}, {id:"d", val: 4}, {id:"e", val: 5}];
var svg = d3.select("body").append("svg").attr("width",1000).attr("height", 1000);

redraw(svg);
dat = [{id:"a", val: 1}, {id:"b", val: 2}, {id:"d", val: 4}, {id:"e", val: 5}];
redraw(svg);

function redraw(layer)
{
layer.selectAll("circle").data(dat, function(d) {return d.id; }).exit().remove("circle");

layer.selectAll("circle").data(dat, function(d) { return d.id; }).enter().append("circle")
      .attr("class", "node")
      .attr("r", function(d) {return d.val*10;})
      .attr("cx", function(d) {return d.val*100;})
      .attr("cy", function(d) {return 100;});
}

</script>
</body>

Upvotes: 1

Related Questions