Skip to content

Layout Force

Flavio Schneider edited this page Nov 1, 2021 · 3 revisions

Layout Force

This layout moves graph nodes and links using different forces by using different physics simulations. Each force inside the <LayoutForce> component is applied at every frame to change the node positions.

Anatomy

import { Graph, LayoutForce, ForceCenter, ForceDirection, ForceManyBody, ForceLink, ForceCollide } from 'graphire'

<Graph>
  <LayoutForce>
    <ForceCenter/>
    <ForceDirection/>
    <ForceManyBody/>
    <ForceLink/>
    <ForceCollide/>
  </LayoutForce>
  {/* Nodes and links here */}
</Graph>

Props & API

<LayoutForce/>

Prop Type Default Description
autoStart boolean true If true will start animating the graph as soon as it's ready.
onReady function - Callback that provides the layout API for manual animation as soon as it's ready.
alpha number 1.0 Amount of energy in the system at the start.
alphaMin number 0.001 Amount of energy where the animation stops.
alphaDecay number 0.02 Amount of energy decrease at each step.
alphaTarget number 0.0 Amount of energy to keep in the system.
velocityDecay number 0.6 Node's velocity decrease multiplier at each step.

You can control the simulation manually by setting autoStart={false} and then using the layout API:

const api = useLayoutForce() // Hook based - must be used inside <LayoutForce>
// or 
<LayoutForce onReady={(api) => ... } /> // Callback based 

Which can then be used as follows:

api.start()          // To restart the simulation with alpha=1.0
api.start(alpha)     // To restart the simulation with custom alpha
api.stop()           // To stop the simulation
api.tick()           // To move one frame ahead in the simulation
api.tick(iterations) // To move `iterations` steps ahead in the simulation

<ForceCenter/>

Moves the center of mass of all nodes to the provided x,y,z coordinates.

Runtime: 2*n for n nodes.

Prop Type Default
strength number 1.0
x number 0.0
y number 0.0
z number 0.0

<ForceDirection/>

Applies a constant velocity to all nodes in the provided direction.

Runtime: n for n nodes.

Prop Type Default
strength number 1.0
x number -
y number -
z number -

<ForceManyBody/>

Applies attraction (for strength < 0) or repulsion (for strength > 0) forces to all nodes. This simulation uses the Random Vertex Sampling (RVS) approximation algorithm for linear time complexity.

Runtime: k*n for n nodes and k neighbors.

Prop Type Default Description
strength number 1.0 -
neighbors number 15 -
updateValue number 0.75 -
sampleValue number 0.25 -
distanceMin number 1.0 -
distanceMax number Infinity -
rand function Math.random() -

<ForceLink/>

Applies spring attraction forces between nodes that are connected by a link.

Runtime: n+e for n nodes and e links.

Prop Type Default Description
strength number 1.0 -
distance number 50 -

<ForceCollide/>

Applies repulsion forces to avoid node overlapping.

Runtime: n*n for n nodes (inefficient for large graphs).

Prop Type Default Description
strength number 1.0 -
radius number 1.0 -

Note that you can specify the radius of each individual node by passing the radius prop to the useNode hook.


Build Custom Force

You can build your custom force by using the useForce hook, which gives you access to all nodes at each frame. There you can modify velocity and positioning. E.g.:

import { useForce } from 'graphire'

export const ForceCustom = (props) => {
  const { velocityX = 1 } = props
  useForce(nodes => {
    nodes.forEach((node) => {
      // Sets the x-velocity to the provided value on all nodes.
      node.vx = velocityX 
    })
  })
  return null
}

Clone this wiki locally