Control layout
Kekonic Diagrams owns coordinates, but you own visual structure. Give the engine a reading direction, meaningful boundaries, and a small number of constraints. Tune the result only after the model is clear.
Use the smallest effective control
Section titled “Use the smallest effective control”Work down this list. Stop as soon as the diagram reads well.
- Set
direction. - Reorder declarations to match the story.
- Add meaningful groups.
- Change
densityor crossing treatment. - Arrange regions into rows, stacks, or a grid.
- Split the diagram.
The last option is often better than adding more configuration.
Set the reading direction
Section titled “Set the reading direction”direction LR // left to rightdirection TD // top to bottomdirection RL // right to leftdirection BT // bottom to topArchitecture and data flow usually read well as LR. Workflows usually read well as TD. Choose
the direction that matches the story, not the available page shape.
Groups are layout boundaries
Section titled “Groups are layout boundaries”Kekonic Diagrams lays out the contents of a group and the relationships between groups. That makes a group stronger than a decorative enclosure:
group application "Application" { arrange: stack api: gateway "API" checkout: service "Checkout"}
group data "Data" { arrange: stack database: database "Postgres" events: broker "Kafka"}Use arrange: pack for a compact cluster, stack for horizontal bands in a top-down diagram or
vertical members in a left-to-right one, and row for the opposite axis.
Arrange groups deliberately
Section titled “Arrange groups deliberately”When the regions themselves have a stable order, wrap them in a parent and arrange the children:
group platform { chrome: false arrange: row align: stretch
group edge "Edge" { /* … */ } group core "Core" { /* … */ } group data "Data" { /* … */ }}Visible groups are a dashed outline without a fill — nested boxes would otherwise stack
translucent washes on the canvas. chrome: false makes the parent structural without painting
another visible box. align: stretch asks sibling regions to share the available cross-axis size.
Surround (center-and-ring)
Section titled “Surround (center-and-ring)”For ports-and-adapters or onion-style views, nest a hub group and put satellite nodes as
siblings with arrange: surround. Optional shape: hexagon or shape: circle paints that chrome
silhouette. Nest surround groups to build rings (adapters outside, ports inside):
group service "Order service" { shape: hexagon arrange: surround
group core "Domain" { arrange: stack app: component "Handler" }
api: component "API adapter" { side: west } store: component "Store adapter" { side: east }}Satellite nodes sit in the annulus inside the parent chrome and outside the hub. Depth is
unlimited: the hub may itself use arrange: surround. Kekonic Diagrams does not attach ports to hex faces.
For a whole-diagram staged composition, put arrange in the layout block. Ungrouped nodes and
top-level regions share the tracks in declaration order, so an actor, service boundary, adapter,
and external system can form one predictable progression without layout-only wrapper groups:
layout { arrange: row }
client: application "Client"group service "Service" { /* ports and core */ }repository: component "Repository Adapter"database: database "Database"Use a grid for two-dimensional structure
Section titled “Use a grid for two-dimensional structure”A grid is appropriate when both rows and columns have meaning—platform zones by concern and runtime, for example:
group platform { arrange: grid columns: [edge, core, data] rows: 2
group gatewayPlane "Edge" { column: edge } group services "Core" { column: core; rowSpan: 2 } group stores "Data" { column: data } group operations "Operations" { column: edge; row: 2 }}Use named columns when names make the source easier to review. rowSpan and colSpan let a region
occupy more than one track. A grid is not a pixel canvas; it declares relationships between regions.
Tune the result, not the coordinates
Section titled “Tune the result, not the coordinates”Put diagram-wide policy in blocks:
layout { density: normal spacingScale: 1.1 groupLayout: compound considerModelOrder: true}
edges { route: metro crossings: smart}density is the first spacing control. spacingScale is a multiplier for finer adjustment.
considerModelOrder asks the layout engine to respect declaration order where it can; it is a
preference, not a guarantee.
Routes:
metro(default) androunded— orthogonal corridors with eased ports and curved avoidance (not sharp 90° stairs)orthogonal— the same corridors with sharp cornersstraight— a true port-to-port chord when that line misses other nodes; otherwise a short dogleg that follows the existing corridorbezier— a smoother cubic along that corridor, using port exit/entry directions and splitting around nodes instead of drawing a naive center-to-center S-curve
Crossing treatment can be none, gaps, jumps, or smart. Layout still owns the
channel; metro, rounded, bezier, and straight refine it rather than inventing a
second router.
Swimlanes versus owner columns
Section titled “Swimlanes versus owner columns”swimlane groups are horizontal responsibility bands with a shared left-to-right process
timeline and a left header. Adjacent lanes share a hairline, not a dashed box around each band.
Top-level swimlanes infer groupLayout: swimlane and direction: LR. See
Expense approval.
arrange: row (or stacked groups inside a row) is the right tool for owner columns — architecture
or workflow bands that do not share a process axis. See Customer refund request.
Do not force a column composition into swimlane just because the groups are named after teams.
When layout goes wrong
Section titled “When layout goes wrong”Diagnose structure before spacing:
- No obvious entry point: the graph may have several stories; split it or raise one path’s priority.
- Groups create huge empty areas: remove weak boundaries or avoid deeply nested compound groups.
- Too many crossings: reduce edges, group related endpoints, or split views before increasing spacing.
- Labels fight the lines: shorten them and put detail in surrounding prose.
- One node dominates: shorten its label or use
minWidth/maxWidthintentionally.
Kekonic Diagrams does not expose arbitrary coordinates. If the exact position of an individual shape is a hard requirement, use a drawing tool.