Module

Hylograph.ForceEngine.Links

Package
purescript-hylograph-simulation
Repository
afcondon/purescript-hylograph-simulation

Link Operations for Force Simulations

Functions for working with links in force-directed graphs:

  • Swizzling: converting index-based links to node-reference links
  • Filtering: selecting links for node subsets

These operations are essential for:

  • Rendering (need node references to read x,y positions)
  • GUP patterns (filtering to visible nodes)
  • Dynamic graph updates

PERFORMANCE: Hot-path functions use FFI-backed O(1) Set/Map lookups instead of O(n) array scans to handle 1000+ node graphs at 60fps.

#swizzleLinksByIndex Source

swizzleLinksByIndex :: forall node rawLink swizzled. (node -> Int) -> Array node -> Array { source :: Int, target :: Int | rawLink } -> (node -> node -> Int -> { source :: Int, target :: Int | rawLink } -> swizzled) -> Array swizzled

Swizzle links by looking up nodes by their index field

USE THIS when working with a FILTERED node subset where array positions don't match node.index values. Looks up nodes by their .index field and silently drops links where either endpoint is not found.

PERFORMANCE: Uses FFI-backed IntMap for O(1) lookups instead of O(n) find.

This is essential for GUP patterns where you show only a subset of nodes.

Example:

let visibleNodes = filter isVisible allNodes
    swizzled = swizzleLinksByIndex _.index visibleNodes links \src tgt i link ->
      { source: src, target: tgt, index: i, value: link.value }

#filterLinksToSubset Source

filterLinksToSubset :: forall node linkData. (node -> Int) -> Array node -> Array { source :: Int, target :: Int | linkData } -> Array { source :: Int, target :: Int | linkData }

Filter links to only those where both endpoints are in the node subset

PERFORMANCE: Uses FFI-backed IntSet for O(1) membership instead of O(n) elem.

Use this before swizzling when you want to show links only between visible/selected nodes. Pairs naturally with swizzleLinksByIndex.

Example:

let visibleNodes = filter isVisible allNodes
    visibleLinks = filterLinksToSubset _.index visibleNodes allLinks
    swizzled = swizzleLinksByIndex _.index visibleNodes visibleLinks transform

#IntSet Source

data IntSet

Opaque IntSet backed by JavaScript Set - O(1) membership

#buildIntSet Source

buildIntSet :: Array Int -> IntSet

Build an IntSet from an array of integers - O(n)

#intSetMember Source

intSetMember :: Int -> IntSet -> Boolean

Check membership - O(1)

#IntMap Source

data IntMap t0

Opaque IntMap backed by JavaScript Map - O(1) lookup

#buildIntMap Source

buildIntMap :: forall node. (node -> Int) -> Array node -> IntMap node

Build an IntMap from nodes using an index accessor

#intMapLookup Source

intMapLookup :: forall a. Int -> IntMap a -> Maybe a

Safe lookup wrapper

#StringSet Source

data StringSet

Opaque StringSet backed by JavaScript Set - O(1) membership

#buildStringSet Source

buildStringSet :: Array String -> StringSet

Build a StringSet from an array of strings - O(n)

#stringSetMember Source

stringSetMember :: String -> StringSet -> Boolean

Check membership - O(1)