Перейти к содержимому
Поиск
Разработка

Drawflow: 12 схем, редактор нод и готовый JavaScript

12 собственных схем на Drawflow: ноды и связи, большой режим редактора, модули, reroute, импорт и экспорт JSON, готовый код и автономный HTML.

Александр Некрасов
Drawflow: редактор нод, связи и JavaScript на тёмно-бирюзовом фоне

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

Drawflow от Jero Soler предоставляет редактор нод и связей на обычном JavaScript без обязательных runtime-зависимостей. В нашей мастерской используется настоящая библиотека версии 0.0.60, а сценарии, панели управления, проверка импорта и учебный вычислитель написаны для этой статьи.

Что делает Drawflow, а что остаётся вашему приложению

Библиотека отвечает за перемещение нод, входы и выходы, соединения, масштабирование, reroute-точки, модули и сериализацию графа. Эти возможности и их API описаны в README Drawflow.

Не путайте редактор графа с движком автоматизации. Линия от «Заказа» к «Оплате» сама по себе не создаёт платёж: интерпретация узлов, вызовы API, авторизация, очередь задач и обработка ошибок относятся к вашему приложению, а не к перечисленным методам редактора.

Все бизнес-сценарии ниже являются учебными схемами без подключённых CRM, ботов и платёжных сервисов. Реально вычисляется только отдельный числовой пример: небольшой собственный обработчик читает связи и считает результат.

Живая мастерская: 12 собственных схем

Начните с «Первой цепочки»: перетащите среднюю ноду, измените название и создайте новое соединение. Круг справа является выходом, круг слева входом; для соединения протяните линию от выхода к входу или воспользуйтесь панелью «Связи без перетаскивания».

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

Ссылка «В отдельной вкладке» открывает выбранный исходный пример на всю ширину вкладки. Для переноса именно своей отредактированной версии скачайте HTML или JSON: они содержат текущее состояние, а не исходный шаблон.

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

Что попробовать в каждом примере

  • Первая цепочка: источник, обработка и результат. Освойте перемещение, выбор узла, создание и удаление связи.
  • Разбор заявок: условие с двумя выходами. Первый маршрут ведёт к менеджеру, второй к уточнению данных.
  • Обработка заказа: две ветки сходятся перед доставкой. Переименуйте шаги под свою предметную область.
  • Ветки чат-бота: три варианта ответа из одной ноды. Сравните несколько выходов и несколько связей из одного выхода.
  • Публикация материала: редакционный маршрут с возвратом на доработку. Цикл допустим как рисунок процесса, но требует отдельного смысла при выполнении.
  • Подготовка данных: два источника объединяются перед проверкой. Добавьте третий вход и новый источник.
  • Успех и ошибка: положительный результат и повторная попытка. Это визуальная модель, а не работающий сетевой запрос.
  • Параллельные ветки: одно событие связано с тремя действиями. Drawflow рисует fan-out, но не планирует параллельные задачи.
  • Числовой конвейер: два числа складываются, сумма умножается на коэффициент. Измените значение и запустите наш учебный расчёт.
  • Несколько портов: маршрутизатор с двумя входами и тремя выходами. Добавляйте и удаляйте порты, наблюдая за связями.
  • Разделение на модули: основная схема Home и отдельная схема Errors. Переключайтесь между ними и скачайте общий JSON.
  • Маршрут связи: заранее расставленные reroute-точки. Переместите их и добавьте новые двойным щелчком по линии.

Открыть числовой конвейер ↑ · Попробовать модули ↑ · Настроить маршрут связи ↑

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

Быстрый старт: контейнер, стили и две ноды

Для vanilla-JavaScript варианта достаточно подключить JavaScript и CSS, создать контейнер и вызвать start(); варианты NPM и CDN приведены в инструкции по установке. Здесь фиксируем версию 0.0.60, чтобы пример не менялся из-за обновления зависимости.

<link rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/drawflow@0.0.60/dist/drawflow.min.css">
<script src="https://cdn.jsdelivr.net/npm/drawflow@0.0.60/dist/drawflow.min.js"></script>

<div id="drawflow" style="width:100%; height:520px"></div>
<script>
const editor = new Drawflow(document.getElementById('drawflow'));
editor.reroute = true;
editor.start();

const source = editor.addNode(
  'source', 0, 1, 60, 120, 'source',
  { title: 'Событие' },
  '<label>Название <input df-title></label>'
);
const result = editor.addNode(
  'result', 1, 0, 390, 120, 'result',
  { title: 'Результат' },
  '<label>Название <input df-title></label>'
);
editor.addConnection(source, result, 'output_1', 'input_1');
</script>

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

Если приложение собирается через NPM, используйте тот же зафиксированный пакет. CSS нужно импортировать отдельно, как показано в документации.

npm install drawflow@0.0.60

// В модуле приложения:
import Drawflow from 'drawflow';
import 'drawflow/dist/drawflow.min.css';

Данные ноды и переиспользуемые шаблоны

Атрибуты df-* синхронизируют поля input, textarea и select с объектом data ноды; библиотека также поддерживает вложенные атрибуты и contenteditable (Drawflow: Nodes). Например, df-title связан с data.title, а df-settings-channel с data.settings.channel.

const html = `
  <label>Название <input df-title></label>
  <label>Канал <input df-settings-channel></label>
`;
const id = editor.addNode(
  'notification', 1, 1, 120, 80, 'notification',
  { title: 'Уведомление', settings: { channel: 'email' } },
  html
);

editor.on('nodeDataChanged', nodeId => {
  console.log(editor.getNodeFromId(nodeId).data);
});

editor.updateNodeDataFromId(id, {
  title: 'Уведомить редактора',
  settings: { channel: 'email' }
});

Не используйте data как место для API-ключей: экспорт графа включает данные узлов. В нашей мастерской поля содержат только учебные названия, описания и числа, а их редактирование можно увидеть в журнале событий.

Один HTML-шаблон можно зарегистрировать через registerNode и использовать при добавлении нескольких нод; такой способ описан в разделе Register Node. Данные каждого экземпляра при этом передаются отдельно.

const template = document.createElement('div');
template.innerHTML = '<label>Название <input df-title></label>';
editor.registerNode('task-template', template);

editor.addNode('task', 1, 1, 80, 80, 'task',
  { title: 'Проверить' }, 'task-template', true);
editor.addNode('task', 1, 1, 390, 80, 'task',
  { title: 'Сохранить' }, 'task-template', true);

В API также предусмотрена регистрация Vue-компонентов, а TypeScript-типы предлагаются отдельным пакетом @types/drawflow; конкретные примеры для Vue 2 и Vue 3 приведены в README. Эта статья и мастерская используют обычный JavaScript, без Vue и без TypeScript-сборки.

Порты, соединения и reroute

Порты называются input_1, input_2 и output_1, output_2; методы addConnection, addNodeInput, addNodeOutput и удаления перечислены в справочнике Drawflow. В нашей панели можно менять до шести входов и выходов у выбранного узла.

// idA и idB получены из addNode().
editor.addNodeInput(idB);
editor.addNodeOutput(idA);
editor.addConnection(idA, idB, 'output_2', 'input_2');

// Удалить конкретное соединение:
editor.removeSingleConnection(idA, idB, 'output_2', 'input_2');

// Удаление порта удаляет и связанные с ним соединения:
editor.removeNodeOutput(idA, 'output_2');

Reroute включается до start() или import(); двойной щелчок по связи создаёт точку, а двойной щелчок по точке удаляет её (Drawflow: Reroute). Это ручная коррекция пути, а не автоматическое построение маршрута в обход всех нод.

const editor = new Drawflow(container);
editor.reroute = true;
editor.curvature = 0.5;
editor.start();

В живом примере «Маршрут связи» несколько точек уже добавлены. Если соединение потерялось за пределами области, нажмите «Вписать» или разверните редактор; для точной работы увеличьте масштаб.

Режимы edit, fixed, view и модули

В режиме edit доступно редактирование, fixed фиксирует ноды, сохраняя доступ к их полям, а view предназначен для просмотра; эти различия указаны в таблице Editor options. В нашей оболочке дополнительно отключаются соответствующие кнопки и поля, чтобы режим был понятен не только по поведению полотна.

editor.editor_mode = 'edit';  // Редактирование графа
editor.editor_mode = 'fixed'; // Закреплённые ноды
editor.editor_mode = 'view';  // Просмотр

editor.zoom_in();
editor.zoom_out();
editor.zoom_reset();

Модули разделяют схемы на отдельные полотна, а базовый модуль называется Home; для переключения используется changeModule (Drawflow: Modules). Само наличие модуля Errors не означает, что основной граф вызовет его при ошибке: такое поведение надо описать в своей логике.

editor.addModule('Errors');
editor.changeModule('Errors');
// Здесь добавляются узлы обработки ошибок.
editor.changeModule('Home');

const allModules = editor.export();

В мастерской можно создать пустой модуль, добавить в него узлы и переключиться обратно. Кнопка «Очистить модуль» затрагивает только текущую схему и требует подтверждения; «Вернуть пример» заменяет весь набор модулей исходным примером.

Живой расчёт: граф отдельно, выполнение отдельно

Откройте «Числовой конвейер» и нажмите «Рассчитать». В исходной схеме числа 12 и 8 поступают в сумму, затем результат умножается на 3: итог равен 60.

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

// Идея обработчиков, не полный обход графа:
const handlers = {
  number: node => Number(node.data.value),
  sum: (_node, values) => values.reduce((a, b) => a + b, 0),
  multiply: (node, values) => values[0] * Number(node.data.value),
  result: (_node, values) => values[0]
};

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

В реальном проекте потребуется более строгая модель: типы портов, правила допустимых связей, порядок выполнения, отмена, повторы и политика обработки циклов. Кнопка «Скачать HTML» сохраняет редактор и граф, но не включает этот учебный вычислитель и панели мастерской.

JSON, автономный HTML и безопасный импорт

Методы export() и import() сохраняют и восстанавливают данные редактора; в документированном формате есть модули, ноды, HTML, координаты и связи (Drawflow: Export / Import). Это удобный формат хранения состояния, но не основание доверять любому загруженному файлу.

// Для своего доверенного состояния:
const saved = editor.export();
const json = JSON.stringify(saved, null, 2);

// В рабочем приложении сначала проверьте структуру и шаблоны.
editor.import(JSON.parse(json));

Наш импорт принимает JSON этой мастерской с известными типами узлов. Он проверяет структуру, координаты и ссылки между портами, пересобирает входящие связи и заменяет HTML, CSS-классы и режим шаблона собственными значениями; произвольный HTML из файла не отображается.

Ограничения мастерской: файл до 250 КБ, до 200 узлов, 500 связей, 10 модулей и шести портов каждого вида на ноду. Это наши защитные ограничения, не заявленные пределы библиотеки.

  • JSON: текущее состояние всех модулей, удобное для сохранения и повторного импорта.
  • JavaScript: код запуска редактора с текущим графом; требует заранее подключённые Drawflow, CSS и контейнер.
  • CSS: оформление мастерской и узлов поверх стандартного drawflow.min.css.
  • HTML: автономная страница со встроенными библиотекой, стилями и схемой, переключением модулей, режимами, масштабом и повторным экспортом JSON.

Данные мастерской находятся в памяти вкладки и не отправляются ею на сервер. Перезагрузка удалит несохранённые изменения; это описание редактора, а не политики аналитики всего сайта.

События и практические ограничения

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

editor.on('nodeCreated', id => console.log('Узел:', id));
editor.on('nodeMoved', id => console.log('Перемещение:', id));
editor.on('connectionCreated', connection => {
  console.log('Связь:', connection);
});
editor.on('moduleChanged', name => console.log('Модуль:', name));

Проверяйте редактор на реальных размерах своих схем: большое количество DOM-элементов, полей и соединений может влиять на отзывчивость. Здесь нет обещания определённого FPS или универсального лимита производительности; начинайте с нужного сценария, а не с максимального числа нод.

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

Версия 0.0.60 выбрана для воспроизводимости; историю изменений можно сверить на странице релизов. Проект распространяется по MIT, а текст лицензии автора сохранён вместе с библиотекой в мастерской.

Когда Drawflow стоит брать в проект

Drawflow имеет смысл рассмотреть, если вам нужен встраиваемый визуальный редактор, обычные HTML-поля внутри нод и сериализация собственной схемы без обязательного UI-фреймворка. Он даёт основу взаимодействия, но оставляет предметную модель и выполнение за вашим кодом.

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

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