предисловие
В: Что такое bpmn.js?
"
bpmn.jsЭто набор инструментов рендеринга BPMN2.0 и средство веб-моделирования, которое позволяет выполнять функцию рисования блок-схем во внешнем интерфейсе.
В: Почему я пишу эту серию учебников? 🤔️
"
Из-за потребностей бизнеса компании его необходимо использовать в проектеbpmn.js
, Однако из-заbpmn.js
Разработчики игры зарубежные друзья,поэтому отечественных методических материалов мало и нет подробных документов.Поэтому много способов использования и много ям приходится искать самому.Поразмыслив,решил написать серию учебные материалы об этом. чтобы помочь большеbpmn.js
Пользователи или разработчики, которые ищут хороший способ рисовать блок-схемы, в то же время для них это еще и своего рода консолидация.
Поскольку это серия статей, она может часто обновляться.Пожалуйста, простите меня, если вы случайно смахнули его, и это не то, что вам нужно😊.
Не просите похвалы👍 не просите сердца❤️ Я просто надеюсь, что смогу вам немного помочь.
Статьи пользовательской палитры
После базовых туториалов в предыдущих главах я считаю, что все правыbpmn.js
Основное использование .
Начиная с этой главы, я объясню некоторыеbpmn.js
Настраиваемые разделы в , включая настраиваемую левую панель инструментов, настраиваемую визуализацию, настраиваемуюcontextPad
и т.п.
Давайте сначала посмотрим на картинку, чтобы увидеть, что есть на наших страницах рисования:
В этой главе я хочу рассказать, как настроить панель инструментов слева (Palette
, также называемая палитрой), читая вы можете узнать:
Для каталога выше 👆 неявное значение заключается в настройкеPalette
Есть два способа:
- существует
bpmn.js
предоставляется по умолчаниюPalette
Измените его (или добавьте новый элемент) - полное покрытие
Palette
Все предметы в, настроить новыйPalette
Изменить на основе палитры по умолчанию
Давайте рассмотрим первый и самый простой, мы добавляем пользовательский элемент в официальную палитру.
- Тип элемента:
bpmn:Task
- Имя элемента:
lindaidai-task
- стиль: следовать
bpmn:Task
Оригинальный стиль, просто поменяйте рамку на красную - Роль: создать тип
lindaidai-task
узел задачи
Эффект такой:
Как показано выше, только цвет окна задачи меняется на красный, поэтому эффект не очень очевиден, вы даже можете изменить его напрямую:
Давайте посмотрим, как это сделать! 🐶
Предварительная подготовка
Поскольку это новая глава, здесь я также создаю новый проект:
$ vue create bpmn-vue-custom
$ npm i vue-router axios bpmn-js-properties-panel bpmn-js --save-D
По предыдущему случаюLinDaiDai/bpmn-vue-basicНастройте соответствующую маршрутизацию и так далее.
существуетcomponents
Создайте новую папку с именемcustom-palette.vue
файл, и будетprovider.vue(предыдущий базовый вариант) копируется.
продолжатьcomponents
Создайте новую папку под папкойcustom
Используется для хранения некоторых пользовательских вещей, которые мы напишем позже.
Давайте посмотрим на нашу текущую структуру проекта:
я уже вcustom
Создана новая папкаCustomPalette.js
, следующим шагом будет запись в нем элементов, которые мы хотим настроить.
записыватьCustomPalette.js
код
Сначала этоjs
Является экспортом класса (имя класса можно брать по желанию, но нельзя брать его по желанию при обращении к нему, о чем речь пойдет позже):
вот и я так понимаюCustomPalette
:
// CustomPalette.js
export default class CustomPalette {
constructor(bpmnFactory, create, elementFactory, palette, translate) {
this.bpmnFactory = bpmnFactory;
this.create = create;
this.elementFactory = elementFactory;
this.translate = translate;
palette.registerProvider(this);
}
// 这个函数就是绘制palette的核心
getPaletteEntries(element) {}
}
CustomPalette.$inject = [
'bpmnFactory',
'create',
'elementFactory',
'palette',
'translate'
]
Код выше 👆 легко понять:
- определить класс
- использовать
$inject
Введите некоторые необходимые переменные - использовать в классе
palette.registerProvider(this)
указать, что этоpalette
определенныйCustomPalette.js
После этого нам нужноindex.js
экспортировать его в:
// custom/index.js
import CustomPalette from './CustomPalette'
export default {
__init__: ['customPalette'],
customPalette: ['type', CustomPalette]
}
Примечание: ️здесь__init__
Имя должно бытьcustomPalette
, и следующие имена атрибутов также должны бытьcustomPalette
, иначе будет сообщено об ошибке.
Также использовать его на странице:
<!--custom-palette.vue-->
<script>
...
import customModule from './custom'
...
this.bpmnModeler = new BpmnModeler({
...
additionalModules: [
// 左边工具栏以及节点
propertiesProviderModule,
// 自定义的节点
customModule
]
})
</script>
Напишите основные функцииgetPaletteEntries
код
Отложив это в сторону, вопрос в том, как построить этоgetPaletteEntries
функция
Нельзя менять имя функции, иначе будет сообщено об ошибке.Во-первых, она возвращает объект, а объект, указанный в объекте, и есть тот элемент, который вы хотите настроить.Наверное, это выглядит так:
// CustomPalette.js
getPaletteEntries(element) {
return {
'create.lindaidai-task': {
group: 'model', // 分组名
className: 'bpmn-icon-task red', // 样式类名
title: translate('创建一个类型为lindaidai-task的任务节点'),
action: { // 操作
dragstart: createTask(), // 开始拖拽时调用的事件
click: createTask() // 点击时调用的事件
}
}
}
}
Вы можете видеть, что имя элемента, которое я определил:create.lindaidai-task
, Он будет иметь несколько фиксированных свойств:
- группа: к какой группе он принадлежит, например
tools、event、gateway、activity
д., для классификации - className: имя класса стиля, мы можем использовать его для изменения стиля элемента
- title: Подсказка, отображаемая над элементом при перемещении мыши.
- действие: событие, которое будет запущено, когда пользователь выполнит действие
Все, что нам нужно сделать дальше, это:
- пройти через
className
установить стиль - пройти через
action
чтобы определить, что запускать
записыватьclassName
код
я здесьscr
создал новый в каталогеcss
файл, который используется для хранения некоторых глобальных стилей, иmain.js
Ссылка на этот глобальный стиль в:
// main.js
// 引入全局的css
import './css/app.css'
Затем добавьте к нему следующие стили:
/* app.css */
.bpmn-icon-task.red {
color: #cc0000 !important;
}
выше 👆className
почему я используюbpmn-icon-task
, потому что классbpmn.js
один изiconfont
класс, который можно использовать для реализацииtask
Эффект значка:
из-заiconfont
это шрифт, поэтому здесь я используюcolor
изменить его цвет.
Вы также можете использовать его, если хотите полностью заменить его картинкой.className
реализовать:
/* app.css */
.icon-custom { /* 定义一个公共的类名 */
border-radius: 50%;
background-size: 65%;
background-repeat: no-repeat;
background-position: center;
}
.icon-custom.lindaidai-task { /* 加上背景图 */
background-image: url('https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/rules.png');
}
затем изменитьcreate.lindaidai-task
серединаclassName
:
// CustomPalette.js
'create.lindaidai-task': {
className: 'icon-custom lindaidai-task'
}
Эта страница - это фоном идет в вашем определении отображаемого:
записыватьaction
код
Фактически, после выполнения вышеуказанной операции страница может нормально отображать пользовательский элемент, но при нажатии или перетаскивании он не будет иметь никакого эффекта💦.
Что мы ожидаем в этот момент, так это щелкнуть или перетащить его, чтобы нарисоватьlindaidai-task
, поэтому вам нужно добавить к нему события,
То есть написать функцию для созданияbpmn:Task
Этот элемент:
// CustomPalette.js
function createTask() {
return function(event) {
const businessObject = bpmnFactory.create('bpmn:Task');
const shape = elementFactory.createShape({
type: 'bpmn:Task',
businessObject
});
console.log(shape) // 只在拖动或者点击时触发
create.start(event, shape);
}
}
Ядро здесь на самом деле использоватьbpmn.js
Предусмотрены некоторые способы созданияshape
Затем добавьте его на холст.
(Я демонстрирую здесь созданиеbpmn:Task
элемент, вы также можете использовать для созданияbpmn:StartEvent、bpmn:ServiceTask、bpmn:ExclusiveGateway
так далее...)
В этот момент вы перетаскиваете или нажимаетеlindaidai-task
вы можете создать страницуTask
элемент.
мы видим, хотяlindaidai-task
Панель инструментов слева золотая, но фактическая страница все еще отображается в «голом» состоянии😅, что как-то связано с пользовательским рендерингом, не волнуйтесь, это будет рассмотрено в следующих главах.
полныйCustomPalette.js
код
Давайте соберем весь приведенный выше код вместе:
// CustomPalette.js
export default class CustomPalette {
constructor(bpmnFactory, create, elementFactory, palette, translate) {
this.bpmnFactory = bpmnFactory;
this.create = create;
this.elementFactory = elementFactory;
this.translate = translate;
palette.registerProvider(this);
}
getPaletteEntries(element) {
const {
bpmnFactory,
create,
elementFactory,
translate
} = this;
function createTask() {
return function(event) {
const businessObject = bpmnFactory.create('bpmn:Task'); // 其实这个也可以不要
const shape = elementFactory.createShape({
type: 'bpmn:Task',
businessObject
});
console.log(shape) // 只在拖动或者点击时触发
create.start(event, shape);
}
}
return {
'create.lindaidai-task': {
group: 'model',
className: 'icon-custom lindaidai-task',
title: translate('创建一个类型为lindaidai-task的任务节点'),
action: {
dragstart: createTask(),
click: createTask()
}
}
}
}
}
CustomPalette.$inject = [
'bpmnFactory',
'create',
'elementFactory',
'palette',
'translate'
]
Git-адрес кейса проекта:LinDaiDai/bpmn-vue-custom
Примечание: В случае с проектом для удобства демонстрации вcustom-palette
Представлен вImportJS/onlyPalette.js
, а рассмотренный выше случай основан на введенииcustom/index.js
Для того, чтобы объяснить, это надо самому понять, как различать.
Полностью настраиваемая палитра
Можно видеть, что описанный выше метод реализации 👆 фактически определяетCustomPalette
затем вnew BpmnModeler
ссылка в сгенерированном объекте.
Но это немного плохо👎, то есть, если вы не хотите, чтобы элементы по умолчанию, которые он предоставляет, такие как начальные узлы, конечные узлы и узлы задач, но все они настраиваются под вас, вы не можете быть удовлетворены . Например:
В этот момент вам нужно переписатьBpmnModeler
В этом классе реализован собственный уникальный наборmodeler
.
Предварительная подготовка
Продолжайте создавать его на основе проекта выше 👆customModeler
И папкаcustom-modeler.vue
документ.
затем вcustomModeler
создатьindex.js
с однимcustom
папка.
-
customModeler
Файлы в папке используются для установки пользовательскихmodeler
-
custom-modeler.vue
Отображать как страницу (не забудьте настроить маршрутизацию страницы)
На данный момент структура проекта становится:
записыватьCustomPalette.js
код
здесьCustomPalette.js
Способ написания отличается от первого:
/**
* A palette that allows you to create BPMN _and_ custom elements.
*/
export default function PaletteProvider(palette, create, elementFactory, globalConnect) {
this.create = create
this.elementFactory = elementFactory
this.globalConnect = globalConnect
palette.registerProvider(this)
}
PaletteProvider.$inject = [
'palette',
'create',
'elementFactory',
'globalConnect'
]
PaletteProvider.prototype.getPaletteEntries = function(element) { // 此方法和上面案例的一样
const {
create,
elementFactory
} = this;
function createTask() {
return function(event) {
const shape = elementFactory.createShape({
type: 'bpmn:Task'
});
console.log(shape) // 只在拖动或者点击时触发
create.start(event, shape);
}
}
return {
'create.lindaidai-task': {
group: 'model',
className: 'icon-custom lindaidai-task',
title: '创建一个类型为lindaidai-task的任务节点',
action: {
dragstart: createTask(),
click: createTask()
}
}
}
}
Вот прямая перепискаPaletteProvider
Этот класс также переопределяетgetPaletteEntries
метод, чтобы добиться эффекта закрытия исходной панели инструментов.
(Не смотрите на то, что написано выше 👆, кажется, много, но на самом деле успокоится и увидит, что это ничто 😊)
записыватьcustom/index.js
код
Следующий шаг такой же, как и первый метод, нам нужно настроитьPalette
Экспорт:
// custom/index.js
import CustomPalette from './CustomPalette'
export default {
__init__: ['paletteProvider'],
paletteProvider: ['type', CustomPalette]
}
Но здесь мы не используемcustomPalette
, но напрямую использоватьpaletteProvider
.
записыватьcustomModeler/index.js
код
Самый важный шаг — написатьCustomModeler
Этот класс имеет:
import Modeler from 'bpmn-js/lib/Modeler'
import inherits from 'inherits'
import CustomModule from './custom'
export default function CustomModeler(options) {
Modeler.call(this, options)
this._customElements = []
}
inherits(CustomModeler, Modeler)
CustomModeler.prototype._modules = [].concat(
CustomModeler.prototype._modules, [
CustomModule
]
)
Экспортируемый класс наследуетModeler
Этот базовый класс обеспечивает реализацию других функций.
Цитата на странице
Последним шагом является преобразование нашего исходногоBpmnModeler
Созданный объект изменяется нашим кастомнымCustomModeler
создавать, писатьcustom-modeler.vue
.
<!--custom-modeler.vue-->
<script>
...
import CustomModeler from './customModeler'
...
this.bpmnModeler = new CustomModeler({ // 原本是用BpmnModeler
...
additionalModules: [] // 可以不用引用任何东西
})
</script>
Заходите и откройте страницу, чтобы увидеть эффект:
послесловие
В приведенном выше 👆 в обоих случаях используется один и тот же проект🦐
Git-адрес кейса проекта:LinDaiDai/bpmn-vue-customЕсли вам это нравится, пожалуйста, дайтеStar
🌟 Да, спасибо😊
Полный каталог серии можно найти здесь:"Самый подробный учебник по bpmn.js во всей сети"
Рекомендации по сериалу:
"Самый подробный учебник по bpmn.js во всей сети - основы"
"Самый подробный учебный материал по bpmn.js во всей сети - http запрос"
"Самый подробный учебный материал по bpmn.js во всей сети - мероприятия"
"Самый подробный учебник по bpmn.js во всей сети - рендерер"
"Самый подробный учебник по bpmn.js во всей сети - contextPad"
"Самый подробный учебник по bpmn.js во всей сети - редактирование и удаление узлов"