Skip to content

Diagram Principles — make the diagram teach

FieldValue
TypeSkill Resource
Source~/.copilot/skills/technical-writing/references/mermaid/diagram-principles.md
DescriptionNot specified

Source Content

Diagram Principles — make the diagram teach

Syntax validity is the floor, not the goal. A diagram can be perfectly valid and still teach nothing. These principles are the design layer: how to make a diagram a reader understands in five seconds. They govern flowcharts; sequence diagrams legitimately model actors as participant columns (see syntax-reference.md).

North star

Every diagram should answer two questions before anyone reads a label:

  1. What is the one thing this diagram is trying to teach?
  2. What are the natural groupings the reader needs to see to understand it?

If a reader can’t get both from a five-second glance, the diagram is doing too much or organized wrong.

House style: encode meaning three ways

Every diagram carries its meaning in icon and shape first, with colour added deliberately — never text alone. A reader decodes a glyph and a shape far faster than a label, and these cues mean the diagram still reads in greyscale print, for colour-blind readers, and at a glance. Plain unlabelled boxes with no icon are a house-style miss — but so is a rainbow of coloured boxes.

  • Icon. Give every actor, role, system, and outcome a consistent icon — a resident is always a person, an engineer a laptop, a store a database, a success a check, a failure an x. Reuse the same glyph for the same concept so the vocabulary is learnable. Prefer monotone FontAwesome icons (fas:fa-* / fab:fa-*, placed inline at the start of the label) over emoji. Emoji render differently on every OS — and as tofu where no emoji font is installed — and multicolour emoji read as AI-generated; one self-hosted monotone icon set renders identically everywhere and reads as considered and hand-made. Use emoji only as a fallback where FontAwesome cannot be loaded.
  • Colour. Monotone-first. Default every node, border, and icon to monotone (neutral / foreground). Add colour only when it teaches — the people/automation boundary, success/failure, or the one punchline node — or when the reader explicitly asks. Never decorative; always pair colour with an icon or text, never colour alone (WCAG). A wall of coloured boxes reads as machine output; restraint reads as care.
  • Shape. One shape per node type — see principle 8 below and the system-node vocabulary in gitops-patterns.md.

“Wherever possible” is the rule: if a type can carry an icon, give it one. The few that cannot — a Sankey encodes with band width, an ER diagram with crow’s-foot notation — already have their own visual language.

Icon vocabulary

Reuse these so a reader learns the set once. Extend it, but keep one glyph per concept. The emoji below name the concept; on any surface with FontAwesome loaded, render them as the monotone inline token instead — person → fas:fa-user, engineer → fas:fa-laptop-code, store → fas:fa-database, service → fas:fa-gear, cloud → fas:fa-cloud, success → fas:fa-circle-check, failure → fas:fa-circle-xmark, caution → fas:fa-triangle-exclamation, review → fas:fa-magnifying-glass, draft → fas:fa-pen-to-square, update → fas:fa-arrows-rotate, AI → fas:fa-robot. Brands use fab: (fab:fa-github).

ConceptIconConceptIcon
Resident / citizen / user🧑Web app / frontend🖥️
Engineer / technologist🧑‍💻API / service⚙️
Caseworker / staff🧑‍💼Case system🗂️
Cloud / platform☁️Store / database🗄️
Payments💳Queue📥
Notifications📨External registry🚗
Find / discovery🔍Apply / draft📝
Submit📤Review🔎
Success / grantedRefused / failure
Needs attention⚠️Permit / artefact issued🎫

Those emoji name the concept. Render each as an inline monotone FontAwesome token (fas:fa-* / fab:fa-* at the start of the label) — the same on every surface, design system and docs alike — using the full concept→token map in icons-and-surfaces.md. Use inline tokens, not @{ shape: icon } icon-nodes.

The grouping principle

Always group your nodes. A flat chain of nodes is the lowest form of diagram — it shows sequence but teaches nothing about structure. Grouping is what turns a diagram from a flowchart into an explanation.

Use Mermaid subgraph blocks to wrap related nodes. The groups tell the reader the diagram has a structure worth understanding before they read a single label. Groups are how the reader’s eye chunks the diagram into something memorable.

Without grouping:

flowchart LR
A --> B --> C --> D --> E

That’s a sequence. It’s correct and it’s forgettable.

With grouping:

flowchart LR
subgraph Group1["Discovery"]
A --> B
end
subgraph Group2["Procurement"]
C --> D
end
subgraph Group3["Delivery"]
E
end
Group1 --> Group2 --> Group3

Same five nodes. The reader now understands the diagram has phases, and they can hold each phase in mind as a unit. That’s the difference between scanning and understanding.

How to choose the right grouping

The grouping should match the most important boundary in the diagram. Different diagrams have different right answers:

If the diagram is about…Group by…
A workflow that involves both people and systemsWhat people do vs. automation (top priority — always try this first)
A multi-phase processPhase (Discovery / Build / Deploy)
A multi-team handoffTeam (Engineering / Procurement / Agency)
A request that crosses environmentsEnvironment (Local / Staging / Production)
A pipeline with conditional logicHappy path vs. error path
A system with internal layersLayer (Frontend / API / Data)

People vs. automation is the top-priority grouping when both are present. It’s the most important boundary in almost any technical diagram, because it tells the reader where their attention needs to be — people need to act on the left; the system handles the right. If you’re showing any flow that crosses from manual to automated, that boundary wins over every other grouping.

If people vs. automation doesn’t apply, fall back to the next most meaningful boundary from the table above. The rule is: always group by something, never leave the diagram flat.

A worked example

A diagram of a deploy pipeline could be grouped multiple ways. Three valid groupings, each teaching something different.

By environment — useful when the lesson is what runs where:

flowchart LR
subgraph Local["Local"]
A["Run tests"]
end
subgraph CI["CI"]
B["Build image"] --> C["Scan"]
end
subgraph Prod["Production"]
D["Deploy"] --> E["Health check"]
end
Local --> CI --> Prod

By people vs. automation — useful when the lesson is what you have to do vs. what happens to you:

flowchart LR
subgraph People["What people do"]
A["Open PR"] --> B["Review"] --> C["Merge"]
end
subgraph Auto["Automation"]
D["Build"] --> E["Deploy"] --> F["Verify"]
end
People --> Auto

By success path vs. failure path — useful when the lesson is what to do when things break:

flowchart TD
A["Deploy initiated"]
A --> B["Healthy"]
A --> C["Failed"]
subgraph Happy["Success"]
B --> D["Mark stable"]
end
subgraph Recovery["Failure"]
C --> E["Rollback"] --> F["Alert"]
end

The first question to ask is which boundary teaches the reader the most? The answer determines the grouping.

Core principles

1. Always group; lead with people vs. automation when both are present

Stated above. The most important rule. A flat diagram should be a warning sign that you haven’t decided what the diagram is for.

2. Nodes are states or actions, never actors

A node should be something that happens or exists, not someone who does. “Open PR” is a node. “Developer” is not — the developer is implied by the fact that opening a PR sits in the “What people do” group. Putting actors as separate nodes doubles the node count and forces the reader to mentally combine “Developer + Open PR” into one concept.

If you need to show who does something, put the actor on the edge label, not as a node:

flowchart LR
PR["Open PR"] -->|reviewer approves| Merge["Merge to main"]

This is the flowchart rule. Sequence diagrams are the exception: there, actors are participant columns and belong in the diagram by design. Multi-layer system/topology diagrams are the other exception — a pipeline’s start and end actors (who triggers it, who receives the result) may be drawn as (( )) circles; see gitops-patterns.md.

3. One concept per diagram

If you can’t say what the diagram teaches in a single sentence, it’s two diagrams. Examples of one-sentence purposes:

  • “This is where the GitOps handoff happens.”
  • “This is how a deploy moves from request to production.”
  • “This is what an incident escalation looks like.”

If the diagram is trying to do “deploy flow AND rollback flow AND incident response,” split it. Three small clear diagrams always beat one comprehensive one.

4. Prefer top-down (TD) for web pages; left-right (LR) only when direction means something

Default to flowchart TD. Browsers are narrow and tall; LR diagrams get squished or force horizontal scroll. Reach for LR only when the direction itself carries meaning — a pipeline, a timeline, a left-to-right progression. If the diagram could be rotated 90 degrees without losing meaning, it should be TD.

5. Five to seven nodes max per diagram

Past seven nodes, the reader stops scanning and starts working. If you have more than seven, either:

  • Collapse adjacent steps into one node (“Build, test, scan” instead of three separate nodes).
  • Split into two diagrams (overview + detail).
  • Use a subgraph as a single conceptual node (one box on the parent diagram representing a group internally).

Node count is a budget. Spend it deliberately. Groups don’t count toward the budget — five nodes in two groups read as easier than five flat nodes.

6. Subgraph labels should name the boundary, not the contents

Good subgraph titles: What people do, Automation, Procurement phase, Production. These name what kind of thing the group represents. Bad titles: Step 1, Group A, Things the team does. The label should make the divide explicit so the reader understands why the grouping exists.

7. Use color to teach, not to decorate

Color earns its place only when it tells the reader something the labels don’t. Acceptable uses:

  • Marking the people/automation boundary.
  • Highlighting the one node that’s the diagram’s punchline.
  • Distinguishing success path from error path.

Unacceptable uses:

  • One color per actor (decorative).
  • Rainbow gradients (decorative).
  • Color used because the diagram looked plain (decorative).

If color is removed and the diagram still reads correctly, the color was decoration. That’s not always wrong, but it’s never load-bearing.

8. Use shapes for state types, not for variety

Mermaid shapes mean things. Use them consistently:

  • [ ] rectangles = actions and states.
  • ( ) rounded = soft states or “in progress”.
  • { } diamonds = decisions and branches.
  • (( )) circles = start and end points only.

Don’t use diamonds for things that aren’t decisions. Inconsistent shape use makes the diagram harder to scan because the reader has to relearn the vocabulary each time.

Exception — multi-layer system/topology diagrams. A single-boundary teaching flowchart earns this minimal vocabulary; a whole-pipeline or architecture diagram (GitOps flow, CI/CD, infra topology) needs one shape and one muted color per layer or the reader can’t tell a durable store from a control plane from a manual gate. This is a hard rule, not a stylistic option — see gitops-patterns.md for the required shape-and-color palette.

9. Edge labels for how, never for what

Edge labels should say something the connected nodes don’t already say. Good edge labels: “if approved,” “on merge,” “after 5 min,” “reviewer signs off.” Bad edge labels: “then,” “next,” “and” — the arrow already says “then.” Adding the word is noise.

10. Dashed lines for handoffs, asynchrony, or boundaries

Solid lines are direct, synchronous flow. Dashed lines (-.->) are for moments where the flow shifts — a handoff between teams, an asynchronous trigger, a transition between two conceptual zones. Use dashed lines sparingly so they keep their meaning.

11. Labels are noun phrases, not sentences

Node labels should be short, scannable, and noun-phrase-shaped. “Open PR” not “The developer opens a PR.” “Merge to main” not “Merging to main.” The reader’s eye should catch the meaning at a glance, not parse a sentence to find it.

The pairing with Docs That Teach

A grouped diagram is one half of the lesson; the sentence beneath it is the other. Every teaching diagram earns a one-line “what to notice” caption that names the boundary the grouping draws — “notice everything people do happens before the automation starts.” The grouping makes the structure visible; the caption makes the takeaway explicit.