Создание узлов
Ограничиваться базовыми узлами не интересно, потому существует возможность создавать собственные узлы с глубокой изменяемостью.
Схема узла
Любой узел определяет его форма, входы и имя.
Наименование
Имя влияет на правильность обработки в программе, потому назвать узлы нужно правильно:
- Имя не должно совпадать с именем уже созданных узлов (базовых или пользовательских)
- Имя не должно иметь пробелов или спец. символов (только английские большие и маленькие буквы)
Форма
Генерация формы происходит автоматически, однако существует возможность изменить размеры узла. Стандартно при небольшом количестве входов и выходов узел имеет форму квадрата 1x1 (блок), однако для циклов и похожих узлов форма расширяется по высоте, доходя до 1x2 (два блока). Расширение по горизонтали возможно. Слева узла находятся входы, справа выходы.
Кроме простых входов существуют разделители и пустые входы. Пустые входы представляют собой маленький вход, но без обозначения (к нему нельзя подключить другой узел). Разделитель, в свою очередь, пытается разделить коннекторы на блоки. Например, если последовательность выходов (сверху вниз) такова - (‘ctrl’, ‘sep’, ‘ctrl’), то результат - форма узла будет 1x2 (два блока), а выходы расположатся по одному на каждый блок.

Генерация узла
У создания узлов есть несколько вариантов:
- Создание изображения узла
- Создание узла с функционалом (требуется знание Python)
- Создание функции
- Создание библиотеки из нескольких узлов
Создание узла
Такой вид генерации является базовым и используется во всех остальных. Для создания требуется базовое знание структуры Python и в частности словарей. Для создания узла требуется создать словарь со следующей структурой:
node = {
# кортеж входов с форматом ('single'|'multiple', [<type>, ['small', ['directed']]])
'inputs': (
('single', 'ctrl'),
),
# кортеж выходов ('single'|'multiple', [<type>, ['small', ['directed']]])
'outputs': (
('single', 'int'),
),
# кортеж цветов выходов (типов) - опционально
'outputs_color': ('int',),
# пользовательский символ - опционально
'user_symbol': '&',
# время работы узла - опционально
'time': '~',
# наименование узла (уникальное и используемое в обработке узлов)
'sync_name': 'length',
# наименование узла (уникальное и используемое в создании
# изображения и обработке узлов если не указано sync_name)
'label': 'length',
# описание внутри узла - опционально
'inner': 'Len',
# дополнительное описание - опционально
'desc': 'in',
# размер шрифта дополнительного описания - опционально
'desc_size': 6,
# размер шрифта дополнительной информации - опционально
'adds_size': 6,
# размер шрифта внутреннего описания - опционально
'inner_size': 8,
# цвет заднего фона (r, g, b) - опционально
'bg_color': (255, 255, 255),
# цвет границ (r, g, b) - опционально
'border_color': (0, 0, 0),
# толщина границ - опционально
'border_width': 0.5,
# ширина узла - опционально
'width': 1,
# подсказка при наведении - опционально
'tooltip': {
# название узла
'label': 'Label',
# описание узла - опционально
'desc': 'Node description',
# список описаний входов узла - опционально
'inputs': [
# кортеж из краткого обозначения узла и описания
('Input 1', 'input 1 desc'),
('Input 2', 'input 2 desc'),
],
# список описаний выходов узла - опционально
'outputs': [
('Output 1', 'output 1 desc'),
('Output 2', 'output 2 desc'),
],
# дополнительная информация - опционально
'adds': 'Node additional description',
# ширина строки - опционально
'word_wrap': 30
}
}
Входы и выходы
Для описания входов или выходов используется кортежа со специальной структурой. Первым элементом является
количество входных соединений - single и multiple. После него может идти тип. После могут идти два
параметра - small и directed. Обязательным всегда является первый элемент. Остальные могут быть в разных
комбинациях, однако тип данных всегда должен быть раньше параметров.
Вместо количества входных соединений можно использовать дополнительные обозначения (разделители):
- sep - разделитель
- empty - пустое место под коннектор
Если в кортеже лишь одно значение, то нужно написать запятую после него, чтоб программа понимала, что это кортеж.
Примеры:
(
# одиночный, бестиповой
('single',),
# одиночный, тип bool
('single', 'bool'),
# множественный, бестиповой
('multiple',),
# множественный, тип char
('multiple', 'char'),
# множественный, тип real, направленный
('multiple', 'real', 'directed'),
# множественный, тип int, уменьшенный
('multiple', 'int', 'small'),
# множественный, тип ctrl, уменьшенный и направленный
('multiple', 'ctrl', 'small'),
# множественный, бестиповой, уменьшенный
('multiple', 'small'),
)
Имя узла
Имя узла определятся двумя способами. Используя только параметр label и используя sync_name. В первом случае название будет принадлежать как изображению, как обозначению в обработчике, так и в библиотеке (если она создаваться будет). Во втором случае label будет относиться к обозначению в библиотеке, а sync_name уже к обозначению в обработчике и к изображению.
Разница не большая, однако иногда требуется обозначить узлы с разным функционалом одинаковым именем.
Подсказка
Всплывающая подсказка - информация показываемая при наведении курсора на узел в Draw.io. Позволяет быстро получить информацию об узле. Очень полезно, если постоянно забывается функция узла. Всплывающая подсказка не обязательна. У подсказки есть название, описание, дополнительная информация, а также информация по входам и выходам.

Описание входов - это список из кортежей. Каждый кортеж должен состоять из обозначения и описания. Описание отображается в подсказке.
Запуск генерации узла
Для простого создания узла не требуется использовать модифицированный Python. Однако для создания описания узла в формате PNG все
же требуется установить библиотеку PIL. Для установки требуется написать в консоли устройства или Repl.it
команду pip install pillow. Последний (Repl.it) чаще всего автоматически устанавливает все требуемые библиотеки автоматически.

Далее требуется перейти в скрипт new_node.py и перейти в раздел if __name__ == "__main__": ....
Внутри него есть пример узла и готовые закомментированные инструкции. Для их использования достаточно убрать решетку.
Переменные svg_save_folder и lib_save_folder определяют места, куда сохранятся файлы SVG и DRAWIO, library_name -
название библиотеки.
svg_save_folder = "<путь к созданным изображениям>"
lib_save_folder = "<путь к созданной библиотеке>"
library_name = "<название создаваемой библиотеки>"
Переменная node хранит в себе информацию по узлу. Если создается один узел, то достаточно прописать в ней описание узла
node = {
'inner': 'Join',
'label': 'join',
...
}
Переменная nodes_info хранит список информаций по узлам. Если требуется создать библиотеку, то требуется через запятую прописать описания узлов. Это можно сделать создавая переменные и сохраняя информацию в них, и после в список, а можно записывать описания сразу.
nodes_info = [
{...},
{...}
]
Простой узел
Для запуска генерации простого узла требуется раскомментировать строчку с выполнением функции generate_node. В функцию требуется передать место сохранения изображения и описание узла. После запуска получается изображение в указанном месте и выводится в консоль стиль, который нужно добавить в узел в Draw.io.
generate_node(node, svg_save_folder)
Для создания рабочего узла нужно перетащить изображение на рабочую область. Стиль можно добавить через правую кнопку по узлу (выбрав “Edit Style”) и добавив полученный стиль в конец окна.
Узел-Функция
Для запуска генерации функции узла требуется раскомментировать строчку с выполнением функции generate_function. В функцию требуется передать описание узла, места сохранения изображения и библиотеки. После запуска получается библиотека в указанном месте, в которой будет храниться узел-функция и определяющие её конструкции.
generate_function(node, svg_save_folder, lib_save_folder)
Библиотека
Для запуска генерации библиотеки узлов требуется раскомментировать строчку с выполнением функции generate_library. В функцию требуется передать название библиотеки, описание узла, места сохранения изображения и библиотеки. После запуска получается библиотека в указанном месте.
generate_library(library_name, nodes_info, svg_save_folder, lib_save_folder)
Дополнительные возможности
- generate_base_libs - обновление стандартных библиотек
- generate_png_description - создание описания узла, указанного в аргументе
- generate_png_descriptions - создание описания всех стандартных узлов и узлов указанных в аргументе