Repository navigation
feat(mermaid): layered flowchart layout, state/class/ER diagrams, better Gantt, mindmaps - #26
Merged
Merged
Conversation
Flowcharts were printed as a list of edges, so a node with several edges appeared once per edge and LR was ignored. They are now parsed fully (shapes, every link kind, labels, chains, & groups, subgraphs, comments, style lines, quoted labels, <br>, entities) and laid out Sugiyama-style on a character grid: cycle breaking, longest-path ranks, dummy nodes, barycenter crossing reduction with subgraph members kept together, isotonic-regression coordinates, orthogonal routing with shared fan-in and fan-out tracks, edge labels as nodes of their own, and arrowheads. Each node is drawn once, with a shape-specific outline; TD/TB/BT/LR/RL are honoured; subgraphs get a titled frame when their members stay together, otherwise their membership is listed under the diagram. Diagrams that do not fit narrow their labels, then LR falls back to top down, then to a compact list; over 200 nodes or 400 edges the list is used directly. Output never exceeds the width. The mermaid module becomes a directory (canvas, engine, graph model, flowchart parser, text helpers, tests) with a fixture corpus under tests/fixtures/mermaid. Snapshots with flowcharts change accordingly.
stateDiagram and stateDiagram-v2 printed as raw source. States, transitions with labels, 'state "…" as id', 'id : description', composite states (as titled frames, with their own [*]), <<choice>>, <<fork>> and <<join>>, direction and notes are parsed into the graph model and drawn by the flowchart engine: [*] is ● as a source and ◉ as a target, choice a ◇, fork/join a bar. Transitions to a composite land on its start state and leave from its end state. Notes are listed under the diagram.
classDiagram printed as raw source. Classes (bodies, 'Name : member' lines, generics as <T>, <<annotations>>, ["labels"]), namespaces (as frames), notes and every relationship form (<|--, *--, o--, -->, --, ..>, ..|>, .., two-way, with labels and "1"/"*" cardinalities) are parsed into the graph model. Each class is a box split into name, attributes and methods; relationship ends carry △ (inheritance, realization), ◆ (composition), ◇ (aggregation) or an arrowhead, dotted for the .. forms, and a legend line names the kinds used.
erDiagram printed as raw source. Entities (with attribute blocks and
["aliases"]) and relationships (||, |o, }o, }| ends, -- and .. lines,
labels) are parsed into the graph model. Each entity is a box with a
row per attribute ('type name PK,FK'); each relationship is a labelled
edge whose label carries the cardinality of the end nearest it (1,
0..1, 0..*, 1..*), dotted when non-identifying.
The Gantt renderer printed task names with bars whose length came from the name, not the schedule. It now parses title, dateFormat (dates with optional times, HH:mm, Unix timestamps), sections, ids, explicit start and end dates, durations (ms s m h d w M y), 'after' and 'until' dependencies and the done/active/crit/milestone tags, and draws a time axis scaled to the width with ticks at round intervals, a section header per section and one bar per task: █ done, ▓ active, ░ planned, ◆ milestone, critical tasks in the warning colour. Task names sit in a left column. Work is linear in the number of tasks (3000-task test). Snapshot: the Product Roadmap chart in diagrams.md.
Diagram types that are not drawn (journey, gitGraph, timeline, quadrantChart, sankey, C4, requirementDiagram, xychart, block, packet, kanban, architecture, …) were printed as bare text under a generic header. They now show their source, hard-wrapped to the width, in a box titled 'mermaid: <type> (not rendered)'. Mindmaps are drawn as an indentation tree with ├─ └─ branches (shapes, icons and classes stripped, deep trees capped at half the width). Sequence diagrams and pie charts keep their output at the usual width; when narrower, pie bars shrink and over-wide lines wrap behind the left border, so no diagram line exceeds the width (ASCII mode included). A 'pie title …' first line now sets the title.
Subgraph membership for edges that name a subgraph was computed per cluster per node (quadratic in thousands of subgraphs); it is now one pass. Diagrams with more than 200 subgraphs are listed rather than laid out, mindmap prefixes stop growing instead of being re-truncated per node, and the list form indexes outgoing edges instead of scanning them per node. The list form is left-aligned and now shows each edge's markers, line style and cardinalities (◁── for inheritance, ┄┄ for dotted, '1 ──buys── *▶').
Merged
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Flowcharts used to print as a list of edges, repeating shared nodes and ignoring direction; state, class and ER diagrams printed as raw source.
&groups and subgraphs parse.Limits
Testing
Exact-output tests, property checks over a 30-diagram corpus (width, each label once, determinism, ASCII-only in ASCII mode), timing-bounded hostile inputs, and an escape-byte test across all diagram types. Two plain snapshots changed deliberately (flowcharts and the Gantt chart). fmt, clippy and the full suite (506 tests) pass locally after merging current main.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UVcvmQrSXd2eyt32g4ko19