score:1

Accepted answer

The exit method:

Returns the exit selection: existing DOM elements in the selection for which no new datum was found. (The exit selection is empty for selections not returned by selection.data.) (API documentation).

While you have specified data for the selections g, foreground, and background, you have not specified any data for the selection svg, so the exit selection will be empty. Consequently, .remove() can't remove anything.


To use an exit selection, note that the exit selection doesn't remove elements in a selection. It is a selection of a subset of elements in a selection that no longer have corresponding bound data.

If a selection holds 10 DOM elements, and the selection's data array is set to an array with 9 elements, the exit selection will contain one element: the excess element.

We can remove this subset with .exit().remove(). The exit is which elements we no longer need, and remove() gets rid of them. Exit doesn't remove elements because we may want to still do something with them, such as transition them, or hide them, etc.

As noted in the quote above, to populate an exit selection you must use selection.data():

var selection = svg.selectAll("path")
  .data(data);

Now we can access the enter selection, the exit selection, and the update selection.

Unless specifying a key, only one of the enter or exit selections can contain elements: if we need more elements we don't need to exit any, if we have excess elements, we don't need any new ones.

To remove excess elements, we can now use:

var selection = svg.selectAll("path")
  .data(data);    

selection.exit().remove();

Given you are specifying data for other selections such as foreground, background, and g, these are the selections you should be using .exit() on, as part of a complete enter/update/exit cycle. Keep in mind, in d3v4 you need to merge the update and enter selections in order to perform operations on pre-existing and new elements in the selection.


However, if you simply want to get rid of the svg and start fresh (which is what it looks like you want to do - as you are trying to remove the svg) you can simply remove the svg:

d3.select("#test")
  .select("svg")
  .remove();

However, this won't allow you transition nicely between charts or utilize the enter/update/exit cycle.

Why note use svg.remove()? Because the selection svg holds a g element:

 var svg = d3.select("#test") // returns a selection with #test
      .append("svg:svg")      // returns a selection with the new svg
      .attr(...)              // returns the selection with the newly created svg again
      .append("svg:g")        // returns a selection with the new g
      .attr(...);             // returns the selection with the newly created g again

svg is consequently a selection of a g, and removing it won't remove the svg element. In fact running the above code block after svg.remove() will add a new svg element to the DOM while not removing the old one.


Related Query