Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chained transitions may interrupt prior ones #54

Closed
devison opened this issue Aug 22, 2016 · 4 comments
Closed

Chained transitions may interrupt prior ones #54

devison opened this issue Aug 22, 2016 · 4 comments
Assignees

Comments

@devison
Copy link

devison commented Aug 22, 2016

Hi,

It seems that when transitions are chained together using transition.transition, a subsequent transition may interrupt the prior one. This was unexpected to me, since I was expecting them to run sequentially. (I was experimenting with staged animations and was observing that sometimes only the second part of the animation happened).

I've isolated this to a simple example:

<!DOCTYPE html>
<html>
    <body>
        <script src="https://d3js.org/d3.v4.min.js"></script>
        <script>

            var n = 300, radius = 5, spacing = 2;

            var width = (n * spacing + 2 * radius), height = 600;

            var svg = d3.select('body').append('svg')
                    .attr('width', width).attr('height', height);

            for (var i = 0; i < n; ++i)
                svg.append('circle');

            // create red circles at top:
            var circles = svg.selectAll('circle')
                    .style('opacity', 0.2)
                    .style('fill', 'red')
                    .attr('r', radius)
                    .attr('cx', function (d, i) {
                        return radius + i * spacing;
                    })
                    .attr('cy', radius);

            function getIndex(d, i) {
                return i;
            }

            function logInterrupt() {
                console.log('first transition interrupted!');
            }

            // transition circles to blue over varying durations, then move to bottom:
            circles.transition().duration(getIndex).style('fill', 'blue').on('interrupt', logInterrupt)
                    .transition().duration(2000).attr('cy', height - radius);

        </script>
    </body>
</html>

Also see here: https://jsfiddle.net/onjtpp4y/2/

In chrome and firefox I see the first part of the row of circles remains red and I see multiple interrupted messages in the console. Is that expected?

d3-line

d3-console

I can imagine why this happens, but would it make more sense to make chained transitions strictly sequential?

Regards,
Dan

p.s. thanks for awesome library

@mbostock
Copy link
Member

I think this qualifies as a bug, but it appears to be triggered only when the prior transition has an extremely short duration, such as zero. If you increase the duration (say the index plus 50ms), the interrupts go away.

@mbostock mbostock self-assigned this Aug 22, 2016
@devison
Copy link
Author

devison commented Aug 22, 2016

Thanks very much for fast response.

Yep. Fyi, in my actual app the delay on the first transition is a few hundred ms, yet this issue occurred with a large number of svg elements. (A user on a slower computer reported some data not displaying correctly).

@mbostock
Copy link
Member

That’s plausible; if the browser stalls temporarily, it could cause a similar situation.

The problem here is the optimization in d3/d3#1576 (see also #16): the first tick is deferred to the end of the current frame, so the following transition starts before the preceding transition can end naturally, triggering the interrupt.

mbostock added a commit that referenced this issue Aug 22, 2016
@devison
Copy link
Author

devison commented Aug 23, 2016

Fantastic - thanks very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants