Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When running a D3 update/enter/exit, how to ignore already exiting elements during the new exit?

Everyone knows the update/enter/exit pattern:

function update(data) {

  // DATA JOIN
  // Join new data with old elements, if any.
  var text = svg.selectAll("text")
      .data(data);

  // UPDATE
  // Update old elements as needed.
  text.attr("class", "update");

  // ENTER
  // Create new elements as needed.
  text.enter().append("text")
      .attr("class", "enter")
      .attr("x", function(d, i) { return i * 32; })
      .attr("dy", ".35em");

  // ENTER + UPDATE
  // Appending to the enter selection expands the update selection to include
  // entering elements; so, operations on the update selection after appending to
  // the enter selection will apply to both entering and updating nodes.
  text.text(function(d) { return d; });

  // EXIT
  // Remove old elements as needed.
  text.exit().transition().duration(2000).attr('transform',
    rotation = 25;
    return 'translate(' + d.x + ',' + d.y + ') rotate('+ rotation +' 30 30)';
  }).remove();
}

My question is:

If I run this function while the exit is still occurring (during the 2000 ms transition window), how can I prevent the transition being called on elements already undergoing the exit transition.

In other words, when the original selection is made, it includes elements already in the exit().transition() state. So the exit transition is called on these elements a second time if they are not finished with their transition and removed().

Would I need to make a filter? Is there a test for in transition while exiting?

like image 238
Union find Avatar asked Mar 01 '16 14:03

Union find


People also ask

What does enter () do in D3?

enter() function in D3. js is used to create the missing elements and return the enter selection.

What is the objective behind using enter and exit selections in d3js?

enter() and . exit() functions on that object to select the items that should be added and the items that should be deleted, respectively.

What is and exit () in D3 JS?

exit() function in D3. js is used to remove the elements or tags which correspond to the old data or in simple words This is used to update the DIV elements that were created before with the new data given.

What is append in D3?

append() function is used to append a new element to the HTML tag name as given in the parameters to the end of the element. If the type that is given is a function then it must be evaluated for each element that is in the selection. Syntax: selection.


1 Answers

D3.js: Stop transitions being interrupted? says give the exiting element a special class and then use that to only admit freshly exiting elements to the exit transition

.exit()
     .filter(function(d,i) {
        return !d3.select(this).classed("exiting");
     })
     .classed("exiting", true)
     .transition()
     ...

A bigger problem will be any data that's re-introduced on your second click while it's still subject to an exit transition from the first. This in your example would disappear elements you want to keep as the exit transition finishes and calls a remove on that element. To get round this in the past I've added immediate (zero delay, zero duration) transitions to my update and enter selections to override/write the exit selection, if they don't have their own transitions already (if there's a better way someone let me know).

This leads to another point: set .classed("exiting", false) in the enter and update, so in the case of 'exiting'>'re-introduced'>'exiting again' elements the .exiting class isn't set and the exiting transition is activated.

like image 145
mgraham Avatar answered Sep 20 '22 19:09

mgraham