Commit Graph

83 Commits

Author SHA1 Message Date
Mike Bostock
3c00395e78 Rename drag to velocity decay. 2016-06-20 14:02:30 -07:00
Mike Bostock
44c73909ee Simplify node-fixing API.
Rather than storing separate state for the nodes’ fixed positions, just use the
fx and fy properties on the nodes themselves. This is more similar to the 3.x
API which used node.fixed (and node.px, node.py to store the previous position).
This eliminates the need to expose additional APIs for getting, setting,
clearing and iterating over the fixed positions.

Fixes #35.
2016-06-20 13:50:42 -07:00
Jeffrey Heer
0e28745c34 Add unfixAll method. 2016-06-07 12:29:24 -07:00
Mike Bostock
f5a9ae2555 If target position is NaN, do nothing. 2016-05-13 11:11:17 -07:00
Mike Bostock
61ac68434d Add simulation.find. Fixes #31. 2016-05-12 15:52:32 -07:00
Mike Bostock
e6ac233670 Better default link strength.
Use the minimum connectedness of the source or target, not the average.
2016-05-12 12:15:05 -07:00
Mike Bostock
ab792d2590 Better link strength normalization.
Related #30. Rather than normalize the total force applied per node, have the
default link strength be inversely proportional to the number of links for the
source and the target. This way, if the source or target is heavily connected,
the strength of the link is reduced. However, we still bias the application of
the link such that the less-connected of the two nodes is moved more.
2016-05-12 09:26:17 -07:00
Mike Bostock
28bacadb96 Reduce default strength. 2016-05-12 09:25:48 -07:00
Mike Bostock
8db7cbdf6c Fix #30 - normalize link force per node. 2016-05-11 19:34:49 -07:00
Mike Bostock
f70a40f78d Default to the node’s current position.
Nice!
2016-05-10 10:15:17 -07:00
Mike Bostock
add1373738 Replace d3.forceFix with simulation.{fix,unfix}.
This feels a bit cleaner since you don’t need to track the name of the fixing
force externally. It also enforces that fixing happens after the application of
any forces.
2016-05-10 10:08:25 -07:00
Mike Bostock
a4153e77fd Add d3.forceFix. Fixes #27. 2016-05-10 09:49:20 -07:00
Mike Bostock
8a2c8590bb Add simulation.alphaTarget.
This lets you set the “desired” alpha for the simulation, and have the
simulation smoothly interpolate towards the desired value. By default, the
target value is zero, such that the simulation cools. However, by setting it to
a non-zero value, such as during a drag interaction, you can also use it to have
the simulation heat. Fixes #26.

This commit also changes simulation.restart so that it no longer resets the
alpha to one, and changes the meaning of simulation.alphaDecay. The new default
alphaDecay now cause the simulation to end after 300 ticks, instead of 345.
2016-05-09 13:41:33 -07:00
Mike Bostock
85b0b09d34 Minor optimization.
Don’t test the bounding box on leaf nodes; test the circles.
2016-05-04 08:40:17 -07:00
Mike Bostock
f15a5adad7 Process collisions serially.
It’s tempting to do them independently (in parallel), but this makes convergence
much slower. We’re now moving nodes while they’re in the quadtree, which means
we could miss a few collisions; but since the tree is rebuilt on each iteration
that should probably be fine.

This reverts part of 95354e8470, though it retains
the area-biased resolution and the performance improvements.
2016-05-04 07:32:18 -07:00
Mike Bostock
4cec18385d Style. 2016-05-04 07:31:42 -07:00
Mike Bostock
ca3aecc94e Tiny optimization. 2016-05-03 22:29:50 -07:00
Mike Bostock
563481bb5a Tiny optimization. 2016-05-03 16:15:55 -07:00
Mike Bostock
95354e8470 Improve collision detection.
Fix #25. We now resolve collisions for all nodes independently, rather than
moving one node at a time. And since we’re not mutating the quadtree while
resolving, the quadtree can now store the maximum radius for each quadrant,
accelerating search! We can also optimize resolution a little bit since now
resolutions are always symmetric.

Collision resolutions are now biased so that the acceleration is inversely
proportional to the circle’s area, such that larger circles (which are more
likely to overlap many small circles) are more stable.

Also: only jiggle if two circles are overlapping.
2016-05-03 16:07:44 -07:00
Mike Bostock
15d5bb7d5b Separate dimensions for coincidence test.
Fixes #23. This doesn’t catch all degenerate configurations, such as when x = y,
but it at least handles a common case for geometric constraints. As an added
bonus, this commit avoids extraneous jiggling in the many-body force when
visiting testing the target node’s quadtree cell.
2016-04-29 10:38:16 -07:00
Mike Bostock
a1ee534c57 Separate d3.forcePosition into d3.force{X,Y}. 2016-04-29 09:40:12 -07:00
Mike Bostock
cf287b8dba Fix exact coincidence with d3.forceCollide. 2016-04-29 09:33:17 -07:00
Mike Bostock
3add8cb634 Fix initialization bug. 2016-04-28 15:24:29 -07:00
Mike Bostock
83851d8d7d Optimize link force initialization.
We don’t need to re-index nodes and links when the strength or distance changes.
2016-04-28 14:55:18 -07:00
Mike Bostock
e448cf8e5d Remove d3.forceBox and d3.forceContain. 2016-04-28 11:26:51 -07:00
Mike Bostock
5c6cb8d5ca Add d3.forceBox. 2016-04-28 11:26:30 -07:00
Mike Bostock
eca9a02f2f Increase the default alphaMin. 2016-04-27 16:35:41 -07:00
Mike Bostock
5d321b2190 Allow iterative constraint application.
Adds {forceCollide,forceLink}.iterations, which defaults to one.
2016-04-27 11:20:21 -07:00
Mike Bostock
19e2a7a7e0 Reduce default drag. 2016-04-27 11:20:10 -07:00
Mike Bostock
93e0397120 Improve stability of collision & links.
We need to look into the future!
2016-04-27 11:03:13 -07:00
Mike Bostock
2f7cd4ae93 Rename simulation.start to simulation.restart.
This is more consistent with timer.restart, and more appropriate given that the
simulation now starts automatically.
2016-04-27 09:52:44 -07:00
Mike Bostock
831ad55a59 Fix #20 - simulation.tick now returns boolean.
This changes simulation.tick to always advance the simulation one step,
regardless of the current value of alpha and alphaMin. If alpha is less than
alphaMin after this step, simulation.tick returns true, indicating that the
simulation can be safely ended.

Furthermore, simulation.tick no longer dispatches a tick event; the tick event
is only dispatched by the simulation’s internal timer. This is now consistent
with simulation.stop, which likewise does not dispatch an end event; the end
event is only dispatched when the simulation’s internal timer stops.
2016-04-27 09:17:47 -07:00
Mike Bostock
aa410cf32e Deterministic initialization!
Rather than initialize the node positions randomly, use a phyllotaxis. This is
just as good, and means the resulting behavior will be deterministic as long as
no nodes are exactly coincident.
2016-04-26 17:37:00 -07:00
Mike Bostock
e88cd9e8c3 Rename for clarity. 2016-04-26 09:34:32 -07:00
Mike Bostock
e532b18700 Fix #18 - allow manual ticking.
Calling simulation.stop no longer resets the alpha, so a subsequent call to
simulation.start now resumes the simulation, and you can call simulation.tick to
run the simulation manually.

This commit also removes the start event. There’s not much of a point to the
start event since it’s impossible to listen for it in the normal case: the event
is dispatched during the construction of the simulation before any listeners can
be registered. Even in other cases, the simulation is always restarted manually,
so you could always notify a listener manually at the same time. Furthermore,
supporting a start event would require us to track whether the timer is running,
so it’s simpler to just leave it out. (And lastly, eliminating the start event
avoids some confusion about the relationship between simulation.stop and the end
event, which are unrelated!)

Lastly, simplify the recalculation of the current iteration when changing the
alpha decay rate constant.
2016-04-26 09:18:51 -07:00
Mike Bostock
3810e0fa11 Pass nodes to force.initialize. 2016-04-25 21:47:24 -07:00
Mike Bostock
b330311b4f Default empty nodes and links. 2016-04-25 17:04:51 -07:00
Mike Bostock
48836d0dfb Pass radius to d3.forceCollide constructor. 2016-04-25 14:00:54 -07:00
Mike Bostock
d0acda9d86 Fix #15 - rename friction to drag. 2016-04-25 10:42:19 -07:00
Mike Bostock
27646831c6 Fix position initialization. 2016-04-25 09:42:22 -07:00
Mike Bostock
b35af748dd Rename for consistency. 2016-04-25 09:40:59 -07:00
Mike Bostock
2dcf98c650 Add a tiny bit of blending to collision.
This greatly improves stability.
2016-04-25 09:38:39 -07:00
Mike Bostock
a6dcf0c876 Improve stability of collision detection. 2016-04-23 14:24:37 -07:00
Mike Bostock
53fb14fcbd Add d3.forceContain. 2016-04-23 10:24:15 -07:00
Mike Bostock
6ad4bc2663 More stable collision detection. 2016-04-23 09:48:31 -07:00
Mike Bostock
d1aff9acf0 Don’t require nodes on creation. 2016-04-23 09:38:08 -07:00
Mike Bostock
b4896d57ef Fix the many-body force.
Mutating the tree deletes the accumulated charges!
2016-04-23 09:37:09 -07:00
Mike Bostock
0f68d7259e Reset link force when links change. 2016-04-23 08:43:59 -07:00
Mike Bostock
95cd502143 Fix typo. 2016-04-22 16:08:22 -07:00
Mike Bostock
0744d26f06 Fix #12 - make position configurable. 2016-04-22 15:35:56 -07:00