Skip to main content

05.22Interfaces

Displaying a task dependency graph so one person sees what to do next

How to draw a 20 to 60 item work dependency DAG so one person sees what to do next and why. Layered swimlanes with a ready-to-start band came out ahead.

Plate: swimlanes hold a dependency graph; the nodes ready to start glow in a highlighted vertical band.Four horizontal swimlanes hold a small dependency graph: two finished nodes in ink, three ready nodes in violet inside a highlighted vertical band labelled ready, and later nodes in outline.READYR-22INTERFACESMOTIF: GRIDS2026 · 10 · PLATE 22 / 30FINDINGSWIMLANES, AND A READY-TO-START BAND
On this page
  1. The question and the constraints
  2. Research on perception and attention
  3. Method-by-method comparison
  4. How to encode the specific attributes of this problem
  5. Recommendation
  6. Gaps and caveats

How should a directed acyclic graph (DAG) of work items be drawn so that one person can see at a glance what to do next and why? AR Labs researched that question in October 2026, and the findings informed the layout of Taskgraph, our status map of AI agent work. The report compares eleven display methods, from layered Graphviz layouts and swimlanes to dependency structure matrices and ready-front lists, against published graph-perception experiments and the documentation of existing tools such as ELK, Nx, Bazel, GitHub and beads_viewer.

The question and the constraints

The goal is a picture of a task graph that lets one person answer two questions at a glance: what should I do next, and why that and not something else. The graph is a DAG (directed acyclic graph) of work items joined by "blocks" edges. Items carry a status (open, in progress, closed, blocked, waiting on a human), may sit inside a parent container, and the user can pick one item as the focus. There are roughly 20 to 60 open items, grouped into a few streams (sets of items that touch the same code), with a few edges crossing between streams. Each edge carries a reason and a confidence. Some items are unassessed, meaning nobody has sequenced them yet, so they have no trustworthy edges.

The output must work as a static SVG generated from data, and ideally also in a terminal UI (TUI) or a small web view.

Two facts from the size alone shape everything below. First, 20 to 60 nodes sits just above the threshold where Ghoniem, Fekete and Castagliola found node-link diagrams start to lose to matrices on most graph-reading tasks (about 20 vertices), but path-following stayed in favour of node-link at every size they tested (Ghoniem et al. 2004/2005). "Why is this next?" is a path question (what does it unblock, what blocks it), so node-link keeps the edge for this use. Second, edge crossings are the single aesthetic that most hurts comprehension: Purchase's experiments ranked crossing reduction "by far the most important" ahead of bends and symmetry (Purchase 1997; Purchase, validating aesthetics). Any method that keeps streams apart and routes only the few cross-stream edges between them is working with this result rather than against it.

Research on perception and attention

  • Edge crossings. Purchase (1997) found crossings dominate the error and time cost of reading a graph; bends and symmetry matter less (Springer, Glasgow eprint). Later work by Huang, Hong and Eades (2008, "Effects of crossing angles", not re-fetched this session) refined this: crossings at near-right angles cost much less than shallow ones, which is the argument for orthogonal edge routing.
  • Matrix versus node-link. Ghoniem et al. found matrices beat node-link above about 20 nodes for tasks such as "is there an edge between A and B" and "which node has most links", while node-link wins on path finding (Semantic Scholar). A large online replication by Okoe, Jianu and Kobourov reached a similar split: node-link better for topology and path tasks, matrices better for adjacency-lookup tasks (Okoe et al. 2019, Network Science). Keller, Eckert and Clarkson studied engineering connectivity models specifically, which is close to the DSM case below (Keller et al. 2006).
  • Layered drawings. The Sugiyama framework (layer assignment, crossing minimisation by reordering within layers, coordinate assignment) is the standard method for directed graphs because it makes almost all edges point one way, which lets a reader treat position as sequence. Graphviz dot is the reference implementation (Gansner et al., "A technique for drawing directed graphs", 1993, from background knowledge). ELK Layered is a modern implementation that also handles compound nodes, cross-hierarchy edges, ports and orthogonal routing (ELK Layered reference; Domrös et al., The Eclipse Layout Kernel, arXiv 2311.00533).
  • Attention over long lists. No source in this session measured attention decay over task lists directly. Two adjacent findings apply and are cited from background knowledge rather than re-verified: the serial-position effect (Murdock 1962), where items in the middle of a list are recalled worst; and the SmartBear/Cisco code-review study (Cohen, "Best Kept Secrets of Peer Code Review", 2006), which found defect detection falls off sharply past about 200 to 400 lines per session. The practical consequence is that a flat list of 60 items will have its middle skimmed, so the view should put the few actionable items in a short, separate band and let the rest recede.

Method-by-method comparison

The table condenses the per-method findings below.

Method Shows well Hides or struggles with Static SVG fit
1. Layered (Sugiyama) layout Direction and depth; paths from the focus Stream membership; long edges; layout shifts between runs Excellent
2. Swimlanes by stream Stream membership; cross-stream edges Sequence, unless a layered layout runs inside lanes Excellent, simplest to hand-generate
3. Transit or metro map Streams as parallel lines with interchanges Branching within a stream; edge reasons Possible but costly
4. Critical path / PERT The longest chain that gates the end goal Parallel work off the path; needs durations to mean much Good as an overlay
5. Now/next/later columns "What next" with almost no reading The edges themselves, so "why" needs text cues Excellent; also works as plain text
6. Dependency structure matrix Every edge with no crossings; sequencing errors Path tracing; unfamiliar to most readers Excellent as an audit view
7. Arc diagram One linear order; backward dependencies Two-dimensional structure; crowds as edges grow Good as a compact strip
8. Ready-front list Exactly what can start now Everything beyond the frontier Trivial; best as a band over a graph
9. GitHub / Linear views One item's blockers and dependents The whole graph Not a generator; borrow the focus panel
10. Bazel / Nx visualisers Build structure with filtering Work status (blocked, waiting, confidence) Not designed for it
11. Focus-centred / force-directed Neighbourhood of one item; free exploration Direction as position (force-directed) Focus view is a strong secondary view

1. Layered (Sugiyama) layout: Graphviz dot, dagre, ELK

  • Shows well: direction and depth. Rank (left to right, or top to bottom) reads as "how many steps away", so the ready items line up at one edge. Paths from the focus to what it unblocks are easy to trace.
  • Hides: stream membership, unless clusters are added; long edges spanning many ranks become dummy-node chains that are hard to follow; layout can shift a lot when one edge changes, which breaks the reader's mental map between runs.
  • Scale at 20 to 60: comfortable. Crossing minimisation is heuristic but produces clean output at this size.
  • Containers and cross-group edges: dot supports clusters (subgraph cluster_x) and, with compound=true, edges clipped to cluster borders (lhead/ltail). ELK supports true compound nodes and cross-hierarchy edges when hierarchyHandling=INCLUDE_CHILDREN is set so the whole graph is laid out in one run (ELK hierarchy handling). dagre has weak compound support and is largely unmaintained; users of React Flow commonly move to ELK for subflows (xyflow discussion #3495).
  • Crossings: minimised by design; ELK's orthogonal routing makes the remaining crossings right-angled and therefore cheaper to read.
  • Tooling: Graphviz (dot, native SVG output), elkjs (JavaScript, gives coordinates and you render SVG yourself), dagre/dagre-d3, Mermaid flowcharts (dagre or ELK renderer), D2. Bazel's query --output=graph emits dot for exactly this purpose (Bazel query reference; Graphviz Bazel gallery).
  • Static SVG fit: excellent. dot writes SVG directly, including <title> tooltips and URL links, so edge reasons can be hover text.

2. Swimlanes by stream

  • Shows well: which stream each item belongs to, and how much work sits in each stream. Cross-stream edges become visually distinct because they are the only edges leaving a lane.
  • Hides: nothing by itself, but it is a constraint on a layout rather than a layout. Without a layered algorithm inside the lanes, sequence is lost.
  • Scale: good for a few streams (2 to 6). Many streams make lanes thin.
  • Containers and cross-group edges: the lane is the container. Parent/child containers can nest inside lanes as boxes. Cross-lane edges are the point of the view.
  • Crossings: within-lane edges rarely cross other lanes; cross-lane edges may cross whole lanes, so lane order should be chosen to put connected streams next to each other.
  • Tooling: dot with one rank=same-free cluster per stream and rankdir=LR approximates lanes; ELK supports layer and partition constraints (elk.partitioning) for stricter lanes, though users report layer constraints are not always respected in hierarchical mode (elkjs issue #327). A hand-written layout (lane = row, x = longest-path rank) is also simple at this size.
  • Static SVG fit: excellent, and the simplest of all to hand-generate.

3. Transit or metro-map style

  • Shows well: each stream as a "line" with items as stations, with interchanges where streams depend on each other. The metaphor is memorable and invites the reader to see streams as parallel tracks.
  • Hides: branching within a stream (a metro line is a path; a stream with internal fan-out breaks the metaphor); edge reasons have nowhere natural to go.
  • Scale: fine at this size visually, but the layout problem is hard. Nöllenburg and Wolff's high-quality method is a mixed-integer program (Nöllenburg & Wolff; KIT metro maps project; survey of automated metro map layout).
  • Containers and cross-group edges: containers have no natural encoding; cross-stream edges become interchanges, which works only if they are few.
  • Crossings: octilinear routing makes them readable, but solvers are slow and output is unstable between runs.
  • Tooling: research code (MetroSets, LOOM/loom-project) rather than off-the-shelf libraries.
  • Static SVG fit: possible but costly to build; a good presentation layer, poor as a daily generator.

4. Critical-path and PERT network diagrams

  • Shows well: the longest chain of dependent work, which is the chain that determines how far away the end goal is. Highlighting it tells the reader which items gate the most.
  • Hides: without durations, "critical path" degrades to "longest chain by count"; parallel opportunities off the path get less attention.
  • Scale: the drawing is a layered DAG (activity-on-node), so it scales the same way as method 1.
  • Containers and cross-group edges: traditional PERT has neither; they must be borrowed from layered layout.
  • Crossings: as method 1.
  • Tooling: any layered engine; the analysis is a longest-path computation. beads_viewer (bv) already computes a critical-path "impact" score and unblock counts for Beads issues (beads_viewer README).
  • Static SVG fit: good as an overlay (thicker or coloured edges) on a layered drawing, rather than as a separate view.

5. Gantt-without-dates and now/next/later columns

  • Shows well: the answer to "what next" with almost no reading. Columns are buckets: Now (ready or in progress), Next (one step from ready), Later (deeper). With rows per stream, this becomes a grid of stream by horizon.
  • Hides: the edges themselves, so "why" must come from a short text cue on each card ("unblocks 3", "waits on X"). Within a bucket, order carries no meaning unless you add it.
  • Scale: excellent; 60 cards in a 3 by 4 grid stays legible, and the column with the action is always the leftmost.
  • Containers and cross-group edges: containers become card groupings or indentation; cross-stream edges can be drawn as a few curves between cells or listed as text on the card.
  • Crossings: few or none, because most edges are not drawn.
  • Tooling: no library needed; this is a table. It renders directly as text in a TUI. beads_viewer's kanban and "actionable plan" (independent execution tracks with unblock counts) are close relatives.
  • Static SVG fit: excellent and trivial; it is also the only method that degrades gracefully to plain text and Markdown.

6. Dependency structure matrix (DSM)

  • Shows well: every edge at once with no crossings at all. Items ordered by sequence put all edges below the diagonal; any mark above the diagonal is a cycle or a sequencing error. Streams appear as blocks along the diagonal and cross-stream edges as marks off the blocks. Edge confidence can be cell colour.
  • Hides: paths. Following A to B to C means hopping rows and columns, which is the one task Ghoniem et al. found matrices consistently lose. Unfamiliar to most readers.
  • Scale: the best of any method at this size (60 by 60 cells is small), consistent with the matrix-scales-better result (Ghoniem et al.; adjacency matrix technique notes, Utah VDL).
  • Containers and cross-group edges: containers as nested diagonal blocks; cross-group edges are simply the cells outside the blocks. This is the cleanest encoding of the two of any method.
  • Crossings: none by construction.
  • Tooling: easy to hand-generate; DSM tools exist in systems engineering (for example Lattix, Cambridge Advanced Modeller) but are heavy for this.
  • Static SVG fit: excellent. Best used as an audit view (is the sequencing consistent, where are cross-stream couplings), not as the daily "what next" view.

7. Arc diagrams

  • Shows well: a single linear order (for example the proposed execution order) with dependencies as arcs above or below the line. Backward arcs (a dependency on something later in the order) stand out.
  • Hides: two-dimensional structure; parallelism looks like sequence.
  • Scale: arcs overlap badly as edge count grows; the method is known to crowd when there are many nodes (Wattenberg, Arc Diagrams; arc diagram overview). At 60 nodes with modest edge counts it is borderline.
  • Containers and cross-group edges: containers as bracketed spans of the line; cross-group edges as arcs in a distinct colour or on the opposite side.
  • Crossings: arcs cross often, but at steep angles near their feet.
  • Tooling: d3 examples, AntV G2 (arc diagram chart); trivially hand-generated.
  • Static SVG fit: good; useful as a compact strip, weak as the main view.

8. Ready-front (frontier) views

  • Shows well: exactly the items whose blockers are all closed, which is the honest answer to "what can I start now". Adding "unblocks N" and the blocker it is waiting on gives the "why".
  • Hides: everything beyond the frontier, by design.
  • Scale: independent of graph size; the frontier is usually a handful of items.
  • Containers and cross-group edges: frontier items can be tagged with their stream and parent.
  • Tooling: bd ready in Beads; bv's --robot-next, --robot-plan and triage views, which select a single highest-impact item from unblock count and priority (beads_viewer README; beads_viewer on pkg.go.dev).
  • Static SVG fit: trivial; it is a short list or a highlighted column. It works best as a band placed on top of a graph view, not alone.

9. GitHub-style and Linear-style dependency views

  • Shows well: a per-item neighbourhood: what blocks this, what this blocks, sub-issues with progress. GitHub made blocked-by and blocking relations generally available in August 2025, with is:blocked and blocking: search filters and up to 50 links per relation (GitHub changelog; feedback discussion).
  • Hides: the whole graph. Neither product draws the full DAG natively; the community discussion asks for it, and third-party viewers fill the gap, for example a self-hosted Linear dependency graph viewer (shdennlin/issue-graph).
  • Scale: per-item, so scale is not the issue; the missing overview is.
  • Containers and cross-group edges: sub-issues as a nested list; no cross-group concept.
  • Static SVG fit: not applicable as a generator. The useful idea to borrow is the focus panel: blockers above, dependents below.

10. Bazel and Nx task-graph visualisers

  • Shows well: Nx's nx graph gives an interactive project graph and a task graph, with filtering to a target and to a selected project's neighbourhood (Nx: explore your workspace; Nx 15.3 task graph). Bazel emits dot and relies on Graphviz (Bazel query guide).
  • Hides: status. These tools draw build structure, not work state, and have no notion of blocked, waiting on a human, or confidence.
  • Scale: Nx copes with hundreds of nodes through filtering, not through layout; Bazel's raw dot output is unreadable above a few dozen nodes without allpaths/somepath filtering.
  • Lesson to borrow: focus plus filtering. Both tools make the full graph usable by letting the user pick a node and show only its upstream and downstream cone. That maps directly onto the user-chosen focus described above.

11. Others found: focus-centred neighbourhood and force-directed

  • Focus-centred (egocentric) view: bv's terminal graph view puts the selected item in the centre with blockers above and dependents below, drawn with Unicode box-drawing characters, and expands paths on demand (beads_viewer README). This is the most TUI-native graph form and a strong secondary view.
  • Force-directed: bv's HTML export defaults to force-directed with DAG and radial modes as alternatives. Force layouts do not encode direction as position, so they serve exploration, not "what next".

How to encode the specific attributes of this problem

These encodings apply whichever layout is chosen.

  • Status. Closed items fade or drop out of the open view. In progress gets a heavy outline. Blocked gets a warm colour. Waiting on a human deserves its own shape or icon, not just a colour, because it is the one status the single viewer can act on directly; it should also be duplicated into the ready band.
  • Edge confidence. Line style: solid for high, dashed for medium, dotted for low. Line style survives greyscale printing and terminal rendering, where colour may not.
  • Edge reason. In SVG, put it in a <title> element so it shows on hover; in the static print, number the edge and list reasons in a legend. Short labels on cross-stream edges only, since those are the ones a reader will question.
  • Unassessed items. Put them in a separate "unsequenced" area, outside the ranked layout, drawn with a dashed outline. Placing them in the ranked layout would assert a position they have not earned.
  • Focus. Highlight the focus and its full upstream and downstream cone; dim everything else to low opacity rather than hiding it, so the reader keeps the overall shape (the Nx and Bazel lesson).

Recommendation

Recommended: a layered graph laid out in stream swimlanes, topped by a ready-front band. Draw each stream as a horizontal lane. Inside each lane, place items left to right by dependency depth, using a Sugiyama-style layout so that "further right" always means "later". Route the few cross-stream edges between lanes with right-angled lines in a distinct colour, labelled with their reason. Above the lanes, show a short band listing the items that can start now, each with its stream, how many items it unblocks, and the reason it is next. Put unassessed items in a dashed parking area below the lanes. When the user picks a focus, keep its upstream and downstream chain at full strength and fade the rest. This fits the research: lanes keep most edges inside their stream, which cuts crossings, the aesthetic Purchase found matters most; node-link keeps path-tracing easy, which Ghoniem et al. found matrices do badly; and the ready band puts the actionable handful at the top so they are not lost in the middle of a long list. It is buildable as a static SVG either with Graphviz dot (one cluster per stream, rankdir=LR, compound=true) or with elkjs for stricter lanes and orthogonal routing. At 60 items, a hand-written layout (lane is row, x is longest-path rank) is also practical and gives stable positions between runs.

Runner-up: a now/next/later grid, with streams as rows and horizons as columns. Each cell holds cards for the items at that horizon in that stream, and each card states what it waits on and what it unblocks. Edges are mostly not drawn; the few cross-stream ones appear as text on the card or as a handful of curves. It loses the visible chain of reasoning that the graph provides, but it is the easiest to read at a glance, it renders unchanged as plain text in a terminal, and it never produces a tangle.

Supporting views, not replacements: a dependency structure matrix as an occasional audit of sequencing and cross-stream coupling, and a focus-centred blockers-above, dependents-below panel for the TUI, which bv already demonstrates.

Gaps and caveats

  • No study found here tests these methods on task-tracking specifically; the perception results come from general graph-reading tasks.
  • The attention-decay evidence (serial-position effect, the code-review study) and Huang et al. on crossing angles are cited from background knowledge and were not re-fetched this session.
  • ELK's lane (partition) constraints were not tested; one elkjs issue reports layer constraints being ignored in hierarchical mode, so a prototype should confirm lane behaviour before committing to ELK over dot or a hand layout.
  • Linear's in-product views were not inspected directly.