learn-mermaid-with-phoebe / Deep dive 6.2 of 3
Learn Mermaid with Phoebe · Deep dive 6.2 of 3

Boxes with opinions: block, packet, treemap, and friends

Four niche diagram types that solve very specific pains: a grid you control by hand, bytes laid out like an RFC, storage drawn to scale, and requirements that trace to the code that satisfies them. Most are beta - delightful anyway.

🟠 Self-paced Data & AI teams ~30 min self-paced
Block: manual grids Packet: bytes Treemap: proportions Requirements: traceability
Part 0

Why this deep dive exists

The main six sessions covered the daily drivers. This deep dive is the specialty shelf: four types you'll reach for maybe once a month - and when you do, nothing else will do the job. Honest framing up front: three of the four carry a -beta suffix, which means the syntax can still shift between versions. Use them for docs you control, keep the examples modest, and enjoy them - they are some of the most charming corners of mermaid. All four get a Nova workout below.

Live - every pink block renders real mermaid Self-study notes ★ Try it now Niche on purpose - that's the point
★ What you walk out with A hand-placed block-beta poster of Nova, the byte layout of Nova's event envelope in packet-beta, warehouse storage drawn to scale in treemap-beta, and Nova's data quality requirements formally traced to the pipeline components that satisfy them in requirementDiagram. Plus a clear sense of when each one beats a flowchart - and when it doesn't.
Part 1 · covers "Block diagram" (beta)

block-beta: when auto-layout fights you 8 min

Flowcharts let dagre decide where boxes go - usually a gift, occasionally a wrestling match. Block diagrams flip the deal: you declare a grid of columns and place every block yourself. Perfect for the tidy "poster" view of a platform where the POSITION is the message: sources on the left, platform in the middle, consumers on the right.

Auto layout (flowchart) you declare edges, dagre picks positions events crm ingest dw Manual layout (block-beta) you declare a grid, blocks land where you say events crm platform bi ml Trade-off: block-beta obeys you completely - which means alignment mistakes are also yours completely.
🔍 Click to zoom - auto layout optimizes, manual layout obeys. block-beta is the "obeys" column.
Self-studyThe grid: columns, spans, space3 min▶

Three ideas run the whole show. columns N sets the grid width; blocks fill it left to right, wrapping to new rows. A suffix like :2 makes a block span columns. And space (or space:2) is an invisible block - your alignment tool.

block-beta
  columns 3
  a["Sources"] b["Platform"] c["Consumers"]
  d["Batch lane"]:2 e["Stream lane"]
  space f["You choose the grid"] space
  • Row wrapping is automatic: with columns 3, the 4th block starts row two. Count as you write.
  • Spans eat columns: d["Batch lane"]:2 takes two cells, so only one cell remains in that row.
  • Shapes carry over from flowcharts: x[("db")] cylinder, x(["pill"]), x{"decision"} all work here.
  • Nesting: block:ID ... end makes a composite block containing its own mini-grid - a group border without a subgraph.
Self-studyNova as a tidy 3-column poster3 min▶

The classic use: a platform poster where column one is sources, column two is the platform, column three is consumers. Edges still exist (-->, with labels as a-- "text" -->b), but layout no longer reflows when you add one - the grid holds.

block-beta
  columns 3
  hdr["Nova data platform"]:3
  ev["App events"] ing["Ingestion"] bi["Dashboards"]
  crm["CRM export"] qa["Quality checks"] ml["ML features"]
  space dw[("Warehouse")] space
  ev --> ing
  crm --> ing
  ing --> qa
  qa-- "pass" -->dw
  dw --> bi
  dw --> ml
  style hdr fill:#FFD9E6,stroke:#D6246E
★ Try it nowFlip this block to Code, open it on mermaid.live, and change columns 3 to columns 2. Watch every block re-wrap - then put it back. That one number is the entire layout engine.
Real world

A platform team kept redrawing their "what we own" slide every quarter because the flowchart version reshuffled itself whenever a box was added. Rebuilt as block-beta, the grid never moves: new services drop into their column, the poster stays recognizable, and executives stop asking "why does the diagram look different this time?"

Self-studyGotchas1 min read▶
  • Beta: current docs have started writing plain block; both block and block-beta parse in v11. This page uses block-beta, which works across all v11 releases.
  • Arrows don't route politely. Edges draw fairly straight lines between cells - if they cross a block, rearrange the grid, not the edge.
  • Never name a block end - it closes composite blocks. Same reserved-word trap as flowcharts.
  • Miscounted rows are the #1 bug: a forgotten space shifts everything after it one cell left. When the poster looks drunk, count cells per row first.
Part 2 · covers "Packet diagram" (beta)

packet-beta: bytes, drawn like an RFC 6 min

Packet diagrams draw bit-level field layouts - the picture you've seen in every TCP textbook. Niche? Extremely. But if you ever document a binary event envelope, a fixed-width file format, or a wire protocol, this type produces in six lines what would take an hour in a drawing tool.

Self-studyNova's event envelope, bit by bit3 min▶

Each line is start-end: "Field name" in bit positions; rows wrap every 32 bits automatically. Since v11.7 you can also write +8: "Field" and let mermaid count on from wherever the previous field ended - much kinder when a design is still moving.

Bit ranges become a proportioned field row SOURCE RENDERS AS packet-beta 0-7: "Version" 8-15: "Event type" 16-31: "Tenant ID" 0 8 16 32 Version Event type Tenant ID 0-7 8-15 16-31 Ranges are inclusive: 0-7 is eight bits - an off-by-one here lies about the wire format.
🔍 Click to zoom - six characters of syntax draw an RFC-style bit diagram
---
title: "Nova event envelope (header)"
---
packet-beta
0-7: "Version"
8-15: "Event type"
16-31: "Tenant ID"
32-63: "Event timestamp"
64-95: "User ID hash"
96-111: "Payload length"
112-127: "Checksum"
  • Ranges are inclusive: 0-7 is eight bits. Off-by-one here means your doc lies about the wire format.
  • Auto-counting: +16: "Tenant ID" starts where the previous field stopped; you can mix +n and explicit ranges freely.
  • Single bits: just 106: "ACK" - one number, no range. Great for flag bits.
When a data person reaches for it Documenting Kafka message envelopes, Avro/Protobuf-adjacent binary headers, fixed-width mainframe exports, or IoT payloads. Any time a colleague asks "which bytes hold the tenant ID?", this diagram IS the answer.
Self-studyGotchas1 min read▶
  • Beta: introduced v11.0 as packet-beta; current docs write plain packet. Both parse in v11 - this page sticks with the widely compatible form.
  • Gaps are errors: fields must be contiguous. Skip bits 40-47 and the parser complains - pad with a "Reserved" field like real RFCs do.
  • It only does layout, not meaning: no types, no endianness, no units. Put those in a table next to the diagram.
  • Long labels squeeze: a 4-bit field with a 30-character name gets unreadable. Abbreviate, expand in prose.
Part 3 · covers "Treemap" (beta)

treemap-beta: proportions you can feel 6 min

A treemap tiles nested rectangles sized by value - hierarchy AND magnitude in one picture. For a data person this is the "where does it all go?" diagram: storage by domain, cost by team, rows by table. The syntax is the simplest on this page: indentation is the hierarchy.

Self-studyNova's warehouse storage by domain3 min▶

Quoted names are nodes; indentation nests them; "Leaf": value sets the size. That's the whole grammar. Tag a node with :::class and style it with a classDef - handy for pointing at the elephant.

Indentation and value become tile width SOURCE RENDERS AS treemap-beta "Events domain" "Page views": 420 "Clicks": 310 "Sessions": 120 Page views 420 Clicks 310 Page views 420 Clicks 310 Sessions 120 Parents don't take values - they sum their children; two levels read instantly, three is the ceiling.
🔍 Click to zoom - tile width is the number, no legend required to feel it
treemap-beta
"Nova warehouse (GB)"
    "Events domain"
        "Page views": 420:::hot
        "Clicks": 310
        "Sessions": 120
    "CRM domain"
        "Accounts": 80
        "Contacts": 60
    "ML features"
        "Feature store": 150
        "Training sets": 90

classDef hot fill:#D6246E,color:#FFEFF5,stroke:#8E1146;
  • Parents don't take values - they sum their children. Give a parent its own number and the picture stops being trustworthy.
  • valueFormat (frontmatter config) formats numbers with d3 specifiers: '$0,0' for cost treemaps, '.1%' for shares.
  • Depth discipline: two levels read instantly, three is the ceiling. Deeper than that, link out to a second treemap.
Real world

The fastest storage-cost conversation ever: a treemap of warehouse GB by domain in the platform README. Finance saw in one glance that one event table dwarfed everything else combined - a conversation that three months of spreadsheet tabs had failed to start.

Self-studyGotchas1 min read▶
  • Genuinely new: the docs warn the syntax "may evolve in future versions". Fine for living docs; risky for anything you'll print and frame.
  • Indentation is load-bearing - a leaf indented one level too far silently changes the hierarchy. Diff carefully.
  • Tiny values vanish: a 2 GB slice next to a 420 GB slice renders as a sliver with no readable label. Group small stuff into "Other".
  • No negatives - treemaps size by area, and negative area isn't a thing.
  • Cousin worth knowing: a venn diagram type also exists in recent releases - even newer than treemap, so we mention it and move on. Watch the release notes.
Part 4 · covers "Requirement diagram"

requirementDiagram: promises, traced 8 min

The grown-up of this page (no beta suffix): a SysML-style diagram that connects requirements to the things that satisfy and verify them. For a data team, read "requirement" as data quality SLA and "element" as pipeline component - suddenly your DQ policy has a picture, with risk levels and verification methods built into the grammar.

Self-studyNova's data quality requirements, formally traced4 min▶

Two building blocks. A requirement has an id, text, a risk (low, medium, high) and a verifymethod (analysis, inspection, test, demonstration). An element is anything real - a DAG, a test suite, a doc. Relationships connect them: {source} - <type> -> {destination} where type is one of contains, copies, derives, satisfies, verifies, refines, traces.

requirementDiagram

requirement freshness {
  id: "DQ-1"
  text: "Warehouse tables refresh within 60 minutes"
  risk: high
  verifymethod: test
}

functionalRequirement no_null_ids {
  id: "DQ-2"
  text: "Customer ID is never null after ingestion"
  risk: medium
  verifymethod: inspection
}

element quality_checks {
  type: "dbt test suite"
  docref: "nova/dbt/tests"
}

element ingestion_job {
  type: "Airflow DAG"
  docref: "nova/dags/ingest"
}

quality_checks - verifies -> freshness
ingestion_job - satisfies -> no_null_ids
freshness - traces -> no_null_ids
  • Six requirement flavors: requirement, functionalRequirement, interfaceRequirement, performanceRequirement, physicalRequirement, designConstraint. For DQ work the first two carry most of the load.
  • satisfies vs verifies is the useful distinction: the ingestion job SATISFIES the rule (it does the work); the test suite VERIFIES it (it proves the work happened).
  • Quote free text - names, text and docrefs can go unquoted, but the parser fails if it smells a keyword. Quotes end the guessing.
★ Try it nowAdd a third requirement to the block above on mermaid.live: "PII columns are masked in marts", risk high, verifymethod inspection - and connect your masking job to it with satisfies. Congratulations, your DQ policy is now a diagram.
Self-studyGotchas1 min read▶
  • Layout is take-it-or-leave-it: big requirement webs get tangled. Split by domain (one diagram per data product) before you hit ten nodes.
  • The enums are closed lists - risk: critical is a parse error. Map your own severity scale onto low/medium/high.
  • The arrow is fussy: it's - satisfies -> with single hyphens, not the flowchart's -->. Muscle memory will betray you exactly once per session.
  • It documents intent, not status - nothing turns red when a test fails. Pair it with your observability stack; this is the map, not the alarm.
Homework

Try it yourself - this week ◐ 30-40 min total

Source material

Official docs covered

This deep dive works through these sections of the official docs at mermaid.js.org (mermaid 11.x). Beta types are marked - expect their syntax to keep evolving.

✓Block diagram (beta)Part 1 - columns, spans, space, nesting, edges, style
✓Packet diagram (beta)Part 2 - bit ranges, +n auto-count, single-bit flags
✓Treemap (beta)Part 3 - indentation hierarchy, values, classDef, valueFormat
✓Requirement diagramPart 4 - requirements, elements, risk/verifymethod, relationships
◐Venn diagrammentioned only - too new to teach responsibly yet
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · In a block-beta grid with columns 3, how do you make one block span two columns?

The :n suffix sets the span - and space:n does the same for invisible spacer blocks. Count your cells per row after adding one.

2 · In packet-beta, which line adds a 16-bit field that starts wherever the previous field ended?

+n auto-continues from the previous field (v11.7+). Option A would declare a single flag bit at position 16 - a very different claim about your bytes.

3 · Which line correctly connects Nova's dbt suite to a requirement in requirementDiagram?

Single hyphens around the relationship type: source - type -> destination. The double-dash flowchart arrow is the classic mistake here.

Deep dive 6.2 cheat sheet · pin this

block-beta skeletoncolumns N, then blocks fill rows left to right. Flowchart shapes work: [(db)], ([pill]), {decision}.
Spans + spacea["label"]:2 spans two columns · space / space:2 are invisible blocks - your alignment tools.
Nesting + edgesblock:ID ... end groups a mini-grid · edges: a --> b, labeled: a-- "text" -->b · never name a block "end".
packet-beta rows0-15: "Field" explicit bits · +8: "Field" auto-continues (v11.7+) · single bit: 106: "ACK" · no gaps allowed.
treemap-betaIndentation = hierarchy · "Leaf": value sizes it · parents sum children · :::class + classDef to highlight.
requirement blockrequirement name { id: text: risk: low|medium|high verifymethod: analysis|inspection|test|demonstration }.
Relationshipssrc - satisfies -> dest · types: contains, copies, derives, satisfies, verifies, refines, traces · single hyphens.
Beta radarblock, packet, treemap carry -beta (plain keywords also parse in v11) · requirementDiagram is stable · venn: newer still, wait.