Za darmo · Bez rejestracji · Obsługuje pliki .mmd

Edytor diagramów stanów Mermaid

Diagram stanów pokazuje stany, w jakich może znaleźć się jedna rzecz, oraz zdarzenia, które przenoszą ją między nimi. Nadaje się wtedy, gdy tematem jest cykl życia — zamówienie, subskrypcja, dokument w obiegu. Nieomylny znak: twoje etykiety są przymiotnikami, a nie czasownikami — oczekujące, wysłane, anulowane.

Cykl życia zamówienia z anulowaniem jako stanem końcowym

Stany to to, czym zamówienie jest; etykiety strzałek to to, co się z nim stało. Zwróć uwagę, że do Anulowane da się dojść z trzech stanów, ale z niego nie prowadzi już nic. Właśnie taką asymetrię diagram stanów pokazuje od razu, a schemat blokowy ukrywa.

stateDiagram-v2
    state "Oczekuje na płatność" as oczekuje

    [*] --> oczekuje: zamówienie złożone
    oczekuje --> Opłacone: płatność zaksięgowana
    oczekuje --> Anulowane: klient rezygnuje
    Opłacone --> Skompletowane: magazyn kompletuje
    Opłacone --> Zwrócone: płatność cofnięta
    Skompletowane --> Wysłane: kurier odbiera
    Skompletowane --> Anulowane: brak towaru
    Wysłane --> Dostarczone: doręczenie potwierdzone
    Wysłane --> Zaginione: brak skanów przez 14 dni
    Dostarczone --> [*]
    Zwrócone --> [*]
    Anulowane --> [*]
    Zaginione --> Zwrócone: reklamacja uznana
Otwórz to w edytorze
Reklama

Omówione przykłady

1. Najmniejszy automat stanów

`[*]` jest zarazem stanem początkowym i końcowym: to, który z nich oznacza, zależy od tego, po której stronie strzałki stoi.

stateDiagram-v2
    [*] --> Szkic
    Szkic --> Opublikowane: opublikuj
    Opublikowane --> [*]
Otwórz w edytorze

2. Nazywanie stanów zawierających spacje

Identyfikator stanu nie może zawierać spacji, ale `state "Etykieta" as id` daje czytelną etykietę przy bezpiecznym identyfikatorze. Po polsku jest to potrzebne niemal zawsze, bo nasze naturalne nazwy stanów są wielowyrazowe: «oczekuje na płatność», «w trakcie weryfikacji».

stateDiagram-v2
    state "Oczekuje na recenzję" as recenzja
    state "Zgłoszono poprawki" as poprawki
    [*] --> recenzja
    recenzja --> poprawki: recenzent zgłasza uwagi
    poprawki --> recenzja: autor poprawia
    recenzja --> [*]: zaakceptowano
Otwórz w edytorze

3. Stany złożone

Stan może zawierać własny automat. Używaj tego, gdy etap ma sensowne kroki wewnętrzne, które na najwyższym poziomie tylko zaśmiecałyby obraz: tutaj wszystko, co dzieje się wewnątrz Przetwarzania.

stateDiagram-v2
    [*] --> Kolejka
    Kolejka --> Przetwarzanie: worker podejmuje

    state Przetwarzanie {
        [*] --> Walidacja
        Walidacja --> Transformacja: schemat zgodny
        Transformacja --> Zapis: wiersze zmapowane
        Zapis --> [*]
    }

    Przetwarzanie --> Sukces: bez błędów
    Przetwarzanie --> Porażka: wyjątek
    Porażka --> Kolejka: ponowienie
    Sukces --> [*]
Otwórz w edytorze

4. Pseudostany wyboru

`<<choice>>` to rozgałęzienie zależne od warunku, a nie od zdarzenia. Zostawia decyzję na widoku, nie udając, że to stan, w którym obiekt przebywa.

stateDiagram-v2
    state ocena <<choice>>
    [*] --> Złożony
    Złożony --> ocena: policz ryzyko
    ocena --> Zaakceptowany: punktacja < 40
    ocena --> WeryfikacjaRęczna: punktacja >= 40
    WeryfikacjaRęczna --> Zaakceptowany: analityk akceptuje
    WeryfikacjaRęczna --> Odrzucony: analityk odrzuca
    Zaakceptowany --> [*]
    Odrzucony --> [*]
Otwórz w edytorze

5. Regiony współbieżne

Dwa myślniki w osobnym wierszu dzielą stan złożony na regiony aktywne jednocześnie. To jedyna rzecz, którą diagram stanów robi, a schemat blokowy naprawdę nie potrafi.

stateDiagram-v2
    [*] --> Rejestracja

    state Rejestracja {
        [*] --> MailNiepotwierdzony
        MailNiepotwierdzony --> MailPotwierdzony: kliknięto link
        --
        [*] --> ProfilPusty
        ProfilPusty --> ProfilKompletny: formularz wysłany
    }

    Rejestracja --> Aktywny: oba kroki gotowe
    Aktywny --> [*]
Otwórz w edytorze

Ściąga ze składni diagramu stanów

Używaj `stateDiagram-v2`, a nie `stateDiagram`. Oba się rysują, ale v2 to wciąż rozwijany silnik układu i znacznie lepiej radzi sobie ze stanami złożonymi i współbieżnymi.

SkładniaZnaczenie
stateDiagram-v2Otwiera diagram. `stateDiagram` nadal działa, ale używa starego układu.
[*] --> AStan początkowy — punkt wejścia.
A --> [*]Stan końcowy.
A --> BPrzejście bez nazwanego zdarzenia.
A --> B: zdarzeniePrzejście opisane zdarzeniem, które je wywołuje.
state "Etykieta" as idCzytelna etykieta przy identyfikatorze bez spacji.
state A { ... }Stan złożony zawierający własny automat.
--Wewnątrz stanu złożonego dzieli go na regiony współbieżne.
state x <<choice>>Punkt rozgałęzienia zależny od warunku.
state f <<fork>> / <<join>>Rozdzielenie na przejścia równoległe i ich scalenie.
note right of A: tekstDołącza notatkę. Jest też `note left of`.
direction LRUkłada automat z lewej do prawej zamiast z góry na dół.
Reklama

Sześć błędów, które psują diagram stanów

Odtworzone na Mermaidzie 11.12.2. Cztery pierwsze zatrzymują rysowanie. Dwa ostatnie są gorsze: rysują się bez mrugnięcia okiem i zwracają diagram, który nie znaczy tego, co napisałeś.

Co widzisz

Rysuje się, ale zamiast jednego stanu pojawia się kilka pudełek

Dlaczego

Spacja wewnątrz identyfikatora stanu. Po polsku to najłatwiejszy do popełnienia błąd, bo prawie żaden nasz stan nie mieści się w jednym wyrazie. Mermaid tego nie odrzuca i nie traktuje reszty jako opisu: tworzy osobne pudełko dla każdego wyrazu. Zmierzone przez odczytanie wygenerowanych identyfikatorów: `[*] --> Oczekuje na płatność` daje trzy stany — `Oczekuje`, `na` i `płatność` — z których tylko pierwszy wisi na strzałce; pozostałe stoją niepodłączone. Diagram po cichu rozszerza się w bok. Opis naprawdę istnieje, ale wymaga dwukropka — `oczekuje: czeka na wpłatę` — i to właśnie z nim ten błąd bywa mylony.

Rozwiązanie

Zadeklaruj stan przez `state "Etykieta" as id` i odwołuj się do niego wyłącznie identyfikatorem.

Błędnie
stateDiagram-v2
    [*] --> Oczekuje na płatność
    Oczekuje na płatność --> Zamknięte
Poprawnie
stateDiagram-v2
    state "Oczekuje na płatność" as oczekuje
    [*] --> oczekuje
    oczekuje --> Zamknięte

Co widzisz

Parse error, kończy się na: got 'INVALID'

Dlaczego

Myślnik w identyfikatorze stanu. Nazwy pisane z łącznikiem nasuwają się same — `w-toku`, `wstępnie-zatwierdzony` — ale łącznik czytany jest jako początek strzałki przejścia.

Rozwiązanie

Jeden wyraz albo podkreślenia w identyfikatorze, a czytelny tekst w etykiecie w cudzysłowie.

Błędnie
stateDiagram-v2
    [*] --> w-toku
    w-toku --> Zamknięte
Poprawnie
stateDiagram-v2
    state "W toku" as wToku
    [*] --> wToku
    wToku --> Zamknięte

Co widzisz

Parse error wewnątrz stanu złożonego

Dlaczego

Stan złożony otwarty przez `{` i nigdy niezamknięty. Klamra zamykająca musi stać w osobnym wierszu.

Rozwiązanie

Zamknij blok.

Błędnie
stateDiagram-v2
    [*] --> Zewnętrzny
    state Zewnętrzny {
        [*] --> Wewnętrzny
Poprawnie
stateDiagram-v2
    [*] --> Zewnętrzny
    state Zewnętrzny {
        [*] --> Wewnętrzny
    }

Co widzisz

Lexical error on line N. Unrecognized text.

Dlaczego

Separator regionów współbieżnych z niewłaściwą liczbą myślników. Są dokładnie dwa, w osobnym wierszu, wewnątrz stanu złożonego. Trzy myślniki to zupełnie inny token.

Rozwiązanie

Użyj dokładnie `--`.

Błędnie
stateDiagram-v2
    state Oba {
        [*] --> A
        ---
        [*] --> B
    }
Poprawnie
stateDiagram-v2
    state Oba {
        [*] --> A
        --
        [*] --> B
    }

Co widzisz

Parse error on line 1, kończy się na: got 'ID'

Dlaczego

Nieistniejący przyrostek wersji. Są `stateDiagram` i `stateDiagram-v2`, i nic więcej: `-v3` przewraca się w pierwszym wierszu.

Rozwiązanie

Użyj `stateDiagram-v2`.

Błędnie
stateDiagram-v3
    [*] --> Szkic
Poprawnie
stateDiagram-v2
    [*] --> Szkic

Co widzisz

Rysuje się, ale węzeł wyboru wygląda jak zwykły stan

Dlaczego

Deklaracja `<<choice>>` stoi po przejściach, które jej używają. Mermaid tworzy stan przy pierwszej wzmiance, a stereotyp dopisany później nie zmienia tego, co już powstało.

Rozwiązanie

Deklaruj pseudostany przed przejściami, które się do nich odwołują.

Błędnie
stateDiagram-v2
    [*] --> ocena
    ocena --> Zaakceptowany
    ocena --> Odrzucony
    state ocena <<choice>>
Poprawnie
stateDiagram-v2
    state ocena <<choice>>
    [*] --> ocena
    ocena --> Zaakceptowany
    ocena --> Odrzucony

Uwagi o renderowaniu

Zmierzone na Mermaidzie 11.12.2, którego używa ta strona.

To tutaj spacja w identyfikatorze zawodzi po cichu

Porównanie typów warto znać, bo to samo niedopatrzenie karane jest zupełnie inaczej. W schemacie blokowym spacja wewnątrz identyfikatora węzła daje Parse error i dowiadujesz się od razu. W diagramie stanów nie daje nic: diagram się rysuje, a zamiast jednego stanu powstaje po jednym pudełku na wyraz. To różnica między błędem, który się zgłasza, a takim, który milczy. A ponieważ po polsku prawie żadna nazwa stanu nie mieści się w jednym wyrazie, jedyną realną obroną jest pisanie `state "…" as id` z przyzwyczajenia.

Wysokość rośnie o około 114 pikseli na stan

Zmierzone: trzy stany dają viewBox mniej więcej 91×348, a czterdzieści stanów 100×4566, czyli około 114 pikseli wysokości na stan. Podobnie jak w schematach blokowych, szerokość prawie się nie rusza: automaty stanów rosną w dół. Gdy cykl życia jest długi i płytki, standardowym środkiem jest wpisanie `direction LR` wewnątrz diagramu.

Rysują się i stateDiagram, i stateDiagram-v2 — i to jest pułapka

Często można przeczytać, że bez `stateDiagram-v2` nic się nie narysuje. W 11.12.2 to nieprawda: obie postacie rysują się bez błędu. Różnica leży w jakości układu, zwłaszcza dla stanów złożonych i współbieżnych, a przy użyciu starej postaci nie ma żadnego ostrzeżenia. Jeśli stan złożony wygląda ciasno albo strzałki prowadzą dziwnymi drogami, sprawdź, którym słowem otworzyłeś diagram, zanim zabierzesz się za przepisywanie go.

Etykiety to HTML, więc eksport do PNG przerysowuje

Podobnie jak w schematach blokowych oraz diagramach klas i ER, etykiety stanów rysowane są wewnątrz `<foreignObject>` w SVG. Przeglądarki odmawiają rasteryzowania tego na canvasie, więc eksport do PNG na tej stronie najpierw przerysowuje diagram etykietami z czystego tekstu SVG. PNG wychodzi poprawny i w pełnym rozmiarze; skład tekstu różni się od ekranowego minimalnie.

Motyw zmienia kolory, nigdy geometrię

Motyw jasny i ciemny dają identyczny viewBox dla tego samego źródła, więc automat stanów nie może się przełożyć przy zmianie motywu.

Kiedy lepszy będzie inny diagram

Jeśli twoje etykiety są czasownikami — zwaliduj, wyślij, ponów — opisujesz proces, a nie cykl życia, i uczciwym wyborem jest schemat blokowy. Najwyraźniejszym sygnałem jest to, że nie potrafisz odpowiedzieć na pytanie «czym jest rzecz, która znajduje się w tym stanie?».

Jeśli kilka komponentów ma własne cykle życia, a ciekawa jest właśnie ich interakcja, jeden diagram stanów na komponent plus diagram sekwencji na wymianę komunikatów wygrywa z jednym olbrzymim automatem.

A jeśli każdy stan łączy się z każdym, diagram będzie kłębkiem bez względu na sposób rysowania. Zwykle oznacza to, że to, co nazwałeś stanami, jest w istocie swobodnie łączącymi się flagami; wtedy tabela dopuszczalnych kombinacji mówi znacznie więcej niż obrazek.

Inne typy diagramów

Autor Dominik Malsch · Ostatnia aktualizacja:

Otwórz edytor →