Module

Hylograph.Kernel.WASM.Simulation

Package
purescript-hylograph-wasm-kernel
Repository
afcondon/purescript-hylograph-wasm-kernel

WASM Simulation with D3-compatible API

High-level simulation wrapper that provides the same API as Hylograph.Kernel.D3.Simulation, enabling drop-in replacement.

Key features:

  • Animation loop via requestAnimationFrame
  • Callback system for Halogen integration
  • Position sync between PureScript and WASM

Usage:

import Hylograph.Kernel.WASM.Simulation as Sim
import Hylograph.Kernel.WASM.Events (defaultCallbacks)

main = do
  callbacks <- defaultCallbacks
  sim <- Sim.createWithCallbacks Sim.defaultConfig callbacks
  Sim.setNodes myNodes sim
  Sim.setLinks myLinks sim
  Sim.start sim

#Simulation Source

type Simulation :: Row Type -> Row Type -> Typetype Simulation r linkRow = { alpha :: Ref Number, animationId :: Ref (Maybe Int), callbacks :: Maybe SimulationCallbacks, config :: SimConfig, links :: Ref (Array (Link linkRow)), nodes :: Ref (Array (SimulationNode r)), prevAlpha :: Ref Number, running :: Ref Boolean, wasmSim :: WASMSimulation }

The Simulation handle Internal refs are implementation details - users interact via functions

#SimulationNode Source

type SimulationNode :: Row Type -> Typetype SimulationNode r = { fx :: Number, fy :: Number, id :: NodeID, vx :: Number, vy :: Number, x :: Number, y :: Number | r }

Simulation node with standard fields. Row polymorphic to allow extra user data. Note: fx/fy use Number with NaN for "not fixed" (D3 convention)

#SimConfig Source

type SimConfig = { alphaDecay :: Number, alphaMin :: Number, alphaTarget :: Number, ticksPerFrame :: Int, velocityDecay :: Number }

Simulation configuration

#NodeID Source

type NodeID = Int

Node ID type (matches D3 kernel)

#defaultConfig Source

defaultConfig :: SimConfig

Default simulation configuration

#create Source

create :: forall r linkRow. SimConfig -> Effect (Simulation r linkRow)

Create a simulation without callbacks

#createWithCallbacks Source

createWithCallbacks :: forall r linkRow. SimConfig -> SimulationCallbacks -> Effect (Simulation r linkRow)

Create a simulation with callbacks (for Halogen integration)

#start Source

start :: forall r linkRow. Simulation r linkRow -> Effect Unit

Start the animation loop

#stop Source

stop :: forall r linkRow. Simulation r linkRow -> Effect Unit

Stop the animation loop

#reheat Source

reheat :: forall r linkRow. Simulation r linkRow -> Effect Unit

Reheat the simulation (reset alpha and restart)

#setNodes Source

setNodes :: forall r linkRow. Array (SimulationNode r) -> Simulation r linkRow -> Effect Unit

Set/replace all nodes Note: We don't sync positions from PureScript to WASM because:

  1. WASM initializes nodes in a nice phyllotaxis pattern
  2. PureScript nodes typically start at (0,0) which causes convergence issues The WASM simulation will compute positions and we read them back via getNodes.

#getNodes Source

getNodes :: forall r linkRow. Simulation r linkRow -> Effect (Array (SimulationNode r))

Get current nodes with positions

#isRunning Source

isRunning :: forall r linkRow. Simulation r linkRow -> Effect Boolean

Check if simulation is running

#getAlpha Source

getAlpha :: forall r linkRow. Simulation r linkRow -> Effect Number

Get current alpha value

#getCallbacks Source

getCallbacks :: forall r linkRow. Simulation r linkRow -> Maybe SimulationCallbacks

Get callbacks (for Halogen integration) Returns the callbacks set at creation time

#configureManyBody Source

configureManyBody :: forall r linkRow. ManyBodyConfig -> Simulation r linkRow -> Effect Unit

Configure many-body force

#configureCenter Source

configureCenter :: forall r linkRow. CenterConfig -> Simulation r linkRow -> Effect Unit

Configure center force

#configureForceX Source

configureForceX :: forall r linkRow. ForceXConfig -> Simulation r linkRow -> Effect Unit

Configure forceX (pull toward x position)

#configureForceY Source

configureForceY :: forall r linkRow. ForceYConfig -> Simulation r linkRow -> Effect Unit

Configure forceY (pull toward y position)

#configureCollide Source

configureCollide :: forall r linkRow. CollideConfig -> Simulation r linkRow -> Effect Unit

Configure collide force (prevent node overlap)

#enableForces Source

enableForces :: forall r linkRow. { center :: Boolean, links :: Boolean, manyBody :: Boolean } -> Simulation r linkRow -> Effect Unit

Enable/disable forces (original 3)

#enableForcesAll Source

enableForcesAll :: forall r linkRow. { center :: Boolean, collide :: Boolean, forceX :: Boolean, forceY :: Boolean, links :: Boolean, manyBody :: Boolean } -> Simulation r linkRow -> Effect Unit

Enable/disable all forces including new ones