Переход с обычных форм на управляемые часто вызывает вопросы у разработчиков, особенно когда речь заходит о визуализации данных. В обычных формах мы могли просто набросать декорации (фигуры, линии) непосредственно на полотно формы. В управляемых формах подход изменился: теперь форма — это логическое описание интерфейса, а визуальное проектирование схем вынесено в отдельные инструменты. Разберем подробно, как реализовать интерактивный план помещений или любую другую графическую схему.
Это основной и наиболее простой способ, позволяющий визуально спроектировать схему в конфигураторе. Основная идея заключается в том, что сама схема хранится в метаданных как макет, а на форме отображается лишь ее копия, загруженная в специальный реквизит.
Шаг 1. Создание макета. Сначала нам необходимо создать «чертеж». Для этого в дереве конфигурации (или в конкретном объекте, например, обработке) добавим новый макет. В качестве типа макета выберем Графическая схема. Откроется редактор, напоминающий графический редактор: здесь можно рисовать прямоугольники, линии, добавлять текст и картинки. Рассмотрим важный нюанс: каждому объекту (например, кабинету на плане), с которым мы хотим взаимодействовать, нужно присвоить уникальное Имя в палитре свойств. Это позволит нам в дальнейшем программно менять цвет этого объекта или понимать, по какому именно кабинету кликнул пользователь.
Шаг 2. Подготовка управляемой формы. На самой управляемой форме нам нужно создать реквизит, который будет хранить данные схемы. Создадим реквизит с типом ГрафическаяСхема (не путайте с картинкой). После этого перетащим этот реквизит в окно элементов формы. Система автоматически создаст элемент типа Поле графической схемы.
Шаг 3. Программная инициализация. Теперь нам нужно «склеить» макет и форму. Поскольку работа с макетами происходит на сервере, напишем соответствующий код:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем макет из метаданных нашей обработки
МакетСхемы = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ПланКабинетов");
// Копируем содержимое макета в реквизит формы
ЭтаФорма.РеквизитГрафическаяСхема = МакетСхемы;
КонецПроцедуры
Просто отобразить схему — это только половина задачи. Разберем, как сделать её «живой». Например, нам нужно, чтобы при нажатии на кабинет открывался отчет по сотрудникам, а сам кабинет окрашивался в красный цвет, если он переполнен.
Обработка клика (событие Выбор). У элемента формы Поле графической схемы есть событие Выбор. Проанализируем, как оно работает. В параметрах события передается выбранный элемент схемы. Мы можем проверить его имя и выполнить действие:
&НаКлиенте
Процедура ГрафическаяСхемаВыбор(Элемент, ВыбранныйОбъект, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Проверяем, что пользователь нажал на значимый объект, а не на пустое место
Если ВыбранныйОбъект <> Неопределено Тогда
ИмяКабинета = ВыбранныйОбъект.Имя;
Сообщить("Вы выбрали кабинет № " + ИмяКабинета);
// Здесь можно вызвать открытие формы или выполнить другой код
КонецЕсли;
КонецПроцедуры
Динамическое изменение свойств. Мы можем обходить все элементы схемы программно. Например, раскрасим все кабинеты в зависимости от их статуса. Для этого нужно понимать, что реквизит формы типа ГрафическаяСхема — это коллекция объектов.
&НаСервере
Процедура ОбновитьЦветаКабинетов()
Схема = ЭтаФорма.РеквизитГрафическаяСхема;
Для Каждого ТекущийЭлемент Из Схема.Элементы Цикл
// Ищем только декорации (прямоугольники), пропуская линии и текст
Если ТипЗнч(ТекущийЭлемент) = Тип("ДекорацияГрафическойСхемы") Тогда
// Предположим, имя элемента соответствует номеру кабинета в базе
Если КабинетЗанят(ТекущийЭлемент.Имя) Тогда
ТекущийЭлемент.ЦветФона = ЦветаСтиля.ОсобыйТекстНизкийПриоритет;
Иначе
ТекущийЭлемент.ЦветФона = ЦветаСтиля.ЦветФонаФормы;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Иногда расположение объектов заранее неизвестно (например, складские ячейки, которые могут добавляться). В этом случае мы можем построить схему полностью «с нуля» кодом. Выясним, как это реализовать.
Для создания объектов используются методы Элементы.Добавить(). Нам необходимо рассчитывать координаты X и Y, а также ширину и высоту каждого блока. Рассмотрим пример создания одного блока:
&НаСервере
Процедура СоздатьЭлементСхемыПрограммно()
Схема = ЭтаФорма.РеквизитГрафическаяСхема;
НовыйОбъект = Схема.Элементы.Добавить(Тип("ДекорацияГрафическойСхемы"));
НовыйОбъект.Имя = "Кабинет_101";
НовыйОбъект.Текст = "Отдел продаж";
// Установка координат (в пунктах)
НовыйОбъект.Лево = 50;
НовыйОбъект.Верх = 50;
НовыйОбъект.Ширина = 100;
НовыйОбъект.Высота = 80;
НовыйОбъект.ЦветФона = WebЦвета.СветлоЗеленый;
КонецПроцедуры
Такой подход позволяет генерировать сложные карты объектов на лету, основываясь на данных из справочников или регистров сведений.
Если стандартных возможностей ГрафическойСхемы недостаточно (например, нужны скругленные углы, сложные градиенты, анимация при наведении или плавное масштабирование), профессионалы часто используют Поле HTML документа в сочетании с форматом SVG.
Проанализируем преимущества этого метода:
window.external (или File.click в веб-клиенте).Хотя этот метод требует знаний HTML/CSS, он позволяет создавать интерфейсы уровня современных веб-приложений, что значительно повышает удобство работы пользователя с графическими планами.
Если вы хотите позволить пользователю самому передвигать элементы на схеме в режиме «1С:Предприятие», вам потребуется сохранить итоговый результат. Для этого используется механизм сериализации. Графическую схему можно сохранить в XML строку и записать в базу данных (например, в реквизит с типом ХранилищеЗначения).
Разберем пример сохранения:
&НаСервере
Процедура СохранитьСхемуВБазу()
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЭтаФорма.РеквизитГрафическаяСхема);
СтрокаXML = ЗаписьXML.Закрыть();
// Далее записываем СтрокаXML в ресурс регистра или реквизит справочника
КонецПроцедуры
Подведем итог: для реализации графической схемы на управляемой форме забудьте о рисовании на самой форме. Используйте макеты для статичных планов, программный обход коллекции Элементы для раскраски и интерактивности, а для продвинутых визуальных эффектов посмотрите в сторону SVG внутри HTML.