preface
When using BPMN-JS to draw flow charts, developers may need to define their own attributes or elements. In order to ensure compliance with the official definition, the official documents are described in Chinese. The following description is based on personal understanding, may differ from the real effect, I hope you point out incorrect or unclear meaning of the place, I can correct, thank you!
Note File configuration properties
See bPMN-IO/Moddle for the original article.
definitionJson = {
"name": "self"."uri": "https://self"."prefix": "se"./ / prefix
"xml": {
"tagAlias": "lowerCase" // The XML tag is converted to a lowercase hump
},
"types": [ // Define an array of label types
{
// name: user-defined label name, displayed as SE :attrOne in XML
"name": "AttrOne".// isAbstract: Specifies whether complex types can be used in instance documents.
// If this value is true, the element cannot use the complex type directly, but must use a complex type derived from it.
"isAbstract": true./** * extends: Some meta-models require it to plug-in new properties that to certain existing model elements. * This can be acomplished Using the extends Field * Some metamodels require it to insert new properties for some existing model elements. This can be done using extended fields * such as camunda:FormalExpression extends => BPMN :FormalExpression, Camunda :FormalExpression Properties: {name: "resource", type: "String", isAttr: Moddle.create (" BPMN :FormalExpression") can set the newly defined attribute resource *. BusinessObject: {* $type: "bpmn:SequenceFlow" * conditionExpression: { * $type: "bpmn:FormalExpression" * language: "123123" * resource: "123123123" *} *} */
"extends": [].// Extend the selected type attribute. The new attribute AttrOne is automatically inserted every time an instance of an element in the array is created
/** * superClass: Types can inherit from one or more super Types by specifying the superClass property. * Specify upward inheritance of all superClass attributes. * Example camunda:FormalExpression extends * => BPMN :FormalExpression superClass * => BPMN :Expression superClass * => BPMN :BaseElement * Adds attributes to the type in order of type structure hierarchy * If inheriting attributes from other custom configuration files (e.g. B.json [prefix: "b", types: [{name: "TextB"}]]) * then the superClass of the current file must be fully prefixed with the name superClass: ["b:TextB"] * To insert this type as a tag into XML, the inherited superClass must contain the BaseElement or Element type */
"superClass": [
"Element"].// Customize the tag attributes
"properties": [{// name: attribute name
"name": "name".// type: attribute value type, which can be any base type or other custom type.
// If the attribute value needs to be set to another custom type AttrTwo, then "type": "AttrTwo"
"type": "String".// isAttr:
"isAttr": true
// isBody:
XXX
;
// If isBody is true, name can only be set to value
// "isBody": false
// isMany: whether to store attribute values in arrays. Note that they are mutually exclusive with other configurations: Type cannot be simple types such as String or Number, isAttr cannot be true, and so on
// "isMany": true
// default: the default value
// "default": "xxx"
// Redefines attributes inherited from supertypes, rewriting names, types, and qualifiers
// "redefines": String
// isReference: Whether to reference another object by its ID attribute as the attribute value, usually used when setting the default path for task nodes/gateways, etc
// "isReference": false
// "xml": {
// serialize: Adds additional comments about how to serialize. Supported values: XSI -- Types are serialized as data types, not elements
// "serialize": "xsi:type"
/ /}
},
{
"name": "value"."type": "Number"."isAttr": "true"."default": 2}]}, {"name": "AttrTwo"."superClass": [
"Element"]."meta": {
"allowedIn": [ "*" ] // Which element tags are allowed to enter
},
"properties": [{"name": "value"."type": "String"."isBody": true
XXX
}}]].// The enumerations and associations properties are reserved for future use.
// Enumerations and associated properties are reserved for future use.
enumerations: [].associations: []}Copy the code
Custom description file Demo
Description fileSelfDescriptor.json
{
"name": "self"."uri": "https://self"."prefix": "se"."xml": {
"tagAlias": "lowerCase"
},
"types": [{"name": "AttrOne"."superClass": [
"Element"]."properties": [{"name": "name"."type": "String"."isAttr": "true"
},
{
"name": "values"."type": "AttrOneProp"."isMany": true}]}, {"name": "AttrOneProp"."superClass": [
"Element"]."meta": {
"allowedIn": [ "*"]},"properties": [{"name": "propName"."type": "String"."isAttr": true
},
{
"name": "value"."type": "String"."isAttr": true}]}, {"name": "AttrTwo"."superClass": [
"Element"]."meta": {
"allowedIn": [ "*"]},"properties": [{"name": "value"."type": "String"."isBody": true}]}]}Copy the code
use
import $ from 'jquery';
import BpmnModeler from 'bpmn-js/lib/Modeler';
/ / the sidebar
import propertiesPanelModule from 'bpmn-js-properties-panel';
// Camunda sidebar content builder
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
// camunda attribute parsing file
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';
// Custom attribute resolution file
import SelfDescriptor from "./SelfDescriptor.json";
// Omit some content...
// Initialize modeler
var bpmnModeler = new BpmnModeler({
container: canvas,
propertiesPanel: {
parent: '#js-properties-panel'
},
additionalModules: [
propertiesPanelModule,
propertiesProviderModule
],
moddleExtensions: {
// Parse the file using the imported properties
camunda: camundaModdleDescriptor,
self: SelfDescriptor
}
});
// Use and create custom attribute tags
bpmnModeler.on("element.click".function (event, eventObj) {
const moddle = bpmnModeler.get("moddle");
// Customize attribute 1
const attrOne = moddle.create("se:AttrOne", { name: "testAttrOne".values: []});// Custom attributes subattributes
const attrOneProp = moddle.create("se:AttrOneProp", {propName: "propName1".value: "propValue1"})
// Customize attribute 2
const attrTwo = moddle.create("se:AttrTwo", { value: "testAttrTwo" })
// Native Properties
const props = moddle.create("camunda:Properties", { values: []});// The child of the native property Properties
const propItem = moddle.create("camunda:Property", { name: "Original child attribute Name".values: "Parent attribute value" });
// Native extended property array
const extensions = moddle.create("bpmn:ExtensionElements", { values: []})// Start node to insert native attributes
if (eventObj.element.type === "bpmn:StartEvent") {
props.values.push(propItem);
extensions.values.push(props);
}
// The task node inserts multiple attributes
if (eventObj.element.type === "bpmn:Task") {
props.values.push(propItem, propItem);
attrOne.values.push(attrOneProp);
extensions.values.push(props, attrOne, attrTwo);
}
// root Inserts custom attributes
if (eventObj.element.type === "bpmn:Process") {
attrOne.values.push(attrOneProp, attrOneProp);
extensions.values.push(attrOne);
}
bpmnModeler.get("modeling").updateProperties(eventObj.element, {
extensionElements: extensions
});
})
Copy the code
The results of
Only relevant parts of the process are captured
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:extensionElements>
<se:attrOne name="testAttrOne">
<se:attrOneProp propName="propName1" value="propValue1" />
<se:attrOneProp propName="propName1" value="propValue1" />
</se:attrOne>
</bpmn2:extensionElements>
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:extensionElements>
<camunda:properties>
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
</camunda:properties>
</bpmn2:extensionElements>
<bpmn2:outgoing>Flow_066c7c5</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="Activity_0ghpzc3" name="1">
<bpmn2:extensionElements>
<camunda:properties>
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
</camunda:properties>
<se:attrOne name="testAttrOne">
<se:attrOneProp propName="propName1" value="propValue1" />
</se:attrOne>
<se:attrTwo>testAttrTwo</se:attrTwo>
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_066c7c5</bpmn2:incoming>
<bpmn2:outgoing>Flow_0qmpzc7</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_066c7c5" sourceRef="StartEvent_1" targetRef="Activity_0ghpzc3" />
<bpmn2:task id="Activity_1gm4zj6" name="2">
<bpmn2:extensionElements>
<camunda:properties>
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
</camunda:properties>
<se:attrOne name="testAttrOne">
<se:attrOneProp propName="propName1" value="propValue1" />
</se:attrOne>
<se:attrTwo>testAttrTwo</se:attrTwo>
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_0qmpzc7</bpmn2:incoming>
<bpmn2:outgoing>Flow_03hry06</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_0qmpzc7" sourceRef="Activity_0ghpzc3" targetRef="Activity_1gm4zj6" />
<bpmn2:task id="Activity_0ahhdt5" name="3">
<bpmn2:extensionElements>
<camunda:properties>
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
<camunda:property name="Original child attribute Name" values="Parent attribute value" />
</camunda:properties>
<se:attrOne name="testAttrOne">
<se:attrOneProp propName="propName1" value="propValue1" />
</se:attrOne>
<se:attrTwo>testAttrTwo</se:attrTwo>
</bpmn2:extensionElements>
<bpmn2:incoming>Flow_03hry06</bpmn2:incoming>
<bpmn2:outgoing>Flow_1h7pp7l</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_03hry06" sourceRef="Activity_1gm4zj6" targetRef="Activity_0ahhdt5" />
<bpmn2:endEvent id="Event_1eofx2i">
<bpmn2:incoming>Flow_1h7pp7l</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="Flow_1h7pp7l" sourceRef="Activity_0ahhdt5" targetRef="Event_1eofx2i" />
</bpmn2:process>
Copy the code
Afterword.
Due to the demands of the job (which is not really necessary), Open source BPMN Process Designer is a Process editor based on bPMN-js + Vue 2.x + ElementUI, preview at MiyueFE blog, welcome fork and star.