Why transitions flicker / stutter when applied to a single function (D3)

I was messing around with transitions, and I noticed some stuttering and flickering when the transitions apply to the selection in another function. If, however, the transition is applied with a chain of methods, it works exactly as prescribed.

The following is a small example ( Fiddle ) of simply moving some text. The first, leftmost line is magically teleported down the page until the transition begins. The second, rightmost line has a smooth transition from the top to the bottom of the page.

Why is this teleport happening? Obviously, applying transitions in a separate function is not the same as chains, but is there a way to achieve this? Let's say I want to apply the same transition to many different objects - extracted from different samples - then is there a way to cancel the transition to my own function without having this stutter?

var svg = d3.select('svg'); var textElem = svg.append('text') .data(['hello world']) .attr('x', 30) .attr('y', 100) .attr('fill', '#000') .attr('id', 'a') .text(function (d) { return d; }); var textElem2 = svg.append('text') .data(['some text']) .attr('x', 230) .attr('y', 100) .attr('fill', '#000') .attr('id', 'a') .text(function (d) { return d; }); setTimeout(foo, 3000); function foo() { textElem.data(['hello world, again!']); applyTextTransitions(textElem); textElem.attr({ x: 30, y: 150 }); textElem.text(function (d) { return d; }); textElem2.data(['some more text!']) .transition() .duration(1000) .style('opacity', 0) .transition() .duration(1000) .style('opacity', 1) .attr({ x: 230, y: 150 }) .text(function (d) { return d; }); } function applyTextTransitions(element) { element .transition() .duration(1000) .style('opacity', 0) .transition() .duration(1000) .style('opacity', 1); } 
+6
source share
2 answers

I have not used d3, but do you want to do this?

 applyTextTransitions(textElem, { x: 30, y: 150 }); function applyTextTransitions(element, newPos) { element .transition() .duration(1000) .style('opacity', 0) .transition() .duration(1000) .attr(newPos) .style('opacity', 1) .text(function(d){ return d; }); } 

https://jsfiddle.net/k8kv4arv/3/

The transition occurs because the calling functions wait until applyTextTransitions() , then they apply new dimensions.

+3
source

I know I'm late to the party, but ...

The stutter you get is only due to the fact that you call the transition function, applyTextTransition , and then immediately change the positioning of the element.

 applyTextTransitions(textElem); textElem.attr({ x: 30, y: 150 }); 

That's why you get an unwanted stutter.


Also, the right way for D3 to reuse functions that use transitions is to use selection.call . This allows you to declare a single function and use the call method to call a function that applies the transition.

 textElem.call(applyTextTransition); function applyTextTransition(selection) { // perform selection.transition() } 

Now you can use your function in the chain, and you are not limited to using this function only for the current selection.

+3
source

All Articles