Hylograph.Data.DAGTree
- Package
- purescript-hylograph-graph
- Repository
- afcondon/purescript-hylograph-graph
DAG Tree: Tree Layout with Extra Links
A DAG (Directed Acyclic Graph) Tree is a tree structure with additional cross-links that don't fit the tree hierarchy. This is useful for visualizing structures that are "mostly hierarchical" with some extra connections.
Examples:
- Git commit graphs (tree + merge commits)
- State machines (tree of states + back-edges)
- The GUP flow diagram (tree + merge arrows)
- Dependency graphs with highlighted cycles
== Design
The tree is laid out using standard algorithms (Tidy/Dendrogram), which assigns x,y positions to each node. The extra links are then rendered as paths between nodes using their computed positions.
This keeps tree layout clean while allowing graph-like visualizations.
== Usage
- Build your tree structure with unique node IDs
- Define extra links between node IDs
- Apply tree layout to get positions
- Render tree edges + extra links
let dagTree =
{ tree: mkTree root children
, extraLinks:
[ { source: "enter", target: "merge", linkType: "flow" }
, { source: "update", target: "merge", linkType: "flow" }
]
}
-- Layout tree
let positioned = layoutDAGTree Vertical dagTree
-- Render with Tree API
renderDAGTree positioned linkGenerator
#PositionedDAGTree Source
type PositionedDAGTree nodeId datum = { extraLinks :: Array { linkType :: String, source :: PositionedNode datum, target :: PositionedNode datum }, nodeMap :: Map nodeId (PositionedNode datum), nodes :: Array (PositionedNode datum), treeLinks :: Array { source :: PositionedNode datum, target :: PositionedNode datum } }A DAG tree after layout has been applied.
Contains positioned nodes and resolved link coordinates.
#PositionedNode Source
type PositionedNode datum = { datum :: datum, depth :: Int, x :: Number, y :: Number }A node with its computed position from tree layout.
#layoutDAGTree Source
layoutDAGTree :: forall nodeId datum. Ord nodeId => TreeLayout -> { height :: Number, width :: Number } -> DAGTree nodeId datum -> PositionedDAGTree nodeId datumApply tree layout and resolve link positions.
This computes positions for all nodes using a tree layout algorithm, then resolves the extra links to their source/target coordinates.
The layout parameter determines orientation:
- Vertical: root at top, children below
- Horizontal: root at left, children right
- Radial: root at center, children radiating out
Note: This is a simplified layout that doesn't use D3's tree algorithms. For production use with large trees, integrate with d3.tree() or d3.cluster().
#getNodePosition Source
getNodePosition :: forall nodeId datum. Ord nodeId => nodeId -> PositionedDAGTree nodeId datum -> Maybe { x :: Number, y :: Number }Get position of a node by ID.
#getExtraLinkPositions Source
getExtraLinkPositions :: forall nodeId datum. PositionedDAGTree nodeId datum -> Array { linkType :: String, sourceX :: Number, sourceY :: Number, targetX :: Number, targetY :: Number }Get source and target positions for all extra links.
Useful for generating path data for link rendering.