Бесплатно · Без регистрации · Поддержка файлов .mmd

Редактор диаграмм состояний Mermaid

Диаграмма состояний показывает, в каких состояниях может находиться один объект и какие события переводят его между ними. Она уместна, когда предмет — жизненный цикл: заказ, подписка, документ на согласовании. Верный признак: ваши подписи — это причастия и прилагательные, а не глаголы: ожидает, отгружен, отменён.

Жизненный цикл заказа с тупиковой отменой

Состояния — это то, чем заказ является; подписи на стрелках — то, что с ним произошло. Обратите внимание: в «Отменён» попадают из трёх состояний, но из него не ведёт ничего. Именно такую асимметрию диаграмма состояний делает очевидной, а блок-схема скрывает.

stateDiagram-v2
    [*] --> Новый: заказ оформлен
    Новый --> Оплачен: платёж прошёл
    Новый --> Отменён: клиент отказался
    Оплачен --> Собран: склад собрал
    Оплачен --> Возвращён: платёж отменён
    Собран --> Отгружен: передан перевозчику
    Собран --> Отменён: товара нет в наличии
    Отгружен --> Доставлен: доставка подтверждена
    Отгружен --> Потерян: нет сканов 14 дней
    Доставлен --> [*]
    Возвращён --> [*]
    Отменён --> [*]
    Потерян --> Возвращён: претензия удовлетворена
Открыть в редакторе
Реклама

Разобранные примеры

1. Минимальный конечный автомат

`[*]` — это и начальное, и конечное псевдосостояние: что именно оно означает, зависит от того, с какой стороны стрелки стоит.

stateDiagram-v2
    [*] --> Черновик
    Черновик --> Опубликован: опубликовать
    Опубликован --> [*]
Открыть в редакторе

2. Как называть состояния с пробелами

Идентификатор состояния не может содержать пробелов, но `state "Подпись" as id` даёт читаемую подпись при безопасном идентификаторе. По-русски это нужно почти всегда, потому что естественные состояния у нас — словосочетания: «ожидает оплаты», «на согласовании».

stateDiagram-v2
    state "Ожидает проверки" as проверка
    state "Нужны правки" as правки
    [*] --> проверка
    проверка --> правки: проверяющий возражает
    правки --> проверка: автор исправил
    проверка --> [*]: согласовано
Открыть в редакторе

3. Составные состояния

Состояние может содержать собственный автомат. Используйте это, когда у этапа есть осмысленные внутренние шаги, которые на верхнем уровне только мешали бы: здесь — всё, что происходит внутри обработки.

stateDiagram-v2
    [*] --> ВОчереди
    ВОчереди --> Обработка: взял обработчик

    state Обработка {
        [*] --> Проверка
        Проверка --> Преобразование: схема подходит
        Преобразование --> Запись: строки сопоставлены
        Запись --> [*]
    }

    Обработка --> Успех: без ошибок
    Обработка --> Сбой: исключение
    Сбой --> ВОчереди: повторить
    Успех --> [*]
Открыть в редакторе

4. Псевдосостояния выбора

`<<choice>>` — это развилка, зависящая от условия, а не от события. Она оставляет решение видимым, не притворяясь, что это состояние, в котором объект находится.

stateDiagram-v2
    state оценка <<choice>>
    [*] --> Подана
    Подана --> оценка: рассчитать риск
    оценка --> Одобрена: балл < 40
    оценка --> РучнаяПроверка: балл >= 40
    РучнаяПроверка --> Одобрена: аналитик согласен
    РучнаяПроверка --> Отклонена: аналитик отказал
    Одобрена --> [*]
    Отклонена --> [*]
Открыть в редакторе

5. Параллельные области

Два дефиса на отдельной строке делят составное состояние на области, активные одновременно. Это единственное, что диаграмма состояний умеет, а блок-схема по-настоящему не может.

stateDiagram-v2
    [*] --> Регистрация

    state Регистрация {
        [*] --> ПочтаНеПодтверждена
        ПочтаНеПодтверждена --> ПочтаПодтверждена: перешёл по ссылке
        --
        [*] --> ПрофильПустой
        ПрофильПустой --> ПрофильЗаполнен: форма отправлена
    }

    Регистрация --> Активен: оба шага завершены
    Активен --> [*]
Открыть в редакторе

Справочник синтаксиса диаграммы состояний

Используйте `stateDiagram-v2`, а не `stateDiagram`. Рисуются оба, но v2 — это активно развиваемый движок раскладки, и составные с параллельными состояниями он обрабатывает заметно лучше.

СинтаксисЗначение
stateDiagram-v2Открывает диаграмму. `stateDiagram` ещё работает, но использует старую раскладку.
[*] --> AНачальное состояние — точка входа.
A --> [*]Конечное состояние.
A --> BПереход без названного события.
A --> B: событиеПереход, подписанный вызвавшим его событием.
state "Подпись" as idЧитаемая подпись с идентификатором без пробелов.
state A { ... }Составное состояние с собственным автоматом внутри.
--Внутри составного состояния делит его на параллельные области.
state x <<choice>>Точка ветвления по условию.
state f <<fork>> / <<join>>Разделение на параллельные переходы и слияние обратно.
note right of A: текстПрикрепляет заметку. Есть и `note left of`.
direction LRРаскладывает автомат слева направо вместо сверху вниз.
Реклама

Шесть ошибок, ломающих диаграмму состояний

Воспроизведены на Mermaid 11.12.2. Первые четыре останавливают отрисовку. Последние две хуже: они спокойно рисуются и выдают диаграмму, которая означает не то, что вы написали.

Что вы видите

Диаграмма рисуется, но вместо одного состояния появляется несколько прямоугольников

Почему

Пробел внутри идентификатора состояния. По-русски это самая лёгкая ошибка из возможных, потому что почти ни одно наше состояние не умещается в одно слово. Mermaid ничего не отвергает и не считает остаток описанием: он создаёт отдельный прямоугольник на каждое слово. Измерено по выданным идентификаторам: `[*] --> Ожидает оплаты` даёт два состояния, `Ожидает` и `оплаты`, и только первое висит на стрелке; второе остаётся ни с чем не связанным. Из трёх слов выйдет три прямоугольника, и диаграмма молча расползётся вширь. Описание действительно существует, но требует двоеточия — `ожидает: ждёт поступления оплаты` — именно с ним эту ошибку и путают.

Решение

Объявите состояние через `state "Подпись" as id` и всегда ссылайтесь на него по идентификатору.

Ошибка
stateDiagram-v2
    [*] --> Ожидает оплаты
    Ожидает оплаты --> Закрыт
Исправлено
stateDiagram-v2
    state "Ожидает оплаты" as ожидание
    [*] --> ожидание
    ожидание --> Закрыт

Что вы видите

Parse error, заканчивается на: got 'INVALID'

Почему

Дефис в идентификаторе состояния. Имена через дефис напрашиваются сами — `в-работе`, `пред-одобрен`, — но дефис читается как начало стрелки перехода.

Решение

Одно слово или подчёркивания для идентификатора, а читаемый текст — в подпись в кавычках.

Ошибка
stateDiagram-v2
    [*] --> в-работе
    в-работе --> Закрыт
Исправлено
stateDiagram-v2
    state "В работе" as вРаботе
    [*] --> вРаботе
    вРаботе --> Закрыт

Что вы видите

Parse error внутри составного состояния

Почему

Составное состояние открыто через `{` и не закрыто. Закрывающая фигурная скобка должна стоять на отдельной строке.

Решение

Закройте блок.

Ошибка
stateDiagram-v2
    [*] --> Внешнее
    state Внешнее {
        [*] --> Внутреннее
Исправлено
stateDiagram-v2
    [*] --> Внешнее
    state Внешнее {
        [*] --> Внутреннее
    }

Что вы видите

Lexical error on line N. Unrecognized text.

Почему

Разделитель параллельных областей написан с неверным числом дефисов. Их ровно два, на отдельной строке, внутри составного состояния. Три дефиса — это совсем другой токен.

Решение

Используйте ровно `--`.

Ошибка
stateDiagram-v2
    state Обе {
        [*] --> A
        ---
        [*] --> B
    }
Исправлено
stateDiagram-v2
    state Обе {
        [*] --> A
        --
        [*] --> B
    }

Что вы видите

Parse error on line 1, заканчивается на: got 'ID'

Почему

Несуществующий суффикс версии. Есть `stateDiagram` и `stateDiagram-v2`, и больше ничего: `-v3` падает на первой строке.

Решение

Используйте `stateDiagram-v2`.

Ошибка
stateDiagram-v3
    [*] --> Черновик
Исправлено
stateDiagram-v2
    [*] --> Черновик

Что вы видите

Диаграмма рисуется, но узел выбора нарисован как обычное состояние

Почему

Объявление `<<choice>>` идёт после переходов, которые его используют. Mermaid создаёт состояние при первом упоминании, и стереотип, добавленный позже, не меняет уже созданное.

Решение

Объявляйте псевдосостояния до переходов, которые на них ссылаются.

Ошибка
stateDiagram-v2
    [*] --> оценка
    оценка --> Одобрена
    оценка --> Отклонена
    state оценка <<choice>>
Исправлено
stateDiagram-v2
    state оценка <<choice>>
    [*] --> оценка
    оценка --> Одобрена
    оценка --> Отклонена

Заметки о рендеринге

Измерено на том Mermaid 11.12.2, который использует сайт.

Пробел в идентификаторе наказывается здесь тише всего

Сравнение типов стоит запомнить, потому что одна и та же оплошность карается по-разному. В блок-схеме пробел внутри идентификатора узла даёт Parse error — вас предупредили сразу. В диаграмме состояний не даёт ничего: диаграмма рисуется, а состояние раскалывается надвое. Это разница между ошибкой, которая себя показывает, и ошибкой, которая молчит. А поскольку по-русски почти ни одно название состояния не умещается в одно слово, единственная реальная защита — писать `state "…" as id` по привычке, не раздумывая.

Высота растёт примерно на 114 пикселей на состояние

Измерено: три состояния дают viewBox около 91×348, сорок состояний — 100×4566, то есть примерно 114 пикселей высоты на состояние. Как и в блок-схемах, ширина почти не меняется: конечные автоматы растут вниз. Когда жизненный цикл длинный и слабо ветвится, обычное решение — написать `direction LR` внутри диаграммы.

И stateDiagram, и stateDiagram-v2 рисуются — и это ловушка

Часто пишут, что без `stateDiagram-v2` ничего не нарисуется. В 11.12.2 это неправда: оба ключевых слова рисуются без ошибок. Разница в качестве раскладки, особенно для составных и параллельных состояний, и при использовании старого варианта никакого предупреждения нет. Если составное состояние выглядит тесным, а стрелки идут странными путями, проверьте, каким ключевым словом вы открыли диаграмму, прежде чем переписывать её.

Подписи — это HTML, поэтому экспорт в PNG перерисовывает

Как и в блок-схемах, диаграммах классов и ER, подписи состояний рисуются внутри `<foreignObject>` в SVG. Браузеры отказываются растрировать это на canvas, поэтому экспорт в PNG на этом сайте сначала перерисовывает диаграмму подписями обычным SVG-текстом. PNG получается правильным и в полном размере; типографика лишь чуть отличается от экранной.

Тема меняет цвета, но никогда — геометрию

Светлая и тёмная темы дают одинаковый viewBox для одного и того же исходника, так что конечный автомат не может перекомпоноваться при смене темы.

Когда лучше взять другую диаграмму

Если ваши подписи — глаголы: проверить, отправить, повторить, — вы описываете процесс, а не жизненный цикл, и честный выбор здесь блок-схема. Самый ясный сигнал: вы не можете ответить на вопрос «что именно находится в этом состоянии?».

Если у нескольких компонентов свой жизненный цикл, а интересно как раз их взаимодействие, лучше сделать по диаграмме состояний на компонент плюс диаграмму последовательности для обмена, чем один гигантский автомат.

А если каждое состояние связано с каждым, диаграмма превратится в клубок, как её ни рисуй. Обычно это значит, что то, что вы назвали состояниями, на самом деле свободно сочетающиеся признаки; в таком случае таблица допустимых сочетаний скажет куда больше, чем картинка.

Другие типы диаграмм

Автор Dominik Malsch · Обновлено:

Открыть редактор →