BPMN activity in Angular Diagram control

25 Feb 202524 minutes to read

Activity

The activity is the task that is performed in a business process. It is represented by a rounded rectangle.

There are two types of activities. They are listed as follows:

  • Task: Occurs within a process and it is not broken down to a finer level of detail.
  • Subprocess: Occurs within a process and it is broken down to a finer level of detail.

To create a BPMN activity, set the shape as activity. You also need to set the type of the BPMN activity by using the activity property of the node. By default, the type of the activity is set as task. The following code example illustrates how to create an activity.

import { DiagramModule, BpmnDiagramsService ,DiagramComponent, NodeModel, BpmnShapeModel} from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task'
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The different activities of BPMN process are listed as follows.

Tasks

The task property of the bpmn activity allows you to define the type of task such as sending, receiving, user based task, etc. By default, the type property of task is set as none. The following code illustrates how to create different types of
BPMN tasks

import { DiagramModule, BpmnDiagramsService,DiagramComponent, NodeModel, BpmnShapeModel  } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape1'></e-node>
            <e-node id='node2' [offsetX]=350 [offsetY]=150 [shape]='shape2'></e-node>
            <e-node id='node3' [offsetX]=550 [offsetY]=150 [shape]='shape3'></e-node>
            <e-node id='node4' [offsetX]=750 [offsetY]=150 [shape]='shape4'></e-node>
            <e-node id='node5' [offsetX]=150 [offsetY]=350 [shape]='shape5'></e-node>
            <e-node id='node6' [offsetX]=350 [offsetY]=350 [shape]='shape6'></e-node>
            <e-node id='node7' [offsetX]=550 [offsetY]=350 [shape]='shape7'></e-node>
            <e-node id='node8' [offsetX]=750 [offsetY]=350 [shape]='shape8'></e-node>
            <e-node id='node9' [offsetX]=450 [offsetY]=550 [shape]='shape9'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape1: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
          activity: 'Task',
          //Sets the type of the task as Send
          task: {
            type: 'Send',
          },
        },
      
    }
    public shape2: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'Service'
            }
        },
    }
    public shape3: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'BusinessRule'
            }
        },
    }
    public shape4: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'Receive'
            }
        },
    }
    public shape5: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'InstantiatingReceive'
            }
        },
    }
    public shape6: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'Manual'
            }
        },
    }
    public shape7: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'Script'
            }
        },
    }
    public shape8: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'User'
            }
        },
    }
    public shape9: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the type of the task as Send
            task: {
                type: 'None'
            }
        },
    }

    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The various types of BPMN tasks are tabulated as follows.

Shape Image
Service ServiceBPMNImage
Send SendBPMNImage
Receive ReceiveBPMNImage
Instantiating Receive Instantiating ReceiveBPMNImage
Manual ManualBPMNImage
Business Rule Business RuleBPMNImage
User UserBPMNImage
Script ScriptBPMNImage

Collapsed Subprocess

A Collapsed sub-process is a group of tasks, which is used to hide or reveal details of additional levels. The following code explains how to create a Collapsed Sub-Process.

import { DiagramModule, BpmnDiagramsService, DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
            subProcess: {
                collapsed: true
            }
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Loop

Loop is a task that is internally being looped. The loop property of bpmn activity allows you to define the type of loop. The default value for loop is none. You can define the loop property in subprocess BPMN shape as shown in the following code.

import { DiagramModule, BpmnDiagramsService, DiagramComponent, NodeModel, BpmnShapeModel} from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=100 [offsetY]=100 [shape]='shape1'></e-node>
            <e-node id='node2' [offsetX]=300 [offsetY]=100 [shape]='shape2'></e-node>
            <e-node id='node3' [offsetX]=500 [offsetY]=100 [shape]='shape3'></e-node>
            <e-node id='node4' [offsetX]=700 [offsetY]=100 [shape]='shape4'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape1: BpmnShapeModel = {
        
        type: 'Bpmn',
        shape: 'Activity',
        
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets loop of the task as Standard
            task: {
                loop: 'Standard'
            }
        },
    }
    public shape2: BpmnShapeModel = {
        
        type: 'Bpmn',
        shape: 'Activity',
        
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
          //Sets collapsed as true and loop as None
          subProcess: {
            collapsed: true,
            loop: 'None',
          },
        },
    }
    public shape3: BpmnShapeModel = {
        
        type: 'Bpmn',
        shape: 'Activity',
        
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
          //Sets collapsed as true and loop as ParallelMultiInstance
          subProcess: {
            collapsed: true,
            loop: 'ParallelMultiInstance',
          },
        },
    }
    public shape4: BpmnShapeModel = {
        
        type: 'Bpmn',
        shape: 'Activity',
        
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
          //Sets collapsed as true and loop as SequenceMultiInstance
          subProcess: {
            collapsed: true,
            loop: 'SequenceMultiInstance',
          },
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The following table contains various types of BPMN loops.

Loops Task Subprocess
Standard StandardTaskImage StandardSubprocessImage
SequenceMultiInstance SequenceMultiInstanceTaskImage SequenceMultiInstanceSubprocessImage
ParallelMultiInstance ParallelMultiInstanceTaskImage ParallelMultiInstanceSubprocessImage

Compensation

Compensation is triggered, when operation is partially failed and enabled it with the compensation property of the bpmn activity.
By default, the compensation is set to false.

import { DiagramModule, BpmnDiagramsService ,DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
            <e-node id='node2' [offsetX]=300 [offsetY]=150 [shape]='shape1'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets compensation of the task as true
            task: {
                compensation: true
            }
        },
    }
    public shape1: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as SubProcess
        activity: {
            activity: 'SubProcess',
            //Set the collapsed as true and compensation as true
            subProcess: {
                collapsed: true,
                compensation: true
            }
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Call

A call activity is a global subprocess that is reused at various points of the business flow and set it with the call property of the task.
By default, the call property is false.

import { DiagramModule, BpmnDiagramsService,DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'Task',
            //Sets the call of the task as true
            task: {
                call: true
            }
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

NOTE

This Property is only applicable for task Type activity.

Adhoc

An adhoc subprocess is a group of tasks that are executed in any order or skipped in order to fulfill the end condition and set it with the adhoc property of subprocess.By default, the adhoc property is false.

import { DiagramModule, BpmnDiagramsService,DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
            //Sets collapsed as true and adhoc as true
            subProcess: {
                collapsed: true,
                adhoc: true
            }
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Boundary

Boundary represents the type of task that is being processed. The boundary property of subprocess allows you to define the type of boundary. By default, it is set as default.

import { DiagramModule, BpmnDiagramsService, DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
    imports: [
        DiagramModule
    ],

    providers: [BpmnDiagramsService],
    standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=250 [offsetY]=250 [shape]='shape'></e-node>
            <e-node id='node2' [offsetX]=450 [offsetY]=250 [shape]='shape1'></e-node>
            <e-node id='node3' [offsetX]=650 [offsetY]=250 [shape]='shape2'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
            //Sets collapsed as true and boundary as Call
            subProcess: {
                collapsed: true,
                boundary: 'Call'
            }
        },
    }
    public shape1: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
            //Sets collapsed as true and boundary as Event
            subProcess: {
                collapsed: true,
                boundary: 'Event'
            }
        },
    }
    public shape2: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as Task
        activity: {
            activity: 'SubProcess',
            //Sets collapsed as true and boundary as Default
            subProcess: {
                collapsed: false,
                boundary: 'Default'
            }
        },
    }
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

The following table contains various types of BPMN boundaries.

Boundary Image
Call CallImage
Event EventImage
Default DefaultImage

SubProcess types

The different types of subprocess are as follows:

* Event subprocess
* Transaction
Event subprocess

A subprocess is defined as an event subprocess, when it is triggered by an event. An event subprocess is placed within another subprocess which is not part of the normal flow of its parent process. You can set event to a subprocess with the event and trigger property of the subprocess. The type property of subprocess allows you to define the type of subprocess whether it should be event subprocess or transaction subprocess.

import { DiagramModule, BpmnDiagramsService , DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as SubProcess
        activity: {
            activity: 'SubProcess',
            //Sets the collapsed as false and type as Event
            subProcess: {
                collapsed: false,
                type: 'Event',
            //Sets event as Start and trigger as Message
            events: [
                {
                  id: 'event',
                  event: 'Start',
                  trigger: 'Message',
                  offset: { x: 0.5, y: 0 },
                },
              ],  
            }
        }
    } as BpmnShapeModel;
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

Transaction subprocess
  • transaction is a set of activities that logically belong together, in which all contained activities must complete their parts of the transaction; otherwise the process is undone. The execution result of a transaction is one of Successful Completion, Unsuccessful Completion (Cancel), and Hazard (Exception). The event property of subprocess allows to represent these results as an event attached to the subprocess.

  • The event object allows you to define the type of event by which the subprocess will be triggered. The name of the event can be defined to identify the event at runtime.

  • The event’s offset property is used to set the fraction/ratio (relative to parent) that defines the position of the event shape.

  • The trigger property defines the type of the event trigger.

  • You can also use define ports and labels to subprocess events by using event’s ports and labels properties.

import { DiagramModule, BpmnDiagramsService,DiagramComponent, NodeModel, BpmnShapeModel } from '@syncfusion/ej2-angular-diagrams'
import { Component, ViewEncapsulation, ViewChild } from '@angular/core';

@Component({
imports: [
         DiagramModule
    ],

providers: [BpmnDiagramsService],
standalone: true,
    selector: "app-container",
    template: `<ejs-diagram #diagram id="diagram" width="100%" height="580px" [getNodeDefaults] ='getNodeDefaults'>
        <e-nodes>
            <e-node id='node1' [offsetX]=150 [offsetY]=150 [shape]='shape'></e-node>
        </e-nodes>
    </ejs-diagram>`,
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    @ViewChild("diagram")
    public diagram?: DiagramComponent;
    public shape: BpmnShapeModel = {
        //Sets type as Bpmn and shape as activity
        type: 'Bpmn',
        shape: 'Activity',
        //Sets activity as SubProcess
        activity: {
          activity: 'SubProcess',
          //Sets the collapsed as true and type as Event
          subProcess: {
            collapsed: true,
            type: 'Transaction',
            //Sets transaction
            transaction: {
              success: {
                id: 'success',
                event: 'Start',
                trigger: 'None',
              },
              failure: {
                id: 'failure',
                event: 'ThrowingIntermediate',
                trigger: 'Error',
              },
              cancel: {
                id: 'cancel',
                event: 'End',
                trigger: 'Cancel',
              },
            },
          },
        },
      }
    
    public getNodeDefaults(node: NodeModel): NodeModel {
        node.height = 100;
        node.width = 100;
        return node;
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));