Kostenlos · Ohne Anmeldung · Für .mmd-Dateien

Mermaid Zustandsdiagramm Editor

Ein Zustandsdiagramm zeigt, in welchen Zuständen eine Sache sein kann und welche Ereignisse sie zwischen ihnen bewegen. Nimm es, wenn es um einen Lebenszyklus geht — eine Bestellung, ein Abonnement, ein Dokument in Prüfung. Das Erkennungszeichen: Deine Beschriftungen sind Eigenschaften statt Tätigkeiten — offen, versendet, storniert.

Ein Bestell-Lebenszyklus mit endgültiger Stornierung

Die Zustände sind, was eine Bestellung ist; die Beschriftungen an den Pfeilen sind, was mit ihr passiert ist. Beachte, dass Storniert aus drei Zuständen erreichbar ist, aber nirgendwohin führt — genau solche Asymmetrien macht ein Zustandsdiagramm sichtbar und ein Flussdiagramm versteckt sie.

stateDiagram-v2
    [*] --> Eingegangen: Bestellung erfasst
    Eingegangen --> Bezahlt: Zahlung eingegangen
    Eingegangen --> Storniert: Kunde storniert
    Bezahlt --> Kommissioniert: Lager packt
    Bezahlt --> Erstattet: Zahlung zurückgebucht
    Kommissioniert --> Versendet: Übergabe an Versanddienstleister
    Kommissioniert --> Storniert: Bestand fehlt
    Versendet --> Zugestellt: Empfang bestätigt
    Versendet --> Verschollen: 14 Tage ohne Scan
    Zugestellt --> [*]
    Erstattet --> [*]
    Storniert --> [*]
    Verschollen --> Erstattet: Reklamation anerkannt
Im Editor öffnen
Werbung

Durchgearbeitete Beispiele

1. Die kleinste Zustandsmaschine

`[*]` ist sowohl Start- als auch Endpseudozustand — was davon gemeint ist, entscheidet die Seite des Pfeils, auf der es steht.

stateDiagram-v2
    [*] --> Entwurf
    Entwurf --> Veroeffentlicht: freigeben
    Veroeffentlicht --> [*]
Im Editor öffnen

2. Zustände mit Leerzeichen benennen

Zustands-IDs dürfen keine Leerzeichen enthalten, aber `state "Beschriftung" as id` liefert einen lesbaren Text bei sicherer ID. Das ist das Gegenstück zur zitierten Beschriftung im Flussdiagramm.

stateDiagram-v2
    state "Wartet auf Prüfung" as pruefung
    state "Änderungen erbeten" as aenderung
    [*] --> pruefung
    pruefung --> aenderung: Prüfer widerspricht
    aenderung --> pruefung: Autor bessert nach
    pruefung --> [*]: freigegeben
Im Editor öffnen

3. Zusammengesetzte Zustände

Ein Zustand kann eine eigene Zustandsmaschine enthalten. Nutze das, wenn eine Phase innere Schritte hat, die sonst die oberste Ebene zumüllen — hier alles, was innerhalb der Verarbeitung passiert.

stateDiagram-v2
    [*] --> Eingereiht
    Eingereiht --> Verarbeitung: Worker übernimmt

    state Verarbeitung {
        [*] --> Pruefen
        Pruefen --> Umwandeln: Schema in Ordnung
        Umwandeln --> Schreiben: Zeilen zugeordnet
        Schreiben --> [*]
    }

    Verarbeitung --> Erfolgreich: keine Fehler
    Verarbeitung --> Fehlgeschlagen: Ausnahme geworfen
    Fehlgeschlagen --> Eingereiht: erneut versuchen
    Erfolgreich --> [*]
Im Editor öffnen

4. Auswahl-Pseudozustände

Ein `<<choice>>` ist eine Verzweigung, die von einer Bedingung abhängt statt von einem Ereignis. So bleibt die Entscheidung sichtbar, ohne so zu tun, als sei sie ein Zustand, in dem das Objekt verweilt.

stateDiagram-v2
    state pruefung <<choice>>
    [*] --> Eingereicht
    Eingereicht --> pruefung: Risikobewertung
    pruefung --> Freigegeben: Punktwert < 40
    pruefung --> Handpruefung: Punktwert >= 40
    Handpruefung --> Freigegeben: Sachbearbeiter stimmt zu
    Handpruefung --> Abgelehnt: Sachbearbeiter lehnt ab
    Freigegeben --> [*]
    Abgelehnt --> [*]
Im Editor öffnen

5. Nebenläufige Bereiche

Zwei Bindestriche auf einer eigenen Zeile teilen einen zusammengesetzten Zustand in Bereiche, die gleichzeitig aktiv sind. Das ist das Einzige, was ein Zustandsdiagramm kann und ein Flussdiagramm wirklich nicht.

stateDiagram-v2
    [*] --> Registrierung

    state Registrierung {
        [*] --> MailOffen
        MailOffen --> MailBestaetigt: Link angeklickt
        --
        [*] --> ProfilLeer
        ProfilLeer --> ProfilVollstaendig: Formular abgeschickt
    }

    Registrierung --> Aktiv: beides erledigt
    Aktiv --> [*]
Im Editor öffnen

Syntaxreferenz für Zustandsdiagramme

Nimm `stateDiagram-v2` statt `stateDiagram`. Beides rendert, aber v2 ist die aktiv weiterentwickelte Layout-Engine und kommt mit zusammengesetzten und nebenläufigen Zuständen deutlich besser zurecht.

SyntaxBedeutung
stateDiagram-v2Öffnet das Diagramm. `stateDiagram` funktioniert weiterhin, ist aber das ältere Layout.
[*] --> AStartzustand — der Einstiegspunkt.
A --> [*]Endzustand.
A --> BÜbergang ohne benanntes Auslöser-Ereignis.
A --> B: EreignisÜbergang mit dem auslösenden Ereignis beschriftet.
state "Beschriftung" as idLesbarer Text bei einer ID ohne Leerzeichen.
state A { ... }Zusammengesetzter Zustand mit eigener Maschine.
--Teilt einen zusammengesetzten Zustand in nebenläufige Bereiche.
state x <<choice>>Verzweigung anhand einer Bedingung.
state f <<fork>> / <<join>>Aufteilen in und Zusammenführen aus parallelen Übergängen.
note right of A: TextNotiz anhängen. Auch `note left of`.
direction LRDie Maschine von links nach rechts statt von oben nach unten anordnen.
Werbung

Sechs Fehler in Zustandsdiagrammen

Nachgestellt mit Mermaid 11.12.2. Die ersten vier verhindern, dass das Diagramm gezeichnet wird. Die letzten beiden sind schlimmer: Sie rendern anstandslos und liefern ein Diagramm, das etwas anderes bedeutet, als du geschrieben hast.

Was du siehst

Parse error, endet mit: got 'INVALID'

Warum

Ein Bindestrich in einer Zustands-ID. Namen in Kebab-Schreibweise liegen nahe — in-pruefung, vor-freigabe —, aber der Bindestrich wird als Anfang eines Übergangspfeils gelesen.

Lösung

Für die ID ein Wort oder Unterstriche verwenden und den lesbaren Text in eine zitierte Beschriftung setzen.

Fehlerhaft
stateDiagram-v2
    [*] --> in-pruefung
    in-pruefung --> Fertig
Korrigiert
stateDiagram-v2
    state "In Prüfung" as pruefung
    [*] --> pruefung
    pruefung --> Fertig

Was du siehst

Parse error innerhalb eines zusammengesetzten Zustands

Warum

Ein mit `{` geöffneter Zustand, der nie geschlossen wurde. Die schließende Klammer gehört auf eine eigene Zeile.

Lösung

Den Block schließen.

Fehlerhaft
stateDiagram-v2
    [*] --> Aussen
    state Aussen {
        [*] --> Innen
Korrigiert
stateDiagram-v2
    [*] --> Aussen
    state Aussen {
        [*] --> Innen
    }

Was du siehst

Lexical error on line N. Unrecognized text.

Warum

Der Trenner für nebenläufige Bereiche mit der falschen Zahl an Bindestrichen. Es sind genau zwei, auf einer eigenen Zeile, innerhalb eines zusammengesetzten Zustands. Drei Bindestriche sind ein völlig anderes Token.

Lösung

Genau `--` verwenden.

Fehlerhaft
stateDiagram-v2
    state Beides {
        [*] --> A
        ---
        [*] --> B
    }
Korrigiert
stateDiagram-v2
    state Beides {
        [*] --> A
        --
        [*] --> B
    }

Was du siehst

Parse error on line 1, endet mit: got 'ID'

Warum

Eine Versionsangabe, die es nicht gibt. Es existieren `stateDiagram` und `stateDiagram-v2`, sonst nichts — `-v3` scheitert schon in der ersten Zeile.

Lösung

`stateDiagram-v2` verwenden.

Fehlerhaft
stateDiagram-v3
    [*] --> Entwurf
Korrigiert
stateDiagram-v2
    [*] --> Entwurf

Was du siehst

Es rendert, aber aus einem Zustand sind still mehrere Kästchen geworden

Warum

Ein Leerzeichen in einer Zustands-ID. Mermaid weist das nicht zurück und liest den Rest auch nicht als Beschreibung — es erzeugt für jedes Wort ein eigenes Kästchen. Gemessen an den ausgegebenen state-IDs: Aus `[*] --> Wartet auf Pruefung` werden drei Zustände, `Wartet`, `auf` und `Pruefung`, von denen nur der erste am Pfeil hängt; die übrigen stehen unverbunden daneben. Das Diagramm wird dadurch still breiter. Die Beschreibung gibt es wirklich, sie braucht aber einen Doppelpunkt — `pruefung: wartet auf einen Prüfer` — und genau damit wird dieser Fehler verwechselt.

Lösung

Den Zustand mit `state "Beschriftung" as id` deklarieren und immer über die ID ansprechen.

Fehlerhaft
stateDiagram-v2
    [*] --> Wartet auf Pruefung
    Wartet auf Pruefung --> Fertig
Korrigiert
stateDiagram-v2
    state "Wartet auf Prüfung" as pruefung
    [*] --> pruefung
    pruefung --> Fertig

Was du siehst

Es rendert, aber der Auswahlknoten wird als gewöhnlicher Zustand gezeichnet

Warum

Die `<<choice>>`-Deklaration kam nach den Übergängen, die sie benutzen. Mermaid legt den Zustand bei der ersten Erwähnung an, und ein späterer Stereotyp ändert nichts mehr an dem, was bereits existiert.

Lösung

Pseudozustände vor den Übergängen deklarieren, die sie verwenden.

Fehlerhaft
stateDiagram-v2
    [*] --> pruefung
    pruefung --> Freigegeben
    pruefung --> Abgelehnt
    state pruefung <<choice>>
Korrigiert
stateDiagram-v2
    state pruefung <<choice>>
    [*] --> pruefung
    pruefung --> Freigegeben
    pruefung --> Abgelehnt

Hinweise zum Rendern

Gemessen an Mermaid 11.12.2, so wie diese Seite es einsetzt.

Sowohl stateDiagram als auch stateDiagram-v2 rendern — und das ist eine Falle

Ein verbreiteter Ratschlag lautet, man müsse `stateDiagram-v2` verwenden, sonst werde nichts gezeichnet. In 11.12.2 stimmt das nicht: Beide Schlüsselwörter rendern fehlerfrei. Der Unterschied liegt in der Layout-Qualität, besonders bei zusammengesetzten und nebenläufigen Zuständen, und es gibt keine Warnung, wenn du die alte Variante benutzt. Wirkt ein zusammengesetzter Zustand gedrängt oder laufen die Pfeile seltsam, prüfe zuerst das Schlüsselwort, bevor du das Diagramm umbaust.

Die Höhe wächst um rund 108 px pro Zustand

Drei Zustände ergeben eine viewBox von etwa 52×462, vierzig Zustände 60×4680. Wie bei Flussdiagrammen bewegt sich die Breite kaum — Zustandsmaschinen wachsen nach unten. `direction LR` im Diagramm ist der übliche Ausweg, wenn ein Lebenszyklus lang, aber flach ist.

Zusammengesetzte Zustände werden eigenständig angeordnet

Die innere Maschine eines zusammengesetzten Zustands wird für sich bemessen und dann platziert. Deshalb kann ein einzelner großer Block das ganze Diagramm viel breiter machen, als die Zahl der Zustände vermuten lässt. Dominiert ein Kasten, liest es sich meist besser, seinen Inhalt auf die oberste Ebene zu holen und auf ein zweites Diagramm zu verweisen, statt gegen das Layout zu kämpfen.

Beschriftungen sind HTML, deshalb rendert der PNG-Export neu

Wie bei Fluss-, Klassen- und ER-Diagrammen stecken die Beschriftungen in einem SVG-`<foreignObject>`. Browser weigern sich, so etwas auf ein Canvas zu zeichnen, deshalb rendert der PNG-Export auf dieser Seite das Diagramm zuerst mit reinen SVG-Textbeschriftungen neu. Das PNG ist korrekt und in voller Größe; die Typografie weicht minimal vom Bildschirm ab.

Das Theme ändert Farben, niemals das Layout

Helles und dunkles Theme ergeben für dieselbe Quelle eine identische viewBox. Eine Zustandsmaschine kann beim Themewechsel also nicht umbrechen.

Wann etwas anderes besser passt

Sind deine Beschriftungen Tätigkeiten — prüfen, senden, wiederholen —, beschreibst du einen Prozess und keinen Lebenszyklus; dann ist ein Flussdiagramm die ehrliche Wahl. Das deutlichste Zeichen: Du kannst die Frage nicht beantworten, was denn eigentlich in diesem Zustand ist.

Haben mehrere Komponenten je einen eigenen Lebenszyklus und ist das Zusammenspiel das Interessante, schlägt ein Zustandsdiagramm pro Komponente plus ein Sequenzdiagramm für die Interaktion jede riesige Einzelmaschine.

Und wenn jeder Zustand mit jedem anderen verbunden ist, wird das Diagramm ein Knäuel, egal wie man es zeichnet. Das heißt meist, dass die Zustände gar keine Zustände sind, sondern frei kombinierbare Merkmale — dann sagt eine Tabelle der gültigen Kombinationen weit mehr als ein Bild.

Andere Diagrammtypen

Geschrieben von Dominik Malsch · Zuletzt aktualisiert:

Editor öffnen →