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

d3.interval().restart() restarts an interval as a timer instead #39

Closed
katiepark opened this issue Oct 23, 2019 · 5 comments
Closed

d3.interval().restart() restarts an interval as a timer instead #39

katiepark opened this issue Oct 23, 2019 · 5 comments

Comments

@katiepark
Copy link

I ran into an issue with d3.interval not working as expected when calling restart. If I create a new interval, it works as expected -- firing the callback every delay milliseconds:

  const intervalCallback = function(t) {
    console.log('interval', t);
    if (t > 5000) intervalTest.stop();
  };
  const intervalTest = d3.interval(intervalCallback, 500);

This outputs:

> interval 515.0400000275113
> interval 1000.9299999801442
> interval 1503.1099999905564
> interval 2000.0850000069477

If I call restart on this instance, passing the same callback and delay, I would expect intervalTest to restart following the same behavior. However, it appears to start a timer (or an interval with 0ms delay) instead.

intervalTest.restart(intervalCallback, 500);

Outputs:

> interval 16.02500001899898
> interval 32.765000010840595
> interval 48.30000002402812
> interval 66.045000043232
> interval 82.05500000622123
...

And so on until the callback reaches its stopping point.

If I'm actually misunderstanding and this isn't how interval is supposed to be used, perhaps something could be added to the docs to clarify?

Let me know if you have any questions, and thanks for your work on this module!

@mbostock
Copy link
Member

d3.interval returns a Timer, it just happens that that Timer comes pre-registered with a callback that will restart the Timer every time it fires before invoking your callback function. So, if you call timer.restart where the timer was returned by d3.interval, it will just fire once rather than fire repeatedly.

If you want to restart an interval, could you just create a new interval by calling d3.interval instead?

@katiepark
Copy link
Author

Sure, that approach works pretty painlessly! As a user, though, it's not clear to me from the documentation that that's how restart would work when applied to an interval. I think adding a note to the docs might make that easier for users to understand.

Thanks for responding so quickly!

@Fil
Copy link
Member

Fil commented Jun 5, 2020

Would it not be better to change the code so that restarting an interval would restart it "as an interval"? I'm struggling to see the implication in terms of code, though.

@Fil
Copy link
Member

Fil commented Aug 23, 2020

Fixed in https://github.com/d3/d3-timer/releases/tag/v2.0.0
Thank you!

@helderdarocha
Copy link

It's still doesn't behave the same as stopping the timer and calling d3.interval() again, since it adds a delay (corresponding to the elapsed time so far) before restarting.

If you set start = d3.now() before starting the interval, the following line in the callback will print the same values for e1 and e2:

function callback(e1) {
    const e2 = d3.now() - start;
    console.log(e1, e2);
}

But if you restart after x seconds, there will be a delay of another x seconds, and e2 will be e1 + x.

This doesn't happen if you stop the interval and create a new one with the same parameters.

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

4 participants