gampleman/elm-visualization/1.3.0

NOTE: this package is not compatible with Elm 0.19.1

Visualization.Force

This module implements a velocity Verlet numerical integrator for simulating physical forces on particles. The simulation is simplified: it assumes a constant unit time step Δt = 1 for each step, and a constant unit mass m = 1 for all particles. As a result, a force F acting on a particle is equivalent to a constant acceleration a over the time interval Δt, and can be simulated simply by adding to the particle’s velocity, which is then added to the particle’s position.

In the domain of information visualization, physical simulations are useful for studying networks and hierarchies!

Simulation

type alias Entity comparable a =
{ a
| x : Float
, y : Float
, vx : Float
, vy : Float
, id : comparable
}

Visualization.Force needs to compute and update positions and velocities on any objects that it is simulating. However, you can use your own data structure to manage these, as long as the individual objects expose the necessary properties. Therefore this type alias is an extensible record allowing you to avoid excessive nesting.

The id property must be unique among objects, otherwise some of the colliding objects will be ignored by the simulation.

Also take care when initializing the positions so that the points don't overlap.

entity : Int -> a -> Entity Int { value : a }

This is a conveninence function for wrapping data up as Entities. The initial position of entities is arranged in a phylotaxic pattern.

simulation : List (Force comparable) -> State comparable

Create a new simulation by passing a list of forces.

type State comparable

This holds internal state of the simulation.

isCompleted : State comparable -> Bool

Has the simulation stopped?

reheat : State comparable -> State comparable

Resets the computation. This is useful if you need to change the parameters at runtime, such as the position or velocity of nodes during a drag operation.

iterations : Int -> State comparable -> State comparable

You can set this to control how quickly the simulation should converge. The default value is 300 iterations.

Lower number of iterations will produce a layout quicker, but risk getting stuck in a local minimum. Higher values take longer, but typically produce better results.

State comparable
-> List (Entity comparable a)
-> List (Entity comparable a)

This will run the entire simulation until it is completed and then returns the entities. Essentially keeps calling tick until the simulation is done.

Note that computing these is fairly computationally expensive and may freeze the UI for a while if the dataset is large.

State comparable
-> List (Entity comparable a)
-> ( State comparable, List (Entity comparable a) )

Advances the simulation a single tick, returning both updated entities and a new State of the simulation.

Forces

type Force comparable

A force modifies nodes’ positions or velocities; in this context, a force can apply a classical physical force such as electrical charge or gravity, or it can resolve a geometric constraint, such as keeping nodes within a bounding box or keeping linked nodes a fixed distance apart.

center : Float -> Float -> Force comparable

The centering force translates nodes uniformly so that the mean position of all nodes (the center of mass) is at the given position ⟨x,y⟩. This force modifies the positions of nodes on each application; it does not modify velocities, as doing so would typically cause the nodes to overshoot and oscillate around the desired center. This force helps keep nodes in the center of the viewport, and it does not distort their relative positions.

manyBody : List comparable -> Force comparable

The many-body (or n-body) force applies mutually amongst all nodes. It can be used to simulate gravity (attraction) if the strength is positive, or electrostatic charge (repulsion) if the strength is negative.

Unlike links, which only affect two linked nodes, the charge force is global: it affects all nodes whose ids are passed to it.

The default strength is -30 simulating a repulsing charge.

manyBodyStrength : Float -> List comparable -> Force comparable

This allows you to specify the strength of the many-body force.