Gratuito · Senza registrazione · Compatibile con file .mmd

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 --> [*]
Aprilo nell'editor
Pubblicità

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 --> [*]
Apri nell'editor

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 --> [*]
Apri nell'editor

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 --> [*]
Apri nell'editor

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 --> [*]
Apri nell'editor

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 --> [*]
Apri nell'editor

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.

SintassiSignificato
stateDiagram-v2Apre il diagramma. `stateDiagram` funziona ancora ma usa la vecchia disposizione.
[*] --> AStato iniziale — il punto d'ingresso.
A --> [*]Stato finale.
A --> BUna transizione senza nome.
A --> B: eventoTransizione etichettata con l'evento che la provoca.
state "Etichetta" as idEtichetta 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: testoAggiunge una nota. Esiste anche `note left of`.
direction LRDispone la macchina da sinistra a destra invece che dall'alto in basso.
Pubblicità

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.

Sbagliato
stateDiagram-v2
    [*] --> In attesa di pagamento
    In attesa di pagamento --> Chiuso
Corretto
stateDiagram-v2
    state "In attesa di pagamento" as attesaPagamento
    [*] --> attesaPagamento
    attesaPagamento --> Chiuso

Cosa 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.

Sbagliato
stateDiagram-v2
    [*] --> in-lavorazione
    in-lavorazione --> Chiuso
Corretto
stateDiagram-v2
    state "In lavorazione" as inLavorazione
    [*] --> inLavorazione
    inLavorazione --> Chiuso

Cosa 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.

Sbagliato
stateDiagram-v2
    [*] --> Esterno
    state Esterno {
        [*] --> Interno
Corretto
stateDiagram-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 `--`.

Sbagliato
stateDiagram-v2
    state Entrambe {
        [*] --> A
        ---
        [*] --> B
    }
Corretto
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`.

Sbagliato
stateDiagram-v3
    [*] --> Bozza
Corretto
stateDiagram-v2
    [*] --> Bozza

Cosa 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.

Sbagliato
stateDiagram-v2
    [*] --> valutazione
    valutazione --> Approvato
    valutazione --> Respinto
    state valutazione <<choice>>
Corretto
stateDiagram-v2
    state valutazione <<choice>>
    [*] --> valutazione
    valutazione --> Approvato
    valutazione --> Respinto

Note 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:

Apri l'editor →