Разработка сложных бизнес-процессов часто требует визуализации связей между объектами, будь то маршруты согласования, иерархия подчинения или логистические цепочки. В системе 1С:Предприятие для этих целей существует мощный инструмент — объект метаданных ГрафическаяСхема, позволяющий отобразить структуру данных в виде узлов и связей. Это не просто рисование линий, а программное создание интерактивных диаграмм, напрямую связанных с информацией в базе.
Многие разработчики ошибочно полагают, что для построения графиков нужны внешние библиотеки или сложные сторонние компоненты. На самом деле, встроенные средства платформы позволяют создавать полноценные графы прямо в форме документа или отчета. Понимание принципов работы с вершинами и ребрами открывает возможности для создания удобных интерфейсов, где пользователь может видеть структуру задачи или зависимость элементов в реальном времени.
В этой статье мы подробно разберем алгоритм создания графа, от объявления объектов до настройки внешнего вида связей. Вы узнаете, как программно добавлять узлы, позиционировать их на поле и связывать линиями, а также как сделать схему динамической, реагирующей на изменения данных.
Подготовка формы и объекта ГрафическаяСхема
Первым шагом для реализации визуализации является добавление необходимого реквизита в форму. В конфигураторе откройте нужную форму и добавьте новый реквизит типа ГрафическаяСхема. Назовите его, например, СхемаГрафа. Этот объект будет служить холстом, на котором мы будем размещать вершины и рисовать связи между ними.
После добавления реквизита необходимо разместить элемент визуализации на самой форме. Перетащите поле СхемаГрафа из палитры полей в область формы. Желательно выделить под него значительное пространство, так как графы могут занимать много места. Важно установить свойство Масштаб в значение Авто или Вместить, чтобы схема корректно отображалась на экранах разного разрешения.
Для управления схемой из кода нам понадобится переменная в модуле формы. Объявите её в секции переменных:
Перем СхемаГрафОбъект;
В процедуре ПриСозданииНаСервере или ПриОткрытии необходимо инициализировать этот объект. Мы присваиваем реквизиту формы новый экземпляр объекта ГрафическаяСхема. Это критически важный этап, без которого любые попытки добавить элементы приведут к ошибке выполнения.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
СхемаГрафОбъект = Объекты.ГрафическаяСхема.Создать();
Элементы.СхемаГрафа.Значение = СхемаГрафОбъект;
КонецПроцедуры
⚠️ Внимание: Объект ГрафическаяСхема является тяжеловесным. Не создавайте его заново при каждом изменении данных формы, если в этом нет острой необходимости. Лучше модифицировать существующий экземпляр, удаляя старые элементы и добавляя новые, чтобы избежать мерцания интерфейса.
Используйте свойство "ТолькоПросмотр" для элемента формы, если пользователю не нужно перетаскивать узлы мышью. Это улучшит производительность отрисовки при большом количестве элементов.
Создание вершин графа (Узлов)
Вершина графа, или узел, является основным элементом схемы. В 1С каждый узел представляется объектом ЭлементГрафическойСхемы. Чтобы нарисовать граф, нужно программно создать коллекцию таких элементов и добавить их в схему. Каждый узел может иметь уникальный идентификатор, текст, цвет и форму.
Рассмотрим процесс добавления узла. Мы создаем новый элемент, задаем его координаты и привязываем к нему данные. Например, если мы строим граф сотрудников, ключом узла может быть ссылка на справочник ФизическиеЛица. Это позволит в дальнейшем быстро находить нужный узел по данным.
Процедура ДобавитьВершину(Ключ, Текст, X, Y)
НовыйЭлемент = СхемаГрафОбъект.Элементы.Добавить();
НовыйЭлемент.Идентификатор = Ключ;
НовыйЭлемент.Текст = Текст;
НовыйЭлемент.ТипЭлемента = ТипЭлементаГрафическойСхемы.Прямоугольник;
// Установка позиции
НовыйЭлемент.Позиция.X = X;
НовыйЭлемент.Позиция.Y = Y;
НовыйЭлемент.Размер.Ширина = 150;
НовыйЭлемент.Размер.Высота = 50;
// Настройка внешнего вида
НовыйЭлемент.ЦветФона = Цвет.Белый;
НовыйЭлемент.ЦветГраницы = Цвет.Синий;
КонецПроцедуры
Важно учитывать систему координат. В 1С начало координат (0,0) находится в левом верхнем углу области схемы. Значения X и Y задаются в условных единицах, которые платформа конвертирует в пиксели в зависимости от масштаба. Для автоматического расположения узлов часто используют алгоритмы расстановки, чтобы они не накладывались друг на друга.
- 🔵 Идентификатор узла должен быть уникальным в пределах одной схемы, иначе возникнет конфликт при обращении к элементу.
- 🟢 ТипЭлемента может быть не только прямоугольником, но и эллипсом, ромбом или изображением, что полезно для семантического различия узлов.
- 🟠 Текст узла поддерживает перенос строк, что удобно для отображения длинных наименований объектов.
Построение связей (Ребер) между узлами
Сам по себе набор разрозненных узлов не является графом. Суть структуры заключается в связях — ребрах, которые показывают отношения между вершинами. В 1С связи создаются через объект СвязьЭлементаГрафическойСхемы. Для создания связи необходимо указать идентификаторы начального и конечного узлов.
Процесс создания связи выглядит следующим образом: мы обращаемся к коллекции Связи объекта схемы и добавляем новый элемент. Попытка создать связь по несуществующему идентификатору приведет к исключительной ситуации.
Процедура ДобавитьСвязь(КлючНачало, КлючКонец)
НоваяСвязь = СхемаГрафОбъект.Связи.Добавить();
НоваяСвязь.НачальныйЭлемент = КлючНачало;
НоваяСвязь.КонечныйЭлемент = КлючКонец;
// Настройка стиля линии
НоваяСвязь.ТипЛинии = ТипЛинииГрафическойСхемы.Сплошная;
НоваяСвязь.ТолщинаЛинии = 2;
НоваяСвязь.Цвет = Цвет.Черный;
// Добавление стрелки
НоваяСвязь.ЗавершениеЛинии = ЗавершениеЛинииГрафическойСхемы.Стрелка;
КонецПроцедуры
Существует возможность создавать направленные и ненаправленные связи. Для направленных графов, где важен порядок прохождения (например, маршрут документа), обязательно используется свойство ЗавершениеЛинии. Если граф отражает равноправные связи (например, родственные связи), стрелки можно убрать, сделав линию простой.
Одной из частых проблем является пересечение линий связи с самими узлами или другими линиями. Платформа 1С автоматически старается обходить узлы, но иногда требуется ручная настройка точек изгиба. Для этого используется коллекция Точки у объекта связи, где можно задать промежуточные координаты.
⚠️ Внимание: При удалении узла из графа все связанные с ним ребра должны быть удалены вручную или автоматически, в зависимости от логики вашей программы. Оставшиеся "висячие" связи, указывающие на несуществующий узел, могут вызвать ошибки при повторной отрисовке формы.
Алгоритмы автоматической расстановки элементов
Ручная расстановка координат X и Y приемлема только для статических схем с фиксированным количеством элементов. В реальных задачах данные динамичны, и жестко заданные координаты быстро приведут к наложению узлов друг на друга ("каша" на экране). Для решения этой задачи применяются алгоритмы автоматической компоновки.
Встроенных сложных алгоритмов типа "force-directed" в базовой поставке 1С нет, но можно реализовать упрощенные версии. Самый популярный подход — иерархическая расстановка (для деревьев) или сеточная. При иерархическом подходе мы вычисляем уровень вложенности узла и размещаем его на соответствующей горизонтальной линии.
Пример логики для простого дерева:
Процедура РасставитьДерево(Корень, Уровень, ОтступX, ОтступY)
// Вычисление позиции текущего узла
ПозицияX = Уровень * ОтступX;
ПозицияY = (СчетчикПоY[Уровень]) * ОтступY;
СчетчикПоY[Уровень] = СчетчикПоY[Уровень] + 1;
// Обновление координат существующего элемента
Элемент = СхемаГрафОбъект.Элементы.НайтиПоИдентификатору(Корень);
Если Элемент <> Неопределено Тогда
Элемент.Позиция.X = ПозицияX;
Элемент.Позиция.Y = ПозицияY;
КонецЕсли;
// Рекурсивный обход детей
Для Каждого Ребенок Из Дети[Корень] Цикл
РасставитьДерево(Ребенок, Уровень + 1, ОтступX, ОтступY);
КонецЦикла;
КонецПроцедуры
Более продвинутый метод — использование физических моделей, где узлы отталкиваются друг от друга как одноименно заряженные частицы, а связи действуют как пружины. Реализация такого алгоритма на встроенном языке 1С возможна, но требует значительных вычислительных ресурсов. Для больших графов (более 100 узлов) расчет позиции лучше выносить на сторону сервера или использовать предвычисленные координаты.
Оптимизация отрисовки
Если граф содержит сотни элементов, отключите свойство "Анимация" у элемента формы. Это ускорит первоначальное отображение схемы в несколько раз, пожертвовав плавностью перемещения.
Интерактивность и обработка событий
Статичная картинка полезна для отчетов, но настоящая мощь графов в 1С раскрывается при интерактивном взаимодействии. Пользователь должен иметь возможность кликнуть на узел, чтобы открыть карточку объекта, или перетащить связь, чтобы изменить маршрут. Для этого используются события элемента формы ГрафическаяСхема.
Основное событие — Выбор. Оно срабатывает, когда пользователь дважды кликает по узлу или связи. В обработчике этого события мы можем проанализировать, что именно было выбрано, и выполнить соответствующее действие, например, открыть форму элемента справочника.
&НаКлиенте
Процедура СхемаГрафаВыбор(Элемент, Выбор)
Если Выбор.Тип = ТипВыбораГрафическойСхемы.Элемент Тогда
// Получаем ключ, который мы записали в Идентификатор
КлючОбъекта = Выбор.Элемент.Идентификатор;
// Открытие объекта
ПараметрыФормы = Новый Структура("Ключ", КлючОбъекта);
ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта", ПараметрыФормы);
ИначеЕсли Выбор.Тип = ТипВыбораГрафическойСхемы.Связь Тогда
Сообщить("Выбрана связь между узлами");
КонецЕсли;
КонецПроцедуры
Также полезно событие НачалоИзменения и ОкончаниеИзменения, которые срабатывают при перетаскивании узлов пользователем. Это позволяет сохранять новую позицию узлов в базе данных, чтобы при следующем открытии схемы структура сохранилась в том виде, в котором её оставил пользователь.
- 🔴 Контекстное меню: Вы можете перехватить правый клик мыши и показать свое меню действий для конкретного узла.
- 🟣 Подсветка: При наведении мыши можно программно менять цвет узла, подсказывая пользователю, что элемент активен.
- 🟡 Фильтрация: Реализуйте поиск по графу, скрывая неподходящие узлы и оставляя только те, что соответствуют условию.
Сравнение методов визуализации в 1С
Выбор инструмента для отрисовки зависит от задачи. Помимо ГрафическойСхемы, разработчики часто используют обычные ТабличныеДокументы или внешние компоненты. Ниже приведена таблица, сравнивающая основные подходы к визуализации графов в экосистеме 1С.
| Метод | Гибкость настройки | Производительность | Интерактивность | Сложность внедрения |
|---|---|---|---|---|
| ГрафическаяСхема | Высокая | Средняя | Высокая (Drag&Drop) | Низкая (встроенный) |
| Табличный Документ | Средняя | Высокая | Низкая (только клик) | Средняя (рисуем фигурами) |
| Внешняя HTML-компонента | Максимальная | Зависит от браузера | Максимальная | Высокая (нужен JS) |
| Диаграмма (Chart) | Низкая | Высокая | Средняя | Низкая |
Как видно из таблицы, стандартная ГрафическаяСхема является золотой серединой для большинства задач внутри платформы. Она не требует знания JavaScript или подключения внешних библиотек, но при этом предоставляет достаточный API для построения сложных структур.
Для задач бизнес-моделирования внутри 1С предпочтительнее использовать встроенный объект ГрафическаяСхема, так как он обеспечивает нативную интеграцию с данными и событиями платформы без необходимости поддержки внешних зависимостей.
⚠️ Внимание: Интерфейс и свойства объекта ГрафическаяСхема могут незначительно отличаться в разных версиях платформы 1С:Предприятие (8.3.10, 8.3.20 и новее). Всегда проверяйте синтакс-помощник для вашей конкретной версии конфигурации перед использованием новых свойств.
Часто задаваемые вопросы (FAQ)
Можно ли экспортировать нарисованный граф в картинку?
Да, объект ГрафическаяСхема поддерживает метод ПолучитьКартинку(). Вы можете получить изображение схемы в формате BMP или JPG и сохранить его в файл, отправить по почте или прикрепить к документу. Однако качество экспорта может зависеть от текущего масштаба отображения.
Как сделать так, чтобы текст в узле переносился по словам?
Для этого необходимо установить свойство ПереносСтрок у элемента графической схемы в значение Истина. Также рекомендуется фиксировать ширину узла, чтобы система знала, на какой длине строки делать разрыв. Автоматическое расширение узла по ширине при переносе строк нужно рассчитывать вручную.
Почему граф тормозит при большом количестве элементов?
Отрисовка сотен векторных объектов в форме 1С — ресурсоемкая задача. Попробуйте отключить тени, градиенты и сгладивание линий. Также помогает группировка элементов: отображайте только верхний уровень иерархии, а детали подгружайте при раскрытии узла (ленивая загрузка).
Можно ли рисовать кривые линии (Безье) вместо прямых?
В стандартной ГрафическойСхеме тип линии обычно задается как прямой отрезок или ломаная под прямым углом. Плавные кривые Безье напрямую не поддерживаются в базовом функционале без использования обходных путей или внешних компонентов, хотя в новых версиях платформы появляются дополнительные опции сглаживания.
Как сохранить позицию узлов после закрытия формы?
Вам нужно записать координаты X и Y каждого узла в регистр сведений или в дополнительное поле объекта, который этот узел представляет. Делать это следует в событии ПриЗакрытии формы или при событии ОкончаниеИзменения схемы, если требуется автосохранение при перетаскивании.