Multiple groups in a simulation?

476 views
Skip to first unread message

Ethan Jewett

unread,
Nov 7, 2016, 5:46:30 PM11/7/16
to d3...@googlegroups.com
Hi,

I’m creating a “graph” view of some data and want to have certain forces apply to certain subsets of the nodes in the graph.

Initially I thought the way to do this was to use the .initialize method on each force to re-initialize it on a subset of nodes different from the full set of nodes set on the force. However, this has seemed to not work well. Specifically, if I define 2 forces of the same type on the simulation and attempt to initialize them with different subsets of nodes, the 2nd force doesn’t seem to work.

So, I think the proper way to do this is to define a separate simulation for each set of nodes. Here is an example with 3 simulations:
  1. Simulation on one set of three nodes to avoid overlap
  2. Simulation with a second set of three nodes to avoid overlap
  3. Simulation on all nodes defining centering force, links, and x/y attractive positioning forces.
The goal here is that nodes in the 2 subsets of 3 nodes can’t overlap with other nodes in their subset but that a node in set 1 could overlap with a node in set 2.

But that doesn’t seem to work. In fact, just the opposite seems to be true. Interactive example: https://jsfiddle.net/esjewett/6hhnyo6f/

Any thoughts or suggestions?

Thanks,
Ethan

Mike Bostock

unread,
Nov 7, 2016, 6:34:14 PM11/7/16
to d3...@googlegroups.com
You’ll probably want to implement a custom force, have it implement a force.nodes accessor on that custom force (similar to link.links), and then pass the desired array of nodes to each of these custom forces. The custom forces should ignore the nodes that are passed to force.initialize (which will be all the nodes for the simulation), and use the subset of nodes you passed in instead.

In theory you should be able to call force.initialize manually to override the set of nodes each force applies to, as you attempted. You didn’t post your code for that version, so it’s hard to speculate why it didn’t work… but that approach is more brittle since the simulation may call force.initialize again, specifically whenever simulation.nodes or simulation.force is called.

I wouldn’t recommend sharing nodes between simulations because then the simulations will separately apply Verlet integration to the shared nodes. And maybe other reasons…

Mike

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mike Bostock

unread,
Nov 7, 2016, 6:47:51 PM11/7/16
to d3...@googlegroups.com

Ethan Jewett

unread,
Nov 8, 2016, 6:30:23 PM11/8/16
to d3...@googlegroups.com
Thanks so much. This is basically what I was doing with the initialize method of the forces and the resulting problem is very similar where one of the forces just doesn’t seem to “take”. I think there may be something about d3.forceCollide and d3.forceManyBody that is making this not work? Almost as if scope isolation is failing for them, but I can’t see the problem in d3-force.


Thanks,
Ethan

To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

Mike Bostock

unread,
Nov 8, 2016, 7:38:15 PM11/8/16
to d3...@googlegroups.com
It appears this trick does not work on those forces because they rely on node.index. Will need to modify how the forces are implemented, probably.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

Ethan Jewett

unread,
Nov 9, 2016, 10:31:33 AM11/9/16
to d3...@googlegroups.com
I haven’t even looked at it yet, but would it make sense to send a pull request against d3-force if I can work it out? Or is this more the type of thing that should just be done with a custom force on my end?

Thanks,
Ethan

To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+unsubscribe@googlegroups.com.

Mike Bostock

unread,
Nov 9, 2016, 12:04:34 PM11/9/16
to d3...@googlegroups.com
Yes, a pull request to fix d3.forceManyBody and d3.forceCollide so that they do not assume that nodes[i].index === i would be lovely. I filed an issue to track this request: https://github.com/d3/d3-force/issues/72

To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages