I was messing around with transitions and I noticed some stuttering and flickering when the transitions are applied to the selection in a different function. If, however, the transition is applied with method chaining, it works exactly as prescribed.
Below is small example (Fiddle) of simply moving some text. The first, leftmost, string magically teleports down the page before the transition starts. The second, rightmost, string has a smooth transition from the top to the bottom of the page.
Why does this 'teleport' happen? Obviously applying the transitions in a separate function is not the same as chaining it, but is there a way to achieve this? Say, I want to apply the same transition to many different objects - retrieved from different selects - then is there a way to relegate the transition to its own function without getting this stuttering?
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);
}
I haven't used d3, but do you mean 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 "jump" happens because the calling functions waits until applyTextTransitions()
is finished, then applies the new dimensions.
I know I'm late to the party, but...
The stuttering that you are getting is only because you call a transition function, applyTextTransition
, and then immediately change the element's positioning.
applyTextTransitions(textElem);
textElem.attr({
x: 30,
y: 150
});
This is why you get the unwanted stuttering.
Additionally, the proper, D3 way to reuse functions that apply transitions is to use selection.call
. This allows you to declare one function, and use the call
method to invoke the function that applies the transition.
textElem.call(applyTextTransition);
function applyTextTransition(selection) {
// perform selection.transition()
}
You can now use your function in your chaining and you aren't limited to using that function for just the current selection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With