vasturiano / 3d-force-graph

3D force-directed graph component using ThreeJS/WebGL
https://vasturiano.github.io/3d-force-graph/example/large-graph/
MIT License
4.54k stars 803 forks source link

How to use d3-force-limit in 3d-force-graph to set a boundary for nodes? #444

Open RachelCT1 opened 3 years ago

RachelCT1 commented 3 years ago

I want to layout several groups of nodes in specify different boxes or area (like this image), and I find d3-force-limit here (https://github.com/vasturiano/3d-force-graph/issues/397#issuecomment-706924317). So I wonder if I can do this work use d3-force-limit? I don't know how to use it in 3d-force-graph, or how to add the limit force in? image

vasturiano commented 3 years ago

@RachelCT1 thanks for reaching out.

I believe it's possible to use d3-force-limit for this purpose, by defining the x0, x1,... coordinate restriction functions to return different bounding box values per cluster. Something like:

.x0(node => node.group === '1' ? 30 : node.group === '2' ? -60 : 0)

However, it would be more suitable to do this using a specific clustering force, which simply assigns focal points per cluster. There is d3-force-cluster but that only works in 2 dimensions, so it would need to be adapted to be aware of the 3rd dimension, so it can be used with 3d-force-graph.

RachelCT1 commented 3 years ago

@RachelCT1 thanks for reaching out.

I believe it's possible to use d3-force-limit for this purpose, by defining the x0, x1,... coordinate restriction functions to return different bounding box values per cluster. Something like:

.x0(node => node.group === '1' ? 30 : node.group === '2' ? -60 : 0)

However, it would be more suitable to do this using a specific clustering force, which simply assigns focal points per cluster. There is d3-force-cluster but that only works in 2 dimensions, so it would need to be adapted to be aware of the 3rd dimension, so it can be used with 3d-force-graph.

Thanks for your help. And I am sorry that I didn't explain my confusion clearly. I mean that we use 3d-force-graph like this: var myGraph = ForceGraph3D(); myGraph(<myDOMElement>) .graphData(<myData>); and use d3-force-limit like this: d3.forceSimulation() .nodes(<myNodes>) .force('limit', d3.forceLimit() .x0(20) .x1(45) ); but I don't understand how to combine them...

vasturiano commented 3 years ago

@RachelCT1 to add a new force into the system all you should need to do is to call the .d3Force method once, with the configuration of the force.

So something like:

myGraph.d3Force('limit', d3.forceLimit().x0(20).x1(45));

And as mentioned above, the input to the x0, etc attributes can also be a function that receives the node as argument.