Editor di diagrammi di stato Mermaid
Un diagramma di stato mostra gli stati in cui una cosa può trovarsi e cosa la fa passare dall'uno all'altro. Va bene quando il soggetto ha un ciclo di vita — un ordine, una fattura, un abbonamento — e la domanda interessante è quali transizioni siano lecite. Se stai descrivendo passi da eseguire e non stati in cui stare, serve un diagramma di flusso.
Il ciclo di vita di una fattura elettronica
Questo è il caso in cui una macchina a stati guadagna il suo posto: gli esiti dopo l'invio sono tre e si escludono a vicenda, e uno di essi — lo scarto — riporta indietro. Nota che ogni transizione ha un'etichetta. Un diagramma di stato senza etichette dice quali stati esistono ma non dice cosa li faccia cambiare, che è metà dell'informazione.
stateDiagram-v2
direction LR
state "Bozza" as bozza
state "Inviata al sistema di interscambio" as inviata
state "Scartata" as scartata
state "Consegnata" as consegnata
state "Mancata consegna" as mancata
state "Accettata" as accettata
[*] --> bozza
bozza --> inviata: firmata e trasmessa
inviata --> scartata: controlli formali falliti
inviata --> consegnata: recapitata al destinatario
inviata --> mancata: casella non raggiungibile
scartata --> bozza: correggi e ritrasmetti
mancata --> consegnata: messa a disposizione
consegnata --> accettata: nessun rifiuto nei termini
accettata --> [*]Esempi commentati
1. La macchina a stati più piccola
`[*]` è sia il punto d'ingresso sia quello d'uscita: quale dei due dipende da che lato della freccia si trova. Questa è la struttura minima che vale la pena disegnare.
stateDiagram-v2
[*] --> Attivo
Attivo --> Chiuso
Chiuso --> [*]2. Transizioni con un nome
Il testo dopo i due punti indica l'evento che provoca la transizione. È la parte che rende utile il diagramma: senza, hai un elenco di stati e nessuna regola.
stateDiagram-v2
[*] --> InAttesa
InAttesa --> Pagato: incasso riuscito
InAttesa --> Annullato: scaduto dopo 24 ore
Pagato --> Spedito: uscito dal magazzino
Spedito --> Consegnato: firma del destinatario
Consegnato --> [*]
Annullato --> [*]3. Etichette leggibili con identificatori sicuri
In italiano quasi nessun nome di stato sta in una parola sola, e uno spazio nell'identificatore rompe le cose in silenzio. `state "Etichetta" as id` risolve la questione una volta per tutte: l'etichetta è leggibile, l'identificatore è al sicuro.
stateDiagram-v2
state "In attesa di pagamento" as attesaPagamento
state "Pronto per la spedizione" as prontoSpedizione
state "In transito" as inTransito
[*] --> attesaPagamento
attesaPagamento --> prontoSpedizione: pagamento confermato
prontoSpedizione --> inTransito: presa in carico dal corriere
inTransito --> [*]4. Stati composti e punti di scelta
Uno stato composto contiene una macchina propria: usalo quando una fase ha una vita interna che conta. `<<choice>>` è una diramazione condizionale, e va dichiarata prima delle transizioni che la usano.
stateDiagram-v2
state valutazione <<choice>>
[*] --> InLavorazione
state InLavorazione {
[*] --> Raccolta
Raccolta --> Imballaggio: articoli raccolti
Imballaggio --> [*]
}
InLavorazione --> valutazione
valutazione --> Approvato: controllo qualità superato
valutazione --> Respinto: difetto rilevato
Approvato --> [*]
Respinto --> [*]5. Regioni concorrenti
Due trattini su una riga a sé dividono uno stato composto in regioni attive contemporaneamente. È l'unica cosa che il diagramma di stato fa e che il diagramma di flusso davvero non sa fare.
stateDiagram-v2
[*] --> Registrazione
state Registrazione {
[*] --> EmailNonVerificata
EmailNonVerificata --> EmailVerificata: link cliccato
--
[*] --> ProfiloVuoto
ProfiloVuoto --> ProfiloCompleto: modulo inviato
}
Registrazione --> Attivo: entrambe completate
Attivo --> [*]Riepilogo della sintassi del diagramma di stato
Usa `stateDiagram-v2` e non `stateDiagram`. Entrambi si disegnano, ma v2 è il motore di disposizione ancora sviluppato e gestisce nettamente meglio gli stati composti e concorrenti.
| Sintassi | Significato |
|---|---|
| stateDiagram-v2 | Apre il diagramma. `stateDiagram` funziona ancora ma usa la vecchia disposizione. |
| [*] --> A | Stato iniziale — il punto d'ingresso. |
| A --> [*] | Stato finale. |
| A --> B | Una transizione senza nome. |
| A --> B: evento | Transizione etichettata con l'evento che la provoca. |
| state "Etichetta" as id | Etichetta leggibile con un identificatore senza spazi. |
| state A { ... } | Stato composto, con una macchina propria dentro. |
| -- | Dentro uno stato composto, lo divide in regioni concorrenti. |
| state x <<choice>> | Punto di diramazione condizionale. |
| state f <<fork>> / <<join>> | Divisione in transizioni parallele e loro ricongiungimento. |
| note right of A: testo | Aggiunge una nota. Esiste anche `note left of`. |
| direction LR | Dispone la macchina da sinistra a destra invece che dall'alto in basso. |
I sei errori che rompono un diagramma di stato
Riprodotti su Mermaid 11.12.2. I primi quattro fermano il disegno. Gli ultimi due sono peggio: si disegnano senza batter ciglio e restituiscono un diagramma che non significa quello che hai scritto.
Cosa vedi
Si disegna, ma al posto di uno stato ne compaiono diversi
Perché
Dentro l'identificatore dello stato c'è uno spazio. In italiano è l'errore più facile da fare, perché quasi nessuno dei nostri nomi di stato sta in una parola sola. Mermaid non lo rifiuta e non lo tratta come una descrizione: crea un riquadro separato per ogni parola. Misurato leggendo gli identificatori emessi — `[*] --> In attesa di pagamento` produce quattro stati distinti, `In`, `attesa`, `di` e `pagamento`, di cui solo il primo è collegato alla freccia; gli altri restano lì scollegati. Il diagramma si allarga di lato senza dire niente. La descrizione esiste davvero, ma vuole i due punti: `attesaPagamento: in attesa dell'incasso`.
Soluzione
Dichiaralo con `state "Etichetta" as id` e riferisciti a esso sempre con l'identificatore.
stateDiagram-v2
[*] --> In attesa di pagamento
In attesa di pagamento --> ChiusostateDiagram-v2
state "In attesa di pagamento" as attesaPagamento
[*] --> attesaPagamento
attesaPagamento --> ChiusoCosa vedi
Parse error che finisce con: got 'INVALID'
Perché
Nell'identificatore dello stato c'è un trattino. I nomi col trattino vengono spontanei — `in-lavorazione`, `pre-autorizzato` — ma il trattino viene letto come l'inizio di una freccia di transizione.
Soluzione
Usa una parola sola o il trattino basso per l'identificatore, e metti il testo leggibile in un'etichetta fra virgolette.
stateDiagram-v2
[*] --> in-lavorazione
in-lavorazione --> ChiusostateDiagram-v2
state "In lavorazione" as inLavorazione
[*] --> inLavorazione
inLavorazione --> ChiusoCosa vedi
Parse error dentro uno stato composto
Perché
Uno stato composto aperto con `{` e mai chiuso. La graffa di chiusura deve stare su una riga a sé.
Soluzione
Chiudi il blocco.
stateDiagram-v2
[*] --> Esterno
state Esterno {
[*] --> InternostateDiagram-v2
[*] --> Esterno
state Esterno {
[*] --> Interno
}Cosa vedi
Lexical error on line N. Unrecognized text.
Perché
Il separatore delle regioni concorrenti è scritto con il numero sbagliato di trattini. Dentro uno stato composto, su una riga a sé, sono esattamente due. Tre trattini sono un token completamente diverso.
Soluzione
Usa esattamente `--`.
stateDiagram-v2
state Entrambe {
[*] --> A
---
[*] --> B
}stateDiagram-v2
state Entrambe {
[*] --> A
--
[*] --> B
}Cosa vedi
Parse error on line 1 che finisce con: got 'ID'
Perché
Un suffisso di versione che non esiste. Esistono `stateDiagram` e `stateDiagram-v2`, e nient'altro: `-v3` cade alla prima riga.
Soluzione
Usa `stateDiagram-v2`.
stateDiagram-v3
[*] --> BozzastateDiagram-v2
[*] --> BozzaCosa vedi
Si disegna, ma il nodo di scelta è disegnato come uno stato qualunque
Perché
La dichiarazione `<<choice>>` arriva dopo le transizioni che la usano. Mermaid crea lo stato nel momento in cui lo incontra per la prima volta, e uno stereotipo aggiunto dopo non modifica quello già creato.
Soluzione
Dichiara gli pseudo-stati prima delle transizioni che vi fanno riferimento.
stateDiagram-v2
[*] --> valutazione
valutazione --> Approvato
valutazione --> Respinto
state valutazione <<choice>>stateDiagram-v2
state valutazione <<choice>>
[*] --> valutazione
valutazione --> Approvato
valutazione --> RespintoNote sul disegno
Misurato su Mermaid 11.12.2, la versione che usa questo sito.
È qui che lo spazio nell'identificatore fallisce in silenzio
Il confronto fra i tipi vale la pena conoscerlo, perché la stessa distrazione viene punita in modi molto diversi. In un diagramma di flusso uno spazio nell'identificatore di un nodo produce un Parse error e te ne accorgi subito. In un diagramma di stato non produce nulla: il diagramma si disegna e al posto di uno stato ne trovi uno per parola. Misurato: `In attesa di pagamento --> Chiuso` esce a 371 pixel di larghezza con cinque riquadri, contro i 161 di una versione a due parole. È la differenza fra un errore che ti avvisa e uno che tace. Dato che in italiano quasi nessun nome di stato sta in una parola sola, l'unica difesa vera è scrivere `state "…" as id` per abitudine.
L'altezza cresce di circa 114 pixel per stato
Misurato: tre stati danno un viewBox di circa 91×348, quaranta ne danno 100×4566 — all'incirca 114 pixel per stato. Come nei diagrammi di flusso la larghezza quasi non si muove: le macchine a stati crescono verso il basso. Se il ciclo di vita è lungo e poco ramificato, mettere `direction LR` nel diagramma è la soluzione consueta.
Si disegnano sia stateDiagram sia stateDiagram-v2 — ed è questa la trappola
Si legge spesso che «senza `stateDiagram-v2` non si disegna nulla». Nella 11.12.2 non è vero: entrambe le parole chiave si disegnano senza errori. Quello che cambia è la qualità della disposizione, soprattutto con stati composti e concorrenti, e usando la vecchia non compare alcun avviso. Se uno stato composto sembra compresso o le frecce fanno giri strani, guarda con quale parola chiave hai aperto il diagramma prima di metterti a riscriverlo.
Le etichette sono HTML, quindi l'esportazione PNG ridisegna
Come nei diagrammi di flusso, delle classi e ER, anche le etichette degli stati sono disegnate dentro un `<foreignObject>` nell'SVG. Dato che i browser si rifiutano di rasterizzarlo su un canvas, l'esportazione PNG di questo sito ridisegna prima il diagramma con etichette di testo SVG semplice. Il PNG esce corretto e a piena dimensione; la composizione differisce di pochissimo da quella a schermo.
Il tema cambia i colori, mai la geometria
Tema chiaro e tema scuro producono lo stesso viewBox per la stessa sorgente, quindi una macchina a stati non si ricompone al cambio di tema.
Quando conviene un altro diagramma
Se le tue etichette sono azioni — valida, invia, riprova — stai descrivendo un processo e non un ciclo di vita, e la scelta onesta è il diagramma di flusso. Il segnale più chiaro è che non riesci a rispondere alla domanda «cos'è la cosa che si trova in questo stato?».
Se più componenti hanno ciascuno il proprio ciclo di vita e la parte interessante è la loro interazione, un diagramma di stato per componente più un diagramma di sequenza per l'interazione batte una sola macchina gigantesca.
Se ogni stato è collegato a ogni altro stato, il diagramma sarà un groviglio comunque lo si disegni. Di solito significa che le cose che hai elencato come stati sono in realtà flag che si combinano liberamente; in quel caso una tabella delle combinazioni valide dice molto più di un'immagine.
Altri tipi di diagramma
Scritto da Dominik Malsch · Ultimo aggiornamento: