Естественно начал с анализа уже готовых решений, наткнулся на это и это, первый по сути работает с исходным форматом *.grs, разбирая и собирая его, второй пример использует XDTO. Первая у меня вообще отказалась работать мой коммент, вторая обработка мне показалась слишком усложнённой, черт ногу сломит. Стал писать свое и вышло очень даже компактно и красиво.
Если не вдаваться в нюансы, работает это так, кодом формируется некая структура, сериализуется в XDTO, сериализованная структура "скармливается" шаблону преобразования XSLT, на выходе получаем XDTO графической схемы, десериализуем и готово. Многие спросят, "почему XSLT?", это наглядно, можно по быстрому поправить, расширить, не лазя по 1000 строк чужого кода.
Вот пример кода, который выводит демо блок-схему
&НаСервере
Функция ПостроитьНаСервере()
Обработка = РеквизитФормыВЗначение("Объект");
СтруктураСхемы = Обработка.ИнициализироватьСтруктуру();
Действие1 = Обработка.ДобавитьДействие(СтруктураСхемы,, "Выполняем что-то", "Действие 1", Новый Структура("Верх,Лево", 150, 500));
Действие2 = Обработка.ДобавитьДействие(СтруктураСхемы,, "Действие 2",, Новый Структура("Верх,Лево", 350, 500),, Истина);
ВложенныйПроцесс1 = Обработка.ДобавитьВложенныйПроцесс(СтруктураСхемы,, "Вложенный процесс", Новый Структура("Верх,Лево", Действие2.Координаты.Верх, Действие2.Координаты.Лево + Действие2.Размер.Ширина + 20));
Действие3 = Обработка.ДобавитьДействие(СтруктураСхемы,, "Действие 3",,,, Истина);
Условие1 = Обработка.ДобавитьУсловие(СтруктураСхемы, "Условие 1",,, Истина);
Действие4 = Обработка.ДобавитьДействие(СтруктураСхемы,, "Действие 4");
Обработка.СвязатьЭлементы(СтруктураСхемы, Условие1, Действие4, 3, 2, "Да");
Обработка.СвязатьЭлементы(СтруктураСхемы, Действие2, ВложенныйПроцесс1, 3, 1);
Обработка.СвязатьЭлементы(СтруктураСхемы, ВложенныйПроцесс1, Действие3, 4, 2);
Возврат Обработка.ПостроитьСхему(СтруктураСхемы);
КонецФункции
Хочу обратить внимание как осуществляется связка элементов. Элементы связываются методом
Обработка.СвязатьЭлементы(СтруктураСхемы, Действие2, ВложенныйПроцесс1, 3, 1);
Параметры 3 и 1, это есть номера т.н. портов элемента
Нумерация портов начинается с левой стороны по часовой стрелке.
Вот еще пример, что бы вывести такую примитивную схему.
Достаточно такого кода:
&НаСервере
Функция ПостроитьНаСервереПример2()
Обработка = РеквизитФормыВЗначение("Объект");
СтруктураСхемы = Обработка.ИнициализироватьСтруктуру();
Обработка.ДобавитьДействие(СтруктураСхемы,, "Шаг 1", "Действие 1",,, Истина);
Обработка.ДобавитьДействие(СтруктураСхемы,, "Шаг 2", "Действие 2",,, Истина);
Обработка.ДобавитьДействие(СтруктураСхемы,, "Шаг 3", "Действие 3",,, Истина);
Обработка.ДобавитьДействие(СтруктураСхемы,, "Шаг 4", "Действие 4",,, Истина);
Обработка.ДобавитьДействие(СтруктураСхемы,, "Шаг 5", "Действие 5",,, Истина);
Возврат Обработка.ПостроитьСхему(СтруктураСхемы);
КонецФункции
Автоматическая связь элементов осуществляется благодаря последнему параметру. Если не задан размер элемента, в таком случаи устанавливается размер по умолчанию 100х50. Если не заданы координаты, тогда первый элемент начинается с точки 10х10 от левого верхнего угла, последующие элементы автоматически располагаются под предыдущем на расстоянии 20px.
В данный момент поддерживается создание следующих элементов графической схемы:
- Действие
- Условие
- Вложенный процесс
Для конкретно моей задачи этого было достаточно, но на самом деле добавление новых элементов много труда не составит. Единственное могут возникнуть не большие трудности если захотите добавить поддержку не прямоугольных элементов, т.к. отрисовывать форму придется самим по точкам (пример можно посмотреть как сделан элемент условия). Если забить и не отрисовывать по точкам, то при первой отрисовке элемент будет прямоугольный, а при изменении чего-то на схеме, элемент перерисуется, перерисовывает его сама платформа. На самом деле, если бы можно было как-то вызвать эту перерисовку программно, это сильно облегчила б жизнь и кода стало бы еще меньше )
Доработал обработку, теперь есть поддержка элемента ВыборВарианта.
Единственное, так и не удалось побороть, то как отрисовываются линии
После перетаскивания элементов, платформа отрисовывает их нормально
Также хочу обратить внимание, что порты для вариантов начинаются с 6 (уж не знаю почему), учитывайте при связке элементов.