Diagrams

Diagram blocks are wdoc's way of drawing diagrams and charts on pages. A diagram is made of shapes that break down into primitive shapes and render as SVG, which lets the same source target different backends.

§ 1The diagram block

Diagrams have the following properties that can be set.

PropertyTypeRequiredDescription
widthi64yesDiagram canvas width in pixels.
heighti64yesDiagram canvas height in pixels.
ididentifiernoOptional explicit HTML id.
classlist<utf8>noOptional style classes.
layoutsymbolnoLayout mode: :free (default, manual x/y) / :grid / :layered / :force / :radial.
directionsymbolnoFlow direction for :layered: :top_to_bottom (default) / :left_to_right.
layer_gapf64noSpacing between ranks (layers) in :layered layout.
node_gapf64noSpacing between nodes within a rank in :layered layout.
cell_widthf64noGrid cell width for :grid layout.
cell_heightf64noGrid cell height for :grid layout.
columnsi64noNumber of columns for :grid layout.
gapf64noGap between cells in :grid layout.
iterationsi64no:force relaxation steps (default 300).
repulsionf64no:force node repulsion strength (default 9000).
link_distancef64no:force ideal edge-to-edge length (default 60).
gravityf64no:force centering pull (default 0.05).
seedi64no:force random seed for reproducible layouts (default 1).
hubidentifierno:radial hub shape id (defaults to the highest-degree shape).
radiusf64no:radial radius of the first ring (default: auto-fit to shape sizes).
ring_gapf64no:radial added radius per successive ring (default 120).
start_anglef64no:radial angle (radians) of the first shape on each ring (default -PI/2, i.e. top).
routingsymbolnoEdge routing: :elbow (default) / :straight.
edge_separationf64noNudge step that separates parallel edges (default 4).
pan_zoomboolnoWhen true, wrap in an interactive viewport with wheel-zoom, drag-pan, and +// controls.
zoom_minf64noMinimum zoom scale; 1.0 = fitted view (default 1.0).
zoom_maxf64noMaximum zoom scale (default 4.0).
pan_marginf64noExtra overscroll past the content bounds, in px (default 0).
descutf8noAccessible description: becomes the SVG's <title> and aria-label, so screen readers can announce the diagram.
edgeslist<Edge>yesEdges connecting shapes (a -> b).

Child blocks

SlotAcceptsMultipleDescription
childrenSvgBlockyesThe shapes drawn in the diagram.

For accessibility, give a diagram a desc — it becomes the SVG's <title> and aria-label, so screen readers announce the diagram instead of skipping it.

§ 2Pan & zoom

Set pan_zoom = true to wrap the diagram in an interactive viewport. Wheel zooms toward the cursor, drag pans, the corner buttons zoom about centre / reset. Zoom is clamped to [zoom_min, zoom_max]; pan allows half-a-viewport of overscroll past each content edge plus the author's pan_margin. Try it on the diagram below:

wcl
diagram {
  width = 320  height = 160  pan_zoom = true
  zoom_min = 0.5  zoom_max = 4.0
  rect { id = a  x = 20.0   y = 30.0  width = 80.0  height = 50.0  fill = "#88c0d0" }
  rect { id = b  x = 210.0  y = 90.0  width = 80.0  height = 50.0  fill = "#a3be8c" }
  a -> b
}

§ 3Linking shapes to pages

Give any shape a link to turn it into a hyperlink: clicking the box/pill navigates to that page — handy when each shape stands for a node that has its own page. The target resolves exactly like a prose link: a bare page name → page.html, a cross-site site:page, and an unknown page fails the build the same way a bad markdown link does. Try clicking the shape below:

Primitive shapes
wcl
diagram { width = 320  height = 100
  process "Primitive shapes" { link = "wdoc_primitives" }
}

Because SVG/HTML anchors can't nest, don't put link on a container whose children are also linked — link the container's title label instead. On a pan_zoom diagram a plain click still navigates, while a drag-to-pan that happens to end on a linked shape does not.

§ 4Styling shapes with classes

Every shape takes a class list, just like text. A class emits SVG paint properties — fill, stroke, stroke_width, stroke_linecap, stroke_linejoin, opacity — with dark { } / light { } overrides, so you style shapes the same way you style prose. Prefer a class over an inline fill = … so a shape follows the site theme and the reader's light/dark mode.

wcl
// Declared at the top level (apply site-wide). Hyphenated names may be
// written bare (`class dgm-box`) or quoted.
class "dgm-box" {
  fill         = "#5e81ac"
  stroke       = "#2e3440"
  stroke_width = "2"
  dark  { fill = "#88c0d0"  stroke = "#eceff4" }
  light { fill = "#5e81ac"  stroke = "#2e3440" }
}
class "dgm-ghost" {
  fill    = "#a3be8c"
  opacity = "0.5"
}

diagram { width = 320  height = 120
  rect { x = 20.0   y = 25.0  width = 110.0  height = 70.0  class = ["dgm-box"] }
  rect { x = 160.0  y = 25.0  width = 110.0  height = 70.0  class = ["dgm-ghost"] }
}

The SVG paint fields a class understands on a shape:

FieldEffect
fillInterior colour.
strokeOutline colour.
stroke_widthOutline thickness.
stroke_linecap / stroke_linejoinLine end / corner style.
opacityOverall transparency (01).
dark { } / light { }Per-colour-scheme overrides.

Built-in shape classes work the same way — redeclare a quoted name to recolour it everywhere. For example, the chart palette (wdoc-series-1..wdoc-series-8) or the timeline parts:

wcl
class "wdoc-series-1" {
  fill   = "#bf616a"
  stroke = "#bf616a"
  dark  { fill = "#d08770" }
}