Editor de diagrama de estados Mermaid
Um diagrama de estados mostra os estados em que uma única coisa pode estar e os eventos que a movem entre eles. Use quando o assunto for um ciclo de vida — um pedido, uma assinatura, um processo em análise. O sinal certeiro é que seus rótulos são adjetivos, não verbos: pendente, enviado, cancelado.
O ciclo de vida de um pedido, com cancelamento terminal
Os estados são o que o pedido é; os rótulos das setas são o que aconteceu com ele. Repare que Cancelado é alcançável a partir de três estados mas não leva a lugar nenhum: essa assimetria é exatamente o que um diagrama de estados torna óbvio e um fluxograma esconde.
stateDiagram-v2
[*] --> Pendente: pedido realizado
Pendente --> Pago: pagamento aprovado
Pendente --> Cancelado: cliente desiste
Pago --> Separado: separado no estoque
Pago --> Estornado: pagamento revertido
Separado --> Enviado: coletado pela transportadora
Separado --> Cancelado: sem estoque
Enviado --> Entregue: entrega confirmada
Enviado --> Extraviado: sem rastreio há 14 dias
Entregue --> [*]
Estornado --> [*]
Cancelado --> [*]
Extraviado --> Estornado: reclamação aceitaExemplos resolvidos
1. A máquina de estados mínima
`[*]` é ao mesmo tempo o pseudoestado inicial e o final: qual dos dois ele significa depende do lado da seta em que está.
stateDiagram-v2
[*] --> Rascunho
Rascunho --> Publicado: publicar
Publicado --> [*]2. Nomear estados com espaços
Identificadores de estado não aceitam espaços, mas `state "Rótulo" as id` dá um rótulo legível com um identificador seguro. Em português isso é quase sempre necessário, porque nossos estados naturais são locuções: «aguardando pagamento», «em análise».
stateDiagram-v2
state "Aguardando revisão" as revisao
state "Ajustes solicitados" as ajustes
[*] --> revisao
revisao --> ajustes: revisor aponta problemas
ajustes --> revisao: autor corrige
revisao --> [*]: aprovado3. Estados compostos
Um estado pode conter a própria máquina de estados. Use quando uma etapa tem passos internos com significado próprio que só atrapalhariam no nível de cima: aqui, tudo o que acontece dentro de Processando.
stateDiagram-v2
[*] --> NaFila
NaFila --> Processando: worker assumiu
state Processando {
[*] --> Validando
Validando --> Transformando: esquema confere
Transformando --> Gravando: linhas mapeadas
Gravando --> [*]
}
Processando --> Concluido: sem erros
Processando --> Falhou: exceção lançada
Falhou --> NaFila: nova tentativa
Concluido --> [*]4. Pseudoestados de escolha
Um `<<choice>>` é uma bifurcação que depende de uma condição, não de um evento. Mantém a decisão visível sem fingir que é um estado em que o objeto permanece.
stateDiagram-v2
state analise <<choice>>
[*] --> Solicitado
Solicitado --> analise: calcular o risco
analise --> Aprovado: score < 40
analise --> AnaliseManual: score >= 40
AnaliseManual --> Aprovado: analista aceita
AnaliseManual --> Negado: analista recusa
Aprovado --> [*]
Negado --> [*]5. Regiões concorrentes
Dois hifens numa linha só dividem um estado composto em regiões ativas ao mesmo tempo. É a única coisa que um diagrama de estados faz e um fluxograma realmente não consegue.
stateDiagram-v2
[*] --> Cadastro
state Cadastro {
[*] --> EmailNaoVerificado
EmailNaoVerificado --> EmailVerificado: link clicado
--
[*] --> PerfilVazio
PerfilVazio --> PerfilCompleto: formulário enviado
}
Cadastro --> Ativo: os dois concluídos
Ativo --> [*]Referência de sintaxe do diagrama de estados
Use `stateDiagram-v2` em vez de `stateDiagram`. Os dois desenham, mas o v2 é o motor de layout que continua em desenvolvimento e lida muito melhor com estados compostos e concorrentes.
| Sintaxe | Significado |
|---|---|
| stateDiagram-v2 | Abre o diagrama. `stateDiagram` ainda funciona, mas usa o layout antigo. |
| [*] --> A | Estado inicial — o ponto de entrada. |
| A --> [*] | Estado final. |
| A --> B | Transição sem evento nomeado. |
| A --> B: evento | Transição rotulada com o que a provoca. |
| state "Rótulo" as id | Rótulo legível com identificador sem espaços. |
| state A { ... } | Estado composto contendo a própria máquina. |
| -- | Dentro de um estado composto, divide em regiões concorrentes. |
| state x <<choice>> | Ponto de bifurcação por condição. |
| state f <<fork>> / <<join>> | Dividir em transições paralelas e reunir. |
| note right of A: texto | Anexa uma nota. Também `note left of`. |
| direction LR | Dispõe a máquina da esquerda para a direita em vez de de cima para baixo. |
Seis erros que quebram um diagrama de estados
Reproduzidos no Mermaid 11.12.2. Os quatro primeiros impedem o diagrama de desenhar. Os dois últimos são piores: desenham numa boa e devolvem um diagrama que não quer dizer o que você escreveu.
O que você vê
Desenha, mas um estado virou várias caixas
Por quê
Um espaço dentro do identificador de um estado. Em português é o erro mais fácil de cometer, porque quase nenhum dos nossos estados cabe numa palavra. O Mermaid não rejeita e não trata o resto como descrição: ele cria uma caixa separada para cada palavra. Medido lendo os identificadores emitidos: `[*] --> Aguardando pagamento` produz dois estados, `Aguardando` e `pagamento`, e só o primeiro fica na ponta da seta; o outro fica solto. Com três palavras são três caixas, e o diagrama se alarga sem avisar. A descrição existe mesmo, mas exige dois-pontos — `aguardando: à espera do pagamento` — e é com isso que este erro é confundido.
Solução
Declare o estado com `state "Rótulo" as id` e refira-se sempre a ele pelo identificador.
stateDiagram-v2
[*] --> Aguardando pagamento
Aguardando pagamento --> FechadostateDiagram-v2
state "Aguardando pagamento" as aguardando
[*] --> aguardando
aguardando --> FechadoO que você vê
Parse error, terminando em: got 'INVALID'
Por quê
Um hífen no identificador de um estado. Nomes em kebab-case saem naturalmente — `em-analise`, `pre-aprovado` —, mas o hífen é lido como o começo de uma seta de transição.
Solução
Use uma palavra só ou underscores no identificador, e ponha o texto legível num rótulo entre aspas.
stateDiagram-v2
[*] --> em-analise
em-analise --> FechadostateDiagram-v2
state "Em análise" as emAnalise
[*] --> emAnalise
emAnalise --> FechadoO que você vê
Parse error dentro de um estado composto
Por quê
Um estado composto aberto com `{` e nunca fechado. A chave de fechamento precisa ficar numa linha só dela.
Solução
Feche o bloco.
stateDiagram-v2
[*] --> Externo
state Externo {
[*] --> InternostateDiagram-v2
[*] --> Externo
state Externo {
[*] --> Interno
}O que você vê
Lexical error on line N. Unrecognized text.
Por quê
O separador de regiões concorrentes com o número errado de hifens. São exatamente dois, numa linha só deles, dentro de um estado composto. Três hifens são um token completamente diferente.
Solução
Use exatamente `--`.
stateDiagram-v2
state Ambas {
[*] --> A
---
[*] --> B
}stateDiagram-v2
state Ambas {
[*] --> A
--
[*] --> B
}O que você vê
Parse error on line 1, terminando em: got 'ID'
Por quê
Um sufixo de versão que não existe. Há `stateDiagram` e `stateDiagram-v2`, e nada mais: `-v3` falha na primeira linha.
Solução
Use `stateDiagram-v2`.
stateDiagram-v3
[*] --> RascunhostateDiagram-v2
[*] --> RascunhoO que você vê
Desenha, mas o nó de escolha sai como um estado comum
Por quê
A declaração `<<choice>>` veio depois das transições que a usam. O Mermaid cria o estado na primeira vez que ele é mencionado, e um estereótipo posterior não muda o que já foi criado.
Solução
Declare os pseudoestados antes das transições que os referenciam.
stateDiagram-v2
[*] --> analise
analise --> Aprovado
analise --> Negado
state analise <<choice>>stateDiagram-v2
state analise <<choice>>
[*] --> analise
analise --> Aprovado
analise --> NegadoNotas sobre a renderização
Medido no Mermaid 11.12.2 que este site usa.
É aqui que o espaço num identificador falha em silêncio
A comparação entre tipos vale a pena, porque o mesmo descuido é punido de formas bem diferentes. Num fluxograma, um espaço dentro do identificador de um nó dá Parse error e você fica sabendo na hora. Num diagrama de estados, não: o diagrama desenha e o estado se parte em dois. É a diferença entre um erro que avisa e um que não avisa. E como em português quase nenhum nome de estado cabe numa palavra, a única defesa real é escrever `state "…" as id` por hábito.
A altura cresce cerca de 114 pixels por estado
Medido: três estados dão um viewBox de aproximadamente 91×348 e quarenta estados dão 100×4566, ou seja, uns 114 pixels de altura por estado. Como nos fluxogramas, a largura quase não se mexe: máquinas de estados crescem para baixo. Quando um ciclo de vida é longo e pouco ramificado, `direction LR` dentro do diagrama é a solução de sempre.
stateDiagram e stateDiagram-v2 desenham os dois — e isso é uma armadilha
Lê-se muito que é preciso usar `stateDiagram-v2` ou nada aparece. Não é verdade na 11.12.2: as duas palavras-chave desenham sem erro. O que muda é a qualidade do layout, sobretudo com estados compostos e concorrentes, e não há aviso nenhum quando você usa a antiga. Se um estado composto parecer apertado ou as setas fizerem contornos estranhos, confira com qual palavra-chave você abriu antes de sair reescrevendo o diagrama.
Os rótulos são HTML, então a exportação para PNG redesenha
Como nos fluxogramas e nos diagramas de classes e ER, os rótulos de estado são desenhados dentro de um `<foreignObject>` do SVG. Os navegadores se recusam a rasterizar isso num canvas, então a exportação para PNG deste site redesenha antes o diagrama com rótulos em texto SVG simples. O PNG sai correto e em tamanho cheio; a tipografia difere muito levemente da tela.
O tema muda a cor, nunca a geometria
Os temas claro e escuro produzem um viewBox idêntico para a mesma fonte, então uma máquina de estados não pode se recompor quando o tema muda.
Quando usar outro diagrama
Se seus rótulos são verbos — validar, enviar, tentar de novo —, você está descrevendo um processo e não um ciclo de vida, e a escolha honesta é o fluxograma. O sinal mais claro é você não conseguir responder à pergunta «o que é a coisa que está neste estado?».
Se vários componentes têm cada um o seu ciclo de vida e o interessante é como eles interagem, um diagrama de estados por componente mais um diagrama de sequência para a interação vence uma máquina gigantesca.
E se todo estado se conecta com todos os outros, o diagrama será um emaranhado por mais que se tente. Isso costuma significar que o que você chama de estados não são estados, e sim indicadores que se combinam livremente; nesse caso, uma tabela de combinações válidas comunica muito mais que um desenho.
Outros tipos de diagrama
Escrito por Dominik Malsch · Última atualização: