Editor de diagramas de estados Mermaid
Un diagrama de estados muestra los estados por los que puede pasar una sola cosa y los sucesos que la mueven entre ellos. Sirve cuando el asunto es un ciclo de vida — un pedido, una suscripción, un expediente en revisión. La señal inequívoca es que tus etiquetas son adjetivos y no verbos: pendiente, enviado, anulado.
El ciclo de vida de un pedido, con una anulación terminal
Los estados son lo que el pedido es; las etiquetas de las flechas son lo que le ha pasado. Fíjate en que a Anulado se llega desde tres estados pero de él no sale nada: esa asimetría es justo lo que un diagrama de estados hace evidente y un diagrama de flujo esconde.
stateDiagram-v2
[*] --> Pendiente: pedido realizado
Pendiente --> Pagado: cobro confirmado
Pendiente --> Anulado: lo cancela el cliente
Pagado --> Preparado: almacén lo prepara
Pagado --> Reembolsado: cobro revertido
Preparado --> Enviado: lo recoge el transportista
Preparado --> Anulado: sin existencias
Enviado --> Entregado: entrega confirmada
Enviado --> Extraviado: sin lecturas en 14 días
Entregado --> [*]
Reembolsado --> [*]
Anulado --> [*]
Extraviado --> Reembolsado: reclamación aceptadaEjemplos resueltos
1. La máquina de estados mínima
`[*]` es a la vez el pseudoestado inicial y el final: cuál de los dos significa depende del lado de la flecha en que esté.
stateDiagram-v2
[*] --> Borrador
Borrador --> Publicado: publicar
Publicado --> [*]2. Nombrar estados con espacios
Los identificadores de estado no admiten espacios, pero `state "Etiqueta" as id` da una etiqueta legible con un identificador seguro. En español esto se necesita casi siempre, porque nuestros estados naturales son sintagmas: «pendiente de revisión», «a la espera de pago».
stateDiagram-v2
state "Pendiente de revisión" as revision
state "Cambios solicitados" as cambios
[*] --> revision
revision --> cambios: hay objeciones
cambios --> revision: se corrige y se reenvía
revision --> [*]: aprobado3. Estados compuestos
Un estado puede contener su propia máquina de estados. Úsalo cuando una etapa tiene pasos internos con sentido propio que en el nivel superior solo harían ruido: aquí, todo lo que ocurre dentro de Procesando.
stateDiagram-v2
[*] --> EnCola
EnCola --> Procesando: lo toma un worker
state Procesando {
[*] --> Validando
Validando --> Transformando: esquema correcto
Transformando --> Escribiendo: filas mapeadas
Escribiendo --> [*]
}
Procesando --> Correcto: sin errores
Procesando --> Fallido: excepción
Fallido --> EnCola: reintento
Correcto --> [*]4. Pseudoestados de decisión
Un `<<choice>>` es una bifurcación que depende de una condición y no de un suceso. Mantiene la decisión a la vista sin fingir que es un estado en el que el objeto se queda.
stateDiagram-v2
state evaluacion <<choice>>
[*] --> Solicitado
Solicitado --> evaluacion: calcular el riesgo
evaluacion --> Aprobado: puntuación < 40
evaluacion --> RevisionManual: puntuación >= 40
RevisionManual --> Aprobado: el analista acepta
RevisionManual --> Denegado: el analista rechaza
Aprobado --> [*]
Denegado --> [*]5. Regiones concurrentes
Dos guiones en una línea propia parten un estado compuesto en regiones activas a la vez. Es lo único que un diagrama de estados hace y un diagrama de flujo no puede hacer de verdad.
stateDiagram-v2
[*] --> Alta
state Alta {
[*] --> CorreoSinVerificar
CorreoSinVerificar --> CorreoVerificado: pulsa el enlace
--
[*] --> PerfilVacio
PerfilVacio --> PerfilCompleto: envía el formulario
}
Alta --> Activo: ambas completas
Activo --> [*]Referencia de sintaxis del diagrama de estados
Usa `stateDiagram-v2` y no `stateDiagram`. Los dos se dibujan, pero v2 es el motor de disposición que se sigue desarrollando y trata mucho mejor los estados compuestos y concurrentes.
| Sintaxis | Significado |
|---|---|
| stateDiagram-v2 | Abre el diagrama. `stateDiagram` aún funciona, pero usa la disposición antigua. |
| [*] --> A | Estado inicial — el punto de entrada. |
| A --> [*] | Estado final. |
| A --> B | Transición sin suceso nombrado. |
| A --> B: suceso | Transición etiquetada con lo que la provoca. |
| state "Etiqueta" as id | Etiqueta legible con un identificador sin espacios. |
| state A { ... } | Estado compuesto con su propia máquina dentro. |
| -- | Dentro de un estado compuesto, lo parte en regiones concurrentes. |
| state x <<choice>> | Bifurcación por condición. |
| state f <<fork>> / <<join>> | Separar en transiciones paralelas y volver a unirlas. |
| note right of A: texto | Adjunta una nota. También `note left of`. |
| direction LR | Dibuja la máquina de izquierda a derecha en vez de de arriba abajo. |
Seis errores que rompen un diagrama de estados
Reproducidos con Mermaid 11.12.2. Los cuatro primeros impiden que el diagrama se dibuje. Los dos últimos son peores: se dibujan tan contentos y devuelven un diagrama que no significa lo que escribiste.
Lo que ves
Se dibuja, pero un estado se ha convertido en varias cajas
Por qué
Un espacio dentro del identificador de un estado. En español es el error más fácil de cometer, porque casi ningún estado nuestro cabe en una palabra. Mermaid no lo rechaza ni trata el resto como descripción: crea una caja separada por cada palabra. Medido leyendo los identificadores emitidos: `[*] --> Pendiente de pago` produce tres estados, `Pendiente`, `de` y `pago`, y solo el primero cuelga de la flecha; los demás quedan sueltos. El diagrama se ensancha sin decir nada. La descripción existe de verdad, pero necesita dos puntos — `pendientePago: a la espera del cobro` — y es justo con eso con lo que se confunde este error.
Solución
Declara el estado con `state "Etiqueta" as id` y refiérete siempre a él por el identificador.
stateDiagram-v2
[*] --> Pendiente de pago
Pendiente de pago --> CerradostateDiagram-v2
state "Pendiente de pago" as pendiente
[*] --> pendiente
pendiente --> CerradoLo que ves
Parse error, termina en: got 'INVALID'
Por qué
Un guion en el identificador de un estado. Los nombres en kebab-case salen solos — `en-curso`, `pre-aprobado` —, pero el guion se lee como el principio de una flecha de transición.
Solución
Usa una sola palabra o guiones bajos para el identificador, y pon el texto legible en una etiqueta entrecomillada.
stateDiagram-v2
[*] --> en-curso
en-curso --> CerradostateDiagram-v2
state "En curso" as enCurso
[*] --> enCurso
enCurso --> CerradoLo que ves
Parse error dentro de un estado compuesto
Por qué
Un estado compuesto abierto con `{` y nunca cerrado. La llave de cierre tiene que ir en una línea propia.
Solución
Cierra el bloque.
stateDiagram-v2
[*] --> Externo
state Externo {
[*] --> InternostateDiagram-v2
[*] --> Externo
state Externo {
[*] --> Interno
}Lo que ves
Lexical error on line N. Unrecognized text.
Por qué
El separador de regiones concurrentes con el número de guiones equivocado. Son exactamente dos, en una línea propia, dentro de un estado compuesto. Tres guiones son un token completamente distinto.
Solución
Usa exactamente `--`.
stateDiagram-v2
state Ambas {
[*] --> A
---
[*] --> B
}stateDiagram-v2
state Ambas {
[*] --> A
--
[*] --> B
}Lo que ves
Parse error on line 1, termina en: got 'ID'
Por qué
Un sufijo de versión que no existe. Están `stateDiagram` y `stateDiagram-v2`, y nada más: `-v3` falla en la primera línea.
Solución
Usa `stateDiagram-v2`.
stateDiagram-v3
[*] --> BorradorstateDiagram-v2
[*] --> BorradorLo que ves
Se dibuja, pero el nodo de decisión sale como un estado normal
Por qué
La declaración `<<choice>>` va después de las transiciones que la usan. Mermaid crea el estado la primera vez que lo ve mencionado, y un estereotipo posterior no cambia algo que ya está creado.
Solución
Declara los pseudoestados antes de las transiciones que los referencian.
stateDiagram-v2
[*] --> evaluacion
evaluacion --> Aprobado
evaluacion --> Denegado
state evaluacion <<choice>>stateDiagram-v2
state evaluacion <<choice>>
[*] --> evaluacion
evaluacion --> Aprobado
evaluacion --> DenegadoNotas sobre el dibujado
Medido sobre el Mermaid 11.12.2 que usa este sitio.
El espacio en un identificador falla en silencio justo aquí
Merece la pena comparar los tipos, porque el mismo descuido se castiga de forma distinta. En un diagrama de flujo, un espacio dentro del identificador de un nodo da un Parse error y te enteras enseguida. En un diagrama de estados no: el diagrama se dibuja y el estado queda partido en dos. Es la diferencia entre un fallo que te avisa y uno que no, y como en español casi ningún nombre de estado cabe en una palabra, aquí la única defensa real es escribir `state "…" as id` por costumbre.
La altura crece unos 114 píxeles por estado
Medido: tres estados dan un viewBox de unos 91×348 y cuarenta estados dan 100×4566, es decir unos 114 píxeles de altura por estado. Igual que en los diagramas de flujo, el ancho apenas se mueve: las máquinas de estados crecen hacia abajo. Cuando un ciclo de vida es largo y poco ramificado, `direction LR` dentro del diagrama es el arreglo habitual.
stateDiagram y stateDiagram-v2 se dibujan los dos, y eso es una trampa
Se lee a menudo que hay que usar `stateDiagram-v2` o no se dibuja nada. En 11.12.2 no es cierto: las dos palabras clave se dibujan sin error. Lo que cambia es la calidad de la disposición, sobre todo con estados compuestos y concurrentes, y no hay ningún aviso cuando usas la antigua. Si un estado compuesto se ve apretado o las flechas dan rodeos raros, mira con cuál has abierto el diagrama antes de ponerte a reescribirlo.
Las etiquetas son HTML, así que la exportación a PNG redibuja
Igual que en los diagramas de flujo, de clases y ER, las etiquetas de estado se dibujan dentro de un `<foreignObject>` del SVG. Los navegadores se niegan a rasterizar eso sobre un canvas, así que la exportación a PNG de este sitio redibuja antes el diagrama con etiquetas de texto SVG plano. El PNG sale correcto y a tamaño completo; la tipografía difiere mínimamente de la de la pantalla.
El tema cambia el color, nunca la geometría
Los temas claro y oscuro producen un viewBox idéntico para la misma fuente, así que una máquina de estados no puede recolocarse al cambiar de tema.
Cuándo conviene otro diagrama
Si tus etiquetas son verbos — validar, enviar, reintentar —, estás describiendo un proceso y no un ciclo de vida, y lo honesto es un diagrama de flujo. La señal más clara es que no sabes responder a la pregunta «¿qué es la cosa que está en este estado?».
Si hay varios componentes con su propio ciclo de vida y lo interesante es cómo se relacionan entre ellos, un diagrama de estados por componente más un diagrama de secuencia para la interacción gana a una máquina gigantesca.
Y si todos los estados conectan con todos, el diagrama será una maraña se dibuje como se dibuje. Eso suele significar que lo que llamas estados no son estados sino indicadores que se combinan libremente; en ese caso una tabla de combinaciones válidas comunica muchísimo más que un dibujo.
Otros tipos de diagrama
Escrito por Dominik Malsch · Última actualización: