Grid-based layout engine for flowchart diagrams.
Coordinate Systems
Grid coordinates {col, row} — logical positions on a coarse grid.
Each node occupies a 3×3 block centered at {col, row}. The 8 surrounding
cells are border/attachment cells used for edge routing.
Draw coordinates {x, y} — character positions in the final output.
Column widths and row heights vary (content, padding, gap, subgraph borders),
so a single grid cell may span many characters.
Layout Model
Nodes are separated by STRIDE grid units (default 4 = 3 block + 1 gap).
Gap cells between node blocks provide routing space for edges.
compute_layout/2 orchestrates the full pipeline: layer assignment, ordering,
placement, sizing, and coordinate conversion.
Summary
Functions
Compute the grid layout for a graph.
Check if a grid cell is not occupied, optionally excluding certain node IDs.
Convert grid coordinates to draw coordinates (top-left of the cell).
Convert grid coordinates to the center of the cell in draw coordinates.
Types
@type t() :: %Boxart.Layout{ canvas_height: integer(), canvas_width: integer(), col_widths: %{required(integer()) => integer()}, grid_occupied: %{required({integer(), integer()}) => String.t()}, offset_x: integer(), offset_y: integer(), placements: %{required(String.t()) => Boxart.Layout.NodePlacement.t()}, row_heights: %{required(integer()) => integer()}, subgraph_bounds: [Boxart.Layout.SubgraphBounds.t()], wrapped_labels: term() }
Functions
@spec compute_layout( Boxart.Graph.t(), keyword() ) :: t()
Compute the grid layout for a graph.
Options
:padding_x— horizontal padding inside nodes (default:4):padding_y— vertical padding inside nodes (default:2):gap— gap size between nodes in characters (default:4, minimum1)
Check if a grid cell is not occupied, optionally excluding certain node IDs.
Convert grid coordinates to draw coordinates (top-left of the cell).
Convert grid coordinates to the center of the cell in draw coordinates.