This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Notebooks · lib/graphlayout

Layered graph layout

layered(g) places the nodes of a directed graph in layers, the way Graphviz's dot does (Sugiyama, Tagawa and Toda, 1981; Gansner, Koutsofios, North and Vo, 1993), and routes every edge between them. The input is a LayoutInput: each node's size, each edge's ends, and for each edge whether it runs against the direction of the layers (a value carried to the next pass of a loop), how much it wants to be straight, where it leaves its source and enters its target, and the size of its label. The output is a Layered: each node's center, each edge's route as a polyline, and each label's center.

Layers run down the page (the rank axis is y, growing downward); a caller that wants them left to right swaps the sizes on the way in and the coordinates on the way out. The four phases:

  1. Cycles. A depth-first search from each node in order turns every edge that closes a cycle around; so does every edge the caller marks back. The rest of the layout sees a graph with no cycles.
  2. Ranks. Longest path: a node's rank is one more than the largest rank of the nodes with an edge into it. A node with no edge in is then moved down to one rank above the nearest node it points to, so it is not left at the top, far from what it feeds.
  3. Order. An edge that spans several ranks gets a dummy node on each rank between, so every edge joins adjacent ranks. The nodes of each rank are ordered by barycenter sweeps, down then up, twelve in all: each node goes to the mean position of its neighbors on the rank before. The order with the fewest crossings is kept; then two neighbors on a rank change places while that removes crossings (the transpose step).
  4. Coordinates. Each node wants to sit at the weighted mean of its neighbors' positions (an edge's weight is larger between dummies, so a long edge runs straight). On each rank the positions nearest those wishes that keep the order and the gaps are found exactly, by pool-adjacent-violators (a least-squares fit under ordering constraints). Sweeps alternate down and up.

The output is deterministic: no hash, no random choice, ties broken by node index.

Used with import graphlayout.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

This program declares a record type (LayoutInput), and records run only in compiled C for now, so the Run buttons here are off. Open it in the workbench and use its C tab to compile it.

Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.

[1]lines 45–1165