# How Diagram Design Determines the Most Appropriate Visual Type for a Diagram

> Diagram Design employs a two-step semantic-pattern routing and visual-type lookup process to choose the best diagram layout from 27 validated grammars. Learn how to select appropriate visuals.

- Repository: [Cathryn Lavery/diagram-design](https://github.com/cathrynlavery/diagram-design)
- Tags: best-practices
- Published: 2026-08-16

---

**Diagram Design uses a deterministic two-step process: semantic-pattern routing for behavior-driven diagrams, followed by a visual-type guide lookup, to select from 27 validated layout grammars.**

The **diagram-design** repository by Cathryn Lavery implements a reproducible, editorial-quality system for choosing diagram layouts. Rather than relying on intuition, it encodes selection logic in structured markdown tables and validation scripts. This article explains exactly how the system determines the most appropriate visual type for any given diagram request.

## Semantic-Pattern Routing: Behavior-Driven Selection

When a diagram's **meaning** depends on behavior, state, enforcement, or risk, the engine first consults the semantic-patterns reference. This routing table maps behavioral scenarios directly to their nearest visual type.

The mapping lives in [[`semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/semantic-patterns.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/semantic-patterns.md) (lines 11–16):

```markdown
| The reader must understand… | Semantic pattern | Nearest visual type |
|---|---|---|
| … | **Fan‑in queue / bottleneck** | Data flow |
| … | **Stage framework with semantic slots** | Process |
| … | **Secure paved road** | Architecture |

```

Each pattern declares:
- **Selection triggers** — keywords that activate the pattern
- **Required primitives** — visual elements that must appear
- **Nearest visual type** — the specific layout grammar from the 27-type canon

This ensures that behaviorally complex scenarios (queuing, security boundaries, state transitions) receive layout types optimized for expressing those dynamics.

## Visual-Type Guide: The Master Catalog of 27 Layouts

If no semantic pattern applies — or after pattern routing completes — the engine consults the **visual-type guide** in [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md). This table contains exactly 27 rows, each describing one canonical visual type.

From [[`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md)](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) (lines 81–106):

```markdown
| If you're showing… | Use | Reference |
|---|---|---|
| Components + connections in a system | **Architecture** | [type‑architecture.md](references/type-architecture.md) |
| Decision logic with branches | **Flowchart** | [type‑flowchart.md](references/type-flowchart.md) |
| Time‑ordered messages between actors | **Sequence** | [type‑sequence.md](references/type-sequence.md) |

```

The guide serves two purposes:
- It provides a **fallback selection path** when behavior is not load-bearing
- It links each visual type to its **concrete implementation** in `type-*.md` reference files

## The Decision Algorithm: Code Structure

The selection logic can be expressed as a deterministic Python function:

```python
def select_visual_type(request):
    # 1️⃣ Load semantic-pattern routing if behavior matters

    if request.behavior_is_load_bearing:
        pattern = match_semantic_pattern(request)          # reads semantic-patterns.md

        visual_type = pattern.nearest_visual_type           # e.g. "Data flow"

    else:
        visual_type = None

    # 2️⃣ If a pattern gave a type, honor it; otherwise pick directly

    if not visual_type:
        visual_type = lookup_visual_type(request.topic)    # reads SKILL.md visual-type table

    # 3️⃣ Load the concrete type reference before rendering

    type_ref = load_type_reference(visual_type)           # e.g. type-data-flow.md

    return type_ref

```

The `match_semantic_pattern` function examines request triggers (`"queue depth"`, `"trust boundary"`, etc.) against the routing table. If no match occurs, `lookup_visual_type` performs a direct topic-based lookup in the visual-type guide.

## Practical Usage Examples

### Python API Invocation

```python

# Example: Request to illustrate a queue bottleneck

request = {
    "title": "API request queue",
    "behavior_is_load_bearing": True,
    "triggers": "Fan‑in, queue depth, capacity",
    "topic": "data‑flow"
}

# Step 1 – route through semantic pattern

pattern = match_semantic_pattern(request)        # → "Fan‑in queue / bottleneck"

print(pattern["Nearest visual type"])            # → "Data flow"

# Step 2 – load the type reference

type_md = load_type_reference("Data flow")       # reads type-data-flow.md

print(type_md[:200])                             # shows the first 200 chars

```

### CLI Interface

The skill also exposes a command-line entrypoint:

```bash
diagram-design \
    --title "API request queue" \
    --behavior "load‑bearing" \
    --trigger "fan‑in queue" \
    --size doc-inline

# Output: "Selected visual type: Data flow"

```

## Automated Enforcement Guarantees

The repository contains [[`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py)](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) to prevent configuration drift. Lines 191–205 implement three critical checks:

- [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) must contain the semantic-pattern router **before** the visual-type guide
- The visual-type guide must contain **exactly 27 rows** — no more, no less
- Every pattern entry must include mandatory fields: `Selection triggers`, `Required primitives`, and `Nearest visual type`

These verification scripts run at build time, ensuring that the selection logic remains deterministic and complete.

## Key Files in the Selection Pipeline

| Role | File | Purpose |
|---|---|---|
| Behavior-to-layout routing | [`skills/diagram-design/references/semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/semantic-patterns.md) | Defines 7 semantic patterns with visual-type mappings |
| Master type catalog | [`skills/diagram-design/SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/SKILL.md) | Contains the validated 27-type visual-type guide |
| Type-specific grammars | `references/type-*.md` | Implements concrete SVG layout specifications |
| Build-time verification | [`scripts/verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/scripts/verify-semantic-motion.py) | Enforces structural integrity of routing tables |

## Summary

- **Semantic-pattern routing** takes precedence when behavior drives meaning, mapping scenarios like "fan-in queue" directly to "Data flow"
- **Visual-type guide** provides a fallback path through 27 canonical layout types, each with dedicated reference documentation
- **Automated verification** guarantees the routing tables remain synchronized and complete via [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py)
- **Deterministic output** ensures reproducible, editorial-quality diagram type selection across all invocations

## Frequently Asked Questions

### What triggers a diagram to use semantic-pattern routing instead of the visual-type guide?

The `behavior_is_load_bearing` flag in the request. When `True`, the engine routes through [`semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/semantic-patterns.md) to find patterns matching triggers like "queue depth" or "trust boundary". When `False` or unspecified, it skips directly to the visual-type guide lookup in [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md).

### Why exactly 27 visual types?

The 27-type canon represents a deliberately constrained design space — extensive enough to cover most technical communication needs, bounded enough to maintain consistency. The [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py) script enforces this count at build time, preventing uncontrolled expansion that would fragment the visual language.

### How do I add a new semantic pattern to the routing table?

Edit [`skills/diagram-design/references/semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/skills/diagram-design/references/semantic-patterns.md) to add a row with `Selection triggers`, `Required primitives`, and `Nearest visual type`. Run [`verify-semantic-motion.py`](https://github.com/cathrynlavery/diagram-design/blob/main/verify-semantic-motion.py) to validate the entry. The pattern must map to one of the existing 27 visual types — introducing new layout grammars requires updating the master type catalog in [`SKILL.md`](https://github.com/cathrynlavery/diagram-design/blob/main/SKILL.md) and all validation scripts.

### Can I override the automatically selected visual type?

Not through the public API. The system is intentionally deterministic to preserve editorial consistency. If the routing logic produces incorrect results for a specific use case, the recommended path is to refine the `triggers` field in your request or extend [`semantic-patterns.md`](https://github.com/cathrynlavery/diagram-design/blob/main/semantic-patterns.md) to cover the missing scenario.