Module

LayeredLayout.Compaction.OneD

Package
purescript-layered-layout
Repository
markgrafhq/purescript-layered-layout

Constraint-graph data model and infrastructure for the post-routing one-dimensional compactor.

This is a port of ELK's org.eclipse.elk.alg.common.compaction.oned package: CGraph / CGroup / CNode / Quadruplet / ISpacingsHandler / ICompactionAlgorithm / IConstraintCalculationAlgorithm / OneDimensionalCompactor.

The Java code mutates the state in place. The PureScript port threads an OneDState a record through each step. The origin field on a CNode is polymorphic so the layered package can tag it with LNode | VerticalSegment without this module knowing the concrete sum.

Phase 2 of the post-routing compaction port (the network simplex algorithm lives in LayeredLayout.NetworkSimplex; the layered-graph bridge lives in LayeredLayout.Compaction.LGraphTransformer / LayeredLayout.Compaction.HorizontalGraphCompactor).

#Rect Source

type Rect = { height :: Number, width :: Number, x :: Number, y :: Number }

#KVec Source

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

#zeroVec Source

#CNodeId Source

type CNodeId = Int

#CGroupId Source

type CGroupId = Int

#CNode Source

type CNode a = { cGroup :: Maybe CGroupId, cGroupOffset :: KVec, constraints :: Array CNodeId, hitbox :: Rect, hitboxPreCompaction :: Rect, id :: CNodeId, ignoreSpacing :: Quadruplet, kind :: Maybe String, origin :: Maybe a, startPos :: Number }

Node in the constraint graph.

The origin field is polymorphic — the layered-graph bridge tags it with a sum of LNode and VerticalSegment, but this module does not need to look inside.

#CGroup Source

type CGroup = { cNodes :: Array CNodeId, delta :: Number, deltaNormalized :: Number, id :: CGroupId, incomingConstraints :: Array CNodeId, master :: Maybe CNodeId, outDegree :: Int, outDegreeReal :: Int, reference :: Maybe CNodeId, startPos :: Number }

Group of nodes whose relative offsets are preserved during compaction.

#CGraph Source

type CGraph a = { cGroupOrder :: Array CGroupId, cGroups :: Map CGroupId CGroup, cNodeOrder :: Array CNodeId, cNodes :: Map CNodeId (CNode a), nextCGroupId :: Int, nextCNodeId :: Int, predefinedHorizontalConstraints :: Array (CNodeId /\ CNodeId), predefinedVerticalConstraints :: Array (CNodeId /\ CNodeId), supportedDirections :: Set Direction }

Constraint graph.

#OneDState Source

type OneDState a = { cGraph :: CGraph a, compactionAlgorithm :: Maybe (ICompactionAlgorithm a), constraintAlgorithm :: Maybe (IConstraintCalculationAlgorithm a), direction :: Direction, finished :: Boolean, lockFun :: Maybe (ILockFunction a), spacingsHandler :: ISpacingsHandler a }

#ISpacingsHandler Source

type ISpacingsHandler a = { horizontalSpacing :: CNode a -> CNode a -> Number, verticalSpacing :: CNode a -> CNode a -> Number }

#ILockFunction Source

#ICompactionAlgorithm Source

#IConstraintCalculationAlgorithm Source

#runCompactionAlgorithm Source

#runConstraintAlgorithm Source

#Quadruplet Source

type Quadruplet = { down :: Boolean, left :: Boolean, right :: Boolean, up :: Boolean }

#fuzzyTolerance Source

#defaultSpacingsHandler Source

#newCGraph Source

newCGraph :: forall a. Set Direction -> CGraph a

#addCNode Source

addCNode :: forall a. { hitbox :: Rect, kind :: Maybe String, origin :: Maybe a } -> CGraph a -> { graph :: CGraph a, id :: CNodeId }

Create a new free-standing CNode in the graph. The node is not placed in any group yet — the OneDimensionalCompactor constructor wraps every group-less node in a singleton group.

#addCNodeWithGroup Source

addCNodeWithGroup :: forall a. { hitbox :: Rect, kind :: Maybe String, origin :: Maybe a } -> CNodeId -> CGraph a -> { graph :: CGraph a, id :: CNodeId }

Add a node and immediately group it with parent. Mirrors CNodeBuilder.groupWith(parent).create(graph).

#addCGroup Source

addCGroup :: forall a. { master :: Maybe CNodeId, nodes :: Array CNodeId } -> CGraph a -> { graph :: CGraph a, id :: CGroupId }

Create a new CGroup containing nodes. The first node in nodes becomes the initial reference.

#addCNodeToGroup Source

addCNodeToGroup :: forall a. CNodeId -> CGroupId -> CGraph a -> CGraph a

Move a node into a group. Mirrors CGroup.addCNode (which throws if the node already belongs to a group). The first node added becomes the group's reference.

#removeCNodeFromGroup Source

#supports Source

supports :: forall a. Direction -> CGraph a -> Boolean

#lookupCNode Source

lookupCNode :: forall a. CNodeId -> CGraph a -> Maybe (CNode a)

#lookupCGroup Source

lookupCGroup :: forall a. CGroupId -> CGraph a -> Maybe CGroup

#updateCNode Source

updateCNode :: forall a. CNodeId -> (CNode a -> CNode a) -> CGraph a -> CGraph a

#setCNodeIgnoreSpacing Source

setCNodeIgnoreSpacing :: forall a. CNodeId -> Quadruplet -> CGraph a -> CGraph a

OR q into the CNode's existing ignoreSpacing flags. Mirrors the merge semantics of VerticalSegment.unionInto so flags set by the transformer accumulate when a node is touched multiple times.

#updateCGroup Source

updateCGroup :: forall a. CGroupId -> (CGroup -> CGroup) -> CGraph a -> CGraph a

#allCNodes Source

allCNodes :: forall a. CGraph a -> Array (CNode a)

Iterate every CNode in insertion order.

#allCGroups Source

allCGroups :: forall a. CGraph a -> Array CGroup

Iterate every CGroup in insertion order.

#newOneD Source

newOneD :: forall a. CGraph a -> OneDState a

Construct a new compactor for the given graph. Matches the Java constructor: (1) compute group offsets so the left-most node in each group becomes the reference, (2) wrap any plain node in a singleton group, (3) snapshot the pre-compaction hitbox.

#setSpacingsHandler Source

#setCompactionAlgorithm Source

#setLockFunction Source

#compact Source

compact :: forall a. OneDState a -> OneDState a

Compact in the current direction. Defaults to LEFT if no direction has been set, then resets per-group outDegree and per-node startPos before running the configured algorithm.

#finish Source

finish :: forall a. OneDState a -> OneDState a

Mark the compactor as finished and restore the canonical LEFT orientation so any hitbox mirrors / transposes are undone.

#changeDirection Source

changeDirection :: forall a. Direction -> OneDState a -> OneDState a

Switch compaction direction. Mirrors / transposes hitboxes as needed and either recalculates the constraints or reverses them (for the LEFT<->RIGHT and UP<->DOWN flips).

#calculateGroupOffsets Source

calculateGroupOffsets :: forall a. OneDState a -> OneDState a

Public re-export of calculateGroupOffsetsGraph operating on the full state.

#forceConstraintsRecalculation Source

forceConstraintsRecalculation :: forall a. OneDState a -> OneDState a

Run the constraint calculation again without changing direction.

#isNodeLocked Source

isNodeLocked :: forall a. CNode a -> Direction -> OneDState a -> Boolean

#isGroupLocked Source