Module

DataViz.Layout.Hierarchy.EdgeBundle

Package
purescript-hylograph-layout
Repository
afcondon/purescript-hylograph-layout

DataViz.Layout.Hierarchy.EdgeBundle

Hierarchical edge bundling layout for visualizing dependencies in hierarchical data.

Based on Danny Holten's algorithm: "Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data"

This module provides:

  • Hierarchy construction from flat dot-notation names
  • Bidirectional link creation (bilink)
  • Radial cluster layout for node positioning
  • Bundle curve rendering with adjustable tension (beta)

Example Usage:

import DataViz.Layout.Hierarchy.EdgeBundle as EdgeBundle

-- Given flat data with imports
nodes :: Array { name :: String, size :: Number, imports :: Array String }

-- Build the visualization
result = EdgeBundle.edgeBundle
  { getName: _.name
  , getImports: _.imports
  , beta: 0.85
  , radius: 400.0
  }
  nodes

-- result contains:
--   nodes: positioned nodes for rendering
--   links: paths between connected nodes

#edgeBundle Source

edgeBundle :: forall a. EdgeBundleConfig a -> Array a -> EdgeBundleResult a

Main entry point: compute edge bundle layout

Takes configuration and array of nodes with imports, returns positioned nodes and bundled link paths.

#EdgeBundleConfig Source

type EdgeBundleConfig a = { beta :: Number, getImports :: a -> Array String, getName :: a -> String, innerRadius :: Number, outerRadius :: Number }

Configuration for edge bundle layout

#EdgeBundleResult Source

type EdgeBundleResult a = { links :: Array BundledLink, nodes :: Array (PositionedNode a) }

Result of edge bundle layout

#PositionedNode Source

type PositionedNode a = { cartX :: Number, cartY :: Number, data_ :: Maybe a, fullName :: String, incomingCount :: Int, isLeaf :: Boolean, outgoingCount :: Int, shortName :: String, x :: Number, y :: Number }

A node positioned for rendering

Re-exports from DataViz.Layout.Hierarchy.EdgeBundle.Bilink

#BilinkedTree Source

type BilinkedTree a = BilinkedNode a

Type alias for the complete bilinked tree

#BilinkedNode Source

data BilinkedNode a

A node with bidirectional link information

Constructors

Instances

#getOutgoing Source

getOutgoing :: forall a. BilinkedNode a -> Array Link

Get outgoing links from a node

#getIncoming Source

getIncoming :: forall a. BilinkedNode a -> Array Link

Get incoming links to a node

#getBilinkedFullName Source

getBilinkedFullName :: forall a. BilinkedNode a -> String

Get full name of a bilinked node

#getBilinkedData Source

getBilinkedData :: forall a. BilinkedNode a -> Maybe a

Get the data from a bilinked node

#getBilinkedChildren Source

getBilinkedChildren :: forall a. BilinkedNode a -> Array (BilinkedNode a)

Get children of a bilinked node

#allBilinkedNodes Source

allBilinkedNodes :: forall a. BilinkedNode a -> Array (BilinkedNode a)

Get all nodes in the tree (pre-order)

#allBilinkedLeaves Source

allBilinkedLeaves :: forall a. BilinkedNode a -> Array (BilinkedNode a)

Get all leaf nodes from a bilinked tree

Re-exports from DataViz.Layout.Hierarchy.EdgeBundle.BundleCurve

#BundlePoint Source

type BundlePoint = { x :: Number, y :: Number }

A point on the bundle path

#bundlePathRadial Source

bundlePathRadial :: Number -> Array { angle :: Number, radius :: Number } -> String

Generate bundle path from radial coordinates Takes (angle, radius) pairs and converts to Cartesian for rendering

#bundlePathCartesian Source

bundlePathCartesian :: Number -> Array { x :: Number, y :: Number } -> String

Generate bundle path from Cartesian coordinates directly

#bundlePath Source

bundlePath :: Number -> Array BundlePoint -> String

Generate SVG path for a bundle curve given points Uses quadratic Bezier spline approximation with bundle tension

The beta parameter controls tension:

  • beta = 0: control points are not adjusted (straight-ish curve)
  • beta = 1: control points follow the path exactly (maximum bundling)

#beta Source

beta :: Number

Default beta (tension) value - D3's default

Re-exports from DataViz.Layout.Hierarchy.EdgeBundle.Hierarchy

#TreeNode Source

data TreeNode a

A node in the hierarchy tree Generic over the leaf data type

Constructors

Instances

#pathBetween Source

pathBetween :: forall a. TreeNode a -> TreeNode a -> TreeNode a -> Array (TreeNode a)

Find the path between two nodes through their lowest common ancestor Returns: path from source up to LCA, then down to target D3's node.path(target) implementation

#leaves Source

leaves :: forall a. TreeNode a -> Array (TreeNode a)

Get all leaf nodes

#isLeaf Source

isLeaf :: forall a. TreeNode a -> Boolean

Check if a node is a leaf (no children)

#getTreeNodeName Source

getTreeNodeName :: forall a. TreeNode a -> String

Get the short name of a node

#getTreeNodeData Source

getTreeNodeData :: forall a. TreeNode a -> Maybe a

Get the user data (if this is a leaf)

#getTreeNodeChildren Source

getTreeNodeChildren :: forall a. TreeNode a -> Array (TreeNode a)

Get children of a node

#getFullName Source

getFullName :: forall a. TreeNode a -> String

Get the full name of a node

#getAncestors Source

getAncestors :: forall a. TreeNode a -> TreeNode a -> Array (TreeNode a)

Get all ancestors of a node (from root to node, inclusive) This traverses down from root to find the path

#findNode Source

findNode :: forall a. String -> TreeNode a -> Maybe (TreeNode a)

Find a node by its full name

#descendants Source

descendants :: forall a. TreeNode a -> Array (TreeNode a)

Get all descendant nodes (pre-order traversal, including self)

#buildHierarchy Source

buildHierarchy :: forall a. { getName :: a -> String } -> Array a -> TreeNode a

Build a hierarchy from flat imported nodes Takes an array of nodes with dot-notation names and builds a tree

Algorithm:

  1. For each node, split name by "." to get path components
  2. Create/find intermediate nodes for each path component
  3. Attach leaf data at the final node

Re-exports from DataViz.Layout.Hierarchy.EdgeBundle.RadialCluster

#RadialNode Source

data RadialNode a

A node with radial coordinates

Constructors

Instances

#RadialLayoutConfig Source

type RadialLayoutConfig = { endAngle :: Number, innerRadius :: Number, outerRadius :: Number, startAngle :: Number }

Configuration for radial cluster layout

#toCartesian Source

toCartesian :: forall a. RadialNode a -> { x :: Number, y :: Number }

Convert radial coordinates to Cartesian for SVG rendering

#radialClusterFromTree Source

radialClusterFromTree :: forall a. TreeNode a -> RadialNode a

Convenience function: layout from a TreeNode using default config

#radialCluster Source

radialCluster :: forall a. RadialLayoutConfig -> TreeNode a -> RadialNode a

Apply radial cluster layout to a tree

Algorithm:

  1. Assign sequential indices to leaves (angular positions)
  2. Position leaves evenly around the circle at outerRadius
  3. Position internal nodes at mean angle of children, at appropriate radius

#defaultRadialConfig Source

defaultRadialConfig :: RadialLayoutConfig

Default configuration