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 uznanaOmó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 --> [*]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 --> [*]: zaakceptowano3. 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 --> [*]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 --> [*]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 --> [*]Ś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ładnia | Znaczenie |
|---|---|
| stateDiagram-v2 | Otwiera diagram. `stateDiagram` nadal działa, ale używa starego układu. |
| [*] --> A | Stan początkowy — punkt wejścia. |
| A --> [*] | Stan końcowy. |
| A --> B | Przejście bez nazwanego zdarzenia. |
| A --> B: zdarzenie | Przejście opisane zdarzeniem, które je wywołuje. |
| state "Etykieta" as id | Czytelna 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: tekst | Dołącza notatkę. Jest też `note left of`. |
| direction LR | Układa automat z lewej do prawej zamiast z góry na dół. |
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.
stateDiagram-v2
[*] --> Oczekuje na płatność
Oczekuje na płatność --> ZamkniętestateDiagram-v2
state "Oczekuje na płatność" as oczekuje
[*] --> oczekuje
oczekuje --> ZamknięteCo 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.
stateDiagram-v2
[*] --> w-toku
w-toku --> ZamkniętestateDiagram-v2
state "W toku" as wToku
[*] --> wToku
wToku --> ZamknięteCo 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.
stateDiagram-v2
[*] --> Zewnętrzny
state Zewnętrzny {
[*] --> WewnętrznystateDiagram-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 `--`.
stateDiagram-v2
state Oba {
[*] --> A
---
[*] --> B
}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`.
stateDiagram-v3
[*] --> SzkicstateDiagram-v2
[*] --> SzkicCo 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ą.
stateDiagram-v2
[*] --> ocena
ocena --> Zaakceptowany
ocena --> Odrzucony
state ocena <<choice>>stateDiagram-v2
state ocena <<choice>>
[*] --> ocena
ocena --> Zaakceptowany
ocena --> OdrzuconyUwagi 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: