Plank help · updated 2026-08-13

Схемы в документе

Когда рисунок лучше абзаца или таблицы и каким требованиям должна отвечать встроенная SVG-схема в документе Plank: фирменные токены, один файл, светлая и тёмная тема, доступность для скринридера.

Agents: fetch the raw markdown of this page at /ru/help/diagrams.md

Схемы в документе

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

Но большинство выводов устроены иначе. Эта страница настолько же о том, когда не рисовать, насколько о том, как рисовать.

Схема живёт внутри стандартного листа документа — как встроенный SVG в том же файле, что и всё остальное. Для количественных данных есть своя страница: Дашборды и графики. График отвечает на вопрос «сколько», схема — на вопрос «как это устроено».

Рисуйте, только если это лучше остальных вариантов

Спросите себя по порядку:

  1. Хватит ли одного предложения? «Счёт проходит регистрацию, сверку, согласование и проведение». Это предложение. Напишите его.
  2. Хватит ли таблицы? Всё, что состоит из именованных строк и сопоставимых колонок, — это таблица, а таблицу можно искать, копировать и переводить без перерисовки. Если то же самое говорит таблица из трёх колонок, выигрывает таблица.
  3. Важна ли сама форма? Если значение несёт то, что шаг возвращается назад, что один блок содержит три других, что два пути расходятся и снова сходятся или что один отрезок в шесть раз длиннее остальных, — таблице пришлось бы это проговаривать, а рисунок просто показывает.

Рисуйте, если на третий вопрос ответ «да». Конкретно: путь или последовательность, где смысл несёт порядок или передача; структура, где смысл несёт вложенность; распределение долей между этапами, где один занимает почти всё; состояния и переходы между ними; решение с ветвлением; пересечение множеств.

Не рисуйте:

  • перечень объектов — это список или таблица;
  • простое «было / стало» — это две колонки;
  • одну подписанную рамку — это предложение с бордюром;
  • то, что придётся объяснять под рисунком абзацем, который говорит ровно то же самое.

Полезный признак: если абзац, который вы только что написали, перечисляет («сначала это, потом это, а оттуда обратно…»), схема делает работу. Если он описывает — не делает.

Проверка на удаление, до того как рисовать. Каждый узел — отдельная мысль; два узла, которые всегда идут вместе, — это один узел. Каждая связь несёт информацию; если отношение и так понятно из расположения, линию нужно убрать. Рисунок готов не тогда, когда в нём есть всё, а тогда, когда из него больше нечего убрать.

Требования

Шесть правил. Правила 1, 2, 4 и 5 проверяются механически — см. Проверка, — поэтому это не вопрос вкуса и не то, что нужно помнить. Правило 3 проверяется только там, где столкновение уже произошло, а правило 6 не проверяется вовсе: эти два остаются на вас.

  1. Цвет берётся из токенов листа. fill="var(--ink)", stroke="var(--mist)", fill="var(--blue)". Никогда не буквальный #0a0a0f. Документ Plank — это один файл, светлая и тёмная тема которого следуют за окружением, и делается это через CSS-переменные. Буквальный цвет верен в той теме, в которой вы рисовали, и неверен — обычно невидим — в другой. Это самый частый дефект схемы, скопированной откуда угодно ещё: большинство инструментов зашивают hex прямо в SVG и выпускают отдельный файл для тёмной темы, а этому фирменному стилю второй файл некуда положить.
  2. У SVG есть имя — либо он явно декоративный. У схемы есть role="img" и aria-labelledby="<slug>-title <slug>-desc". Её <title>первый дочерний элемент <svg>, до <defs>: программы чтения с экрана могут проигнорировать заголовок, стоящий позже. <desc> — одно предложение о том, что показывает схема тому, кто её не видит; описывайте содержание, а не фигуры. «Согласование держит счёт 6 дней из 11», а не «ряд прямоугольников с полосками внизу». SVG, который не несёт смысла (маркер, линейка, иконка рядом с текстом, который и так это говорит), получает aria-hidden="true". Других состояний нет: безымянный SVG объявляется как картинка, о которой ничего не сказано.
  3. Каждый id внутри схемы начинается с её слага. (Проверяется только при столкновении: уникальный id без префикса пройдёт — и сломается в тот день, когда рядом появится вторая схема.) Идентификаторы действуют на весь документ. Две схемы, вставленные из одного шаблона, приносят два маркера id="arrow", а url(#arrow) находит тот, что встретился первым, — вторая схема молча берёт стрелки первой, а с голым id="title" её ещё и объявят чужим именем.
  4. Схема масштабируется — и текст переживает это масштабирование. viewBox="0 0 W H" на <svg>, размер задаёт CSS. Без viewBox на телефоне рисунок обрежется. Ловушка в том, что SVG масштабирует и текст: viewBox шириной 760 внутри блока контента листа шириной 656 px отрисует каждую подпись с коэффициентом 0,86 — подпись в 12 px придёт как 10,3 px, а на телефоне как 5 px. Поэтому делайте viewBox шириной 656 (это самый широкий блок контента листа, то есть 1:1 на десктопе), а на узком экране пусть рисунок прокручивается, а не сжимается ниже порога читаемости.
  5. Файл остаётся одним файлом. Никаких <image href="https://…"> и вообще ничего внешнего. Рисуйте знак средствами SVG или вставляйте картинку как data:-URI. Внешняя ссылка становится пустотой в тот момент, когда файл переслали или открыли без интернета, — а это и есть большинство случаев.
  6. Текст остаётся текстом. (Не проверяется: отличить <path>, которым написано слово, от <path>, которым нарисован прямоугольник, нечем.) Элементы <text>, а не контуры и не картинка с буквами. Его должно быть можно выделить, найти поиском, перевести и прочитать при увеличении страницы.

Готовый блок

Добавьте эти правила в <style> листа:

/* В собственное правило листа нужно добавить `figure`, иначе рисунок после
   заголовка встанет на 8 px ниже, чем все остальные элементы. */
h2 + p, h2 + ul, h2 + figure { margin-top: 12px; }

figure.diagram { margin: 20px 0 0; overflow-x: auto; }
figure.diagram svg {
  display: block;
  width: 100%;
  min-width: 592px;   /* прокрутка вместо сжатия текста ниже порога */
  height: auto;
}
figure.diagram figcaption {
  margin-top: 10px;
  color: var(--muted);
  font-size: 13px;
}
.d-label { font-family: Inter, system-ui, sans-serif; font-size: 14px; font-weight: 600; }
.d-sub   { font-family: "JetBrains Mono", monospace; font-size: 13px; }
.d-edge  { font-family: "JetBrains Mono", monospace; font-size: 12px; letter-spacing: 0.06em; }

Эти три размера подобраны так, чтобы даже самый мелкий из них оставался не меньше 10 px при ширине 592 px — а уже она самая узкая, при которой рисунок вообще отрисовывается. Измерено: 14 / 13 / 12 на десктопе и 12,6 / 11,7 / 10,8 на телефоне.

И сам рисунок. Замените invoice-wait на собственный слаг везде, где он встречается: именно этот префикс не даёт двум схемам в одном документе столкнуться:

<figure class="diagram">
  <svg
    viewBox="0 0 656 184"
    role="img"
    aria-labelledby="invoice-wait-title invoice-wait-desc"
    xmlns="http://www.w3.org/2000/svg"
  >
    <title id="invoice-wait-title">Где ждёт счёт поставщика</title>
    <desc id="invoice-wait-desc">
      Пять этапов от поступления счёта до оплаты и полоса под ними,
      показывающая длительность каждого. Согласование у владельца ЦФО
      занимает 6,1 дня из 11,2 — больше, чем остальные четыре этапа вместе.
    </desc>

    <defs>
      <!-- По одному маркеру на цвет: маркер красится сам и НЕ наследует
           обводку линии, которая его использует. -->
      <marker id="invoice-wait-arrow" markerWidth="8" markerHeight="6"
              refX="7" refY="3" orient="auto">
        <polygon points="0 0, 8 3, 0 6" fill="var(--muted)" />
      </marker>
      <marker id="invoice-wait-arrow-focus" markerWidth="8" markerHeight="6"
              refX="7" refY="3" orient="auto">
        <polygon points="0 0, 8 3, 0 6" fill="var(--blue)" />
      </marker>
    </defs>

    <!-- Связи рисуются первыми, чтобы узлы легли поверх них. -->
    <line x1="116" y1="72" x2="144" y2="72" stroke="var(--muted)"
          stroke-width="1" marker-end="url(#invoice-wait-arrow)" />
    <line x1="248" y1="72" x2="276" y2="72" stroke="var(--blue)"
          stroke-width="1.5" marker-end="url(#invoice-wait-arrow-focus)" />

    <!-- Обычный узел. Ряд несёт ПОСЛЕДОВАТЕЛЬНОСТЬ и больше ничего:
         доли несёт полоса, значения — таблица. -->
    <rect x="12" y="48" width="104" height="48" rx="6"
          fill="var(--surface)" stroke="var(--muted)" stroke-width="1" />
    <text class="d-label" x="64" y="77" fill="var(--ink)"
          text-anchor="middle">Регистрация</text>

    <!-- Смысловой центр. Один на схему, максимум два. -->
    <rect x="276" y="48" width="104" height="48" rx="6"
          fill="var(--blue-soft)" stroke="var(--blue)" stroke-width="1.5" />
    <text class="d-label" x="328" y="70" fill="var(--blue-on)"
          text-anchor="middle">Согласование</text>
    <text class="d-sub" x="328" y="87" fill="var(--blue-on)"
          text-anchor="middle">6,1 д</text>

    <!-- Те же этапы одной полосой, в масштабе. Фокусный сегмент ещё и ВЫШЕ
         остальных, поэтому аргумент переживает серую печать. -->
    <text class="d-edge" x="12" y="124" fill="var(--muted)">СРОК В ДНЯХ, В МАСШТАБЕ</text>
    <rect x="12" y="138" width="20" height="8" rx="2" fill="var(--muted)" />
    <rect x="84" y="132" width="342" height="20" rx="2" fill="var(--blue)" />
    <text class="d-sub" x="255" y="172" fill="var(--blue-on)"
          text-anchor="middle">6,1 из 11,2 дня</text>
  </svg>
  <figcaption>
    Медиана дней по этапам, II квартал 2026 года. На согласование приходится
    54 % общего срока — почти вдвое больше следующего по величине этапа.
  </figcaption>
</figure>

Это фрагмент — два узла из пяти и два сегмента полосы из пяти, чтобы форма читалась прямо здесь. Готовый документ целиком, из которого он взят (лист, показатели, схема полностью, таблица, решение), лежит в репозитории: apps/website/src/content/help/assets/example_diagram_deliverable.html — он же служит образцом для описанных ниже проверок, так что проходит их гарантированно. Если вы вставляете фрагмент, перепишите <desc> под то, что нарисовали на самом деле: описание пяти этапов над рисунком из двух — это ровно та ошибка, ради которой существует правило 2.

Мастерство — то, чего не увидит ни одна проверка

Один смысловой центр. Акцент (--blue / --blue-soft / --blue-on) отмечает то единственное, ради чего схема нарисована. Всё остальное — --ink, --graphite, --muted, --mist. Выделить четыре узла — значит не решить, какой из них главный, и читатель не получит никакого сигнала вовсе.

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

Связи — это и есть мастерство. И именно по ним видно сгенерированную схему:

  • Прямоугольные изломы, а не диагонали. Прямая <line> уместна, когда оба конца лежат на одной вертикали или горизонтали; во всех остальных случаях линия поворачивает.
  • Никакие две связи не идут по одному пути и не накладываются друг на друга. Если двум стрелкам нужен один маршрут, компоновка слишком тесная — сдвиньте узел.
  • Если из одной грани блока выходит несколько связей, дайте каждой свою точку крепления, примерно в 12 px друг от друга. Стрелка, спрятанная за другой стрелкой, — это неудавшийся рисунок.
  • Связь не должна проходить за блоком, который не является ни её началом, ни её концом. Проложите её иначе.
  • Подпись к стрелке ставится на непрозрачный <rect fill="var(--surface)">, и между этим прямоугольником и линией остаётся зазор 6–10 px: подпись, лежащая на своей стрелке, прячет то, что подписывает. Никогда не поворачивайте текст подписи вертикально.
  • Рисуйте связи до узлов, чтобы блоки закрыли концы линий.

Линия, которая несёт смысл, — это не тонкая линейка. Здесь измерено, а не почувствовано. --mist — токен границ в листе — даёт контраст 1,3:1 к фону листа в обеих темах. Для линейки, разделяющей два блока текста, это верно; для всего, что читатель должен видеть, — края узла, связи, полосы в масштабе — нет: это графические объекты, и им нужно 3:1. --muted — самый светлый токен, который этот порог берёт (4,95:1 в светлой теме, 5,51:1 в тёмной); --ink и --graphite берут его с большим запасом, но в 1 px читаются уже как насыщенность текста, а не как линия. --faint (2,4:1 в светлой) и --stone не берут его вовсе. --blue берёт порог и на фоне листа, и на --blue-soft. Отсюда:

Токен
Края узлов, связи, наконечники стрелок, полосы в масштабе--muted
Смысловой центр, его связь, его полоса--blue (заливка --blue-soft, текст --blue-on)
Названия узлов--ink
Подписи, единицы, текст легенды--muted
Разделитель под легендой — и больше ничего--mist

Цвет никогда не единственный канал. --blue против --muted — это 1,1:1 по яркости, поэтому две полосы, отличающиеся только оттенком, в оттенках серого превращаются в одну, а рекомендованный способ получить PDF документа — это печать. Дайте смысловому центру второе, нецветовое отличие: в готовом примере фокусная полоса выше остальных (20 px против 8), а обводка фокусного узла — 1,5 px против 1. Тогда аргумент переживёт чёрно-белый принтер, проектор и читателя с нарушением цветовосприятия.

Легенда — внизу, вне рисунка, и только если она рисунку нужна: горизонтальная полоса под тонкой линией, а не подпись, плавающая между узлами; увеличивайте высоту viewBox, вместо того чтобы поджимать сам рисунок. Прежде чем добавлять легенду, проверьте, не окажется ли она четвёртым местом, где написано одно и то же: если фокусный узел уже подписан, фокусная полоса уже прокомментирована, а подпись под рисунком уже всё называет, легенда «синим — медленный этап» — это украшение. В готовом примере легенды нет именно поэтому.

Шрифт. Названия — Inter (.d-label); числа, коды, порты и единицы — JetBrains Mono (.d-sub, .d-edge). Ничего мельче 10 px, а если элемент несёт число, по которому читатель принимает решение, — не мельче 11 px. Это документ для человека за столом, а не технический плакат.

Геометрия. Координаты, размеры и отступы — по сетке 4 px; скругление 4–8 px; тонкие линии в 1 px. Два намеренных исключения, оба есть в готовом примере: обводка 1,5 px отмечает смысловой центр (см. правило о каналах выше), а полоса, построенная в масштабе, задаётся данными, а не сеткой — считайте от значение / сумма × (W − зазоры) и округляйте только ради того, чтобы ряд в сумме дал W − зазоры, а не ради кратности четырём. Округлить масштабную полосу до сетки — значит сломать единственное, ради чего она нарисована; в готовом примере пять сегментов равны 20, 48, 342, 32 и 180 для 0,4, 0,9, 6,1, 0,6 и 3,2 дня, и три из них лежат вне сетки, потому что туда их поставили данные. Никаких теней и градиентов: эту работу здесь делают границы. Документы говорят негромко.

Проверка

Схемы проверяет тот же инструмент, который вычитывает документ:

mkdir -p /workspace/scripts/deck
curl -sSfL -o /workspace/scripts/deck/plank_deck_qa.py https://plank.md/help/assets/plank_deck_qa.py
python3 /workspace/scripts/deck/plank_deck_qa.py отчёт-по-кредиторке.html

Ошибки — они дают ненулевой код возврата и останавливают цикл «собрать → проверить → исправить»: заливка буквальным цветом вместо токена (включая литерал, спрятанный в запасном значении var(), и литерал в общей таблице стилей, если её селектор попадает в схему); SVG без имени и без пометки «декоративный»; <title>, который не первый или пуст, и отсутствующий <desc>; aria-labelledby, который не указывает на собственные <title> и <desc>; голый id или id, уже занятый где-то ещё в документе; ссылка на что угодно за пределами файла — соседний chart.png ровно так же, как адрес https; и незакрытый <svg>.

Предупреждения — сообщаются, но не фатальны: отсутствующий viewBox. Читайте отчёт, а не только код возврата.

Инструмент работает на любом .html-документе, в том числе полностью английском, и встраивается в тот же цикл, что и проверка русской типографики на той странице.

Чего он не видит — это самого рисунка: прослеживаются ли связи, читается ли компоновка, не следовало ли из девяти узлов сделать две схемы и, главное, стоило ли вообще что-то рисовать. Если то же самое говорит таблица, выигрывает таблица, и об этом вам не скажет ни одна проверка.

В презентации и в PDF

  • HTML-документ или дашборд — это дом схемы. Встроенный SVG, один файл, обе темы.
  • PDF — печать HTML-документа из браузера. SVG векторный, поэтому текст и тонкие линии остаются чёткими при любом увеличении; схема, выгруженная в PNG, — нет.
  • Презентация .pptx — слайды состоят из настоящих редактируемых фигур, поэтому вставить в них SVG нельзя. Для линейного пути у обоих сборщиков есть process(...) — и в .pptx, и в HTML-презентации; для чего-то сложнее собирайте презентацию в HTML и печатайте в PDF, где этот же блок работает без изменений. Какой из двух форматов нужен вашей презентации, написано на странице Презентации.

Благодарность

Правила из раздела Мастерство — предел сложности, грамматика связей, требования к доступности SVG, проверка «а не подойдёт ли таблица» — адаптированы из проекта diagram-design Кэтрин Лавери и используются по лицензии MIT. Палитра, шрифты, работа с темами и проверки здесь — собственные наработки Plank; оригинал выпускается со светлым фирменным стилем в других гарнитурах и в исходном виде с брендом Plank несовместим.