-
Notifications
You must be signed in to change notification settings - Fork 377
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
Rethink automatic starting of simulations? #45
Comments
It starts upon creation. That is what is meant by “automatically”. If you prefer you can explicitly stop the force layout upon creation and then start it again later. (However stopping the force layout does not prevent the forces from being reinitialized when the nodes change, since starting and stopping only affects the internal timer, and the simulation can be run manually by calling simulation.tick.) You can change the nodes after the force layout starts. Yes, this does cause the constituent forces for be reinitialized, but this cost is typically negligible so it doesn’t seem urgently necessary to optimize this. I don’t want to debounce this work until the next tick because it makes debugging slightly harder, but I suppose it would be an option. You could not implement the type of simulation.start API you propose without the simulation knowing about all possible forces and their parameters. The design is intended to be generic and extensible in that the simulation can be run with arbitrary forces that have arbitrary behavior and arbitrary parameters; the simulation does not know what links are, for instance. Furthermore forces can be bound and unbound dynamically, so it doesn’t make sense to pass all the parameters through start. I suppose you could use weakly (string) named parameters defined in the simulation as is done with the forces, but that seems worse than having the forces define their own parameters and by worry about potential name conflicts. There is a slight problem with the example on that the simulation can run for a tick with an empty graph (no nodes). This is mostly harmless especially since the ticked listener is not yet registered, but it does mean that the simulation can cool slightly while the data is loading. I can see if there is an easy way to avoid this, though I don’t think it will require any changes to the API. (Deferring creation of the simulation until the data loads, for example, would do it.) |
Think its fine as it is. After some hours working with it and now reading your reply, I got the feeling for the API, which favors convenience over minor inefficiencies. Thank you for your time. |
I am reopening this issue as a reminder to myself to fix the issue you raised with the example. Thank you for your feedback! |
I ended up with this sequence:
which is simple, but limited to cases where reheating and restarting is not required. (any maybe has even more issues I am not aware of) |
Some options:
|
@mbostock on option |
This comment has been minimized.
This comment has been minimized.
I've implemented solution 1 in #165. We start when any listener is added (ie "tick" or "end") so it should cover @IPWright83 's use case too (though I'd be reassured if it could be tested independently). demo notebook @ https://observablehq.com/d/0e3586acc3d9cd55 |
@Fil really disappointingly my new job doesn't give me the chance to use D3 anymore, which is such a shame as it's an amazing library. I will see if I can find some time to test though |
We finally decided against this change. Use .stop() then .restart() when the data is ready. |
Reading the Force-Directed Graph example, I find it hard to understand, when the simulation starts.
According to the the API, "The simulator starts automatically". So that would be here:
Hmmm, without nodes, there wont be much to simulate. Continue reading the code, I assume, it might happen here:
Now it has nodes and can work. But it still has no links. Hmmm. So does it run considering the other forces? Well, Javascript is singlethreaded, so the time callback cannot execute anyway. So presumably it the timer fires, but the callback will be run after this function, or more exactly, after the XmlHttpRequest callback is handled. Lots of pondering. Continue reading
I assume that now the simulation has all arguments and can run considering the link forces. Which in fact is correct. Anyway, I find the API a bit confusing in this point (otherwise the new force API is absolutely ingenious!).
Debugging reveals, that force.initialize() is called 3 times, computing
twice, unnecessarily. So maybe it makes sense to have an API method alike
or more abstract (or precise)
? For me that would have been clearer. Most functions would fall into category configure while start, restart, stop would be category run.
thx so much for d3
urbanhop
The text was updated successfully, but these errors were encountered: