Improve Workflow Driven
Applications with Ext JS
Draw Package
Jovan Cvetkovic
What is Workflow?
• Sequence of processes
• Execution and automation of business processes
• Coordinating tasks between people
2
Business Process Management
• Business solution approach
• BPM Software / Workflow application
Workflow application
Workflow Application
What is workflow application?
• Graphical designer
Workflow Application
Graphical designer
• Back-end
• Front-end
Workflow Application
• Activiti (Software)
• BPMN (Business Process Model and
Notation)
Back-end
Workflow Application
• Draw package
• Implementation
• Designer
Front-end
Draw package
Draw Package
• Basic shapes (rectangle, circle, text, image,
path…)
• Transformations (translate, rotate, scale)
Implementation
Implementation
• Graphical designer
• Role model (data view)
Idea
Implementation
Final goal
Graphical designer
Implementation
• Store / Data model
• View
Data view role model
Ext.define('App.workflow.data.Model', {
extend: 'Ext.data.Model',
fields: [{
// Draw Data
name: 'translationX'
}, {
name: 'translationY'
}, {
name: 'width'
}, {
name: 'height'
}, {
// Activity Data
name: 'stepName'
}, {
name: 'description'
}, {
name: 'type'
}, {
name: 'configuration'
}, {
name: 'outgoingConfiguration'
}]
});
• Draw graphic data
• Activity workflow data
Implementation
Workflow data model
Implementation
• Store events
• Selection model (simple, multi, region)
• Plugins (events, drag & drop, pan)
View / draw
component
registerStoreListeners: function(){
this.store.on({
add: 'onStoreAdd',
load: 'onStoreLoad',
remove: 'onStoreRemove',
update: 'onStoreChange'
});
},
onStoreAdd: function(record){
var surface = this.getSurface();
var sprite = record.getData();
surface.add(sprite);
}
• Load (add all steps)
• Add (add step)
• Change (change step)
• Remove (remove step)
Implementation
Store events
onItemSelect: function(record){
var sprite = this.findSprite(record);
sprite.setAttributes({
selected: true
});
}
getRegion: function(){
var bbox = this.getBBox();
var top = bbox.x;
var right = bbox.x + bbox.width;
var bottom = bbox.y + bbox.height;
var left = bbox.y;
return Ext.create('Ext.util.Region', top, right, bottom, left);
}
• Select
o Simple selection
o Multi selection
o Region selection
• Deselect
• Deselect all
Selection model
Implementation
Implementation
Select by drawing a region
Region selection
Implementation
• Events (mouse events, click, hover…)
• Drag & Drop
• Pan (move surface)
Plugins
Implementation
• Mandatory (enables use of touch and click events)
• Out of the box
Events plugin
config: {
gestures: {
minDistance: 2,
dragstart: 'onDragStart',
drag: 'onDrag',
dragend: 'onDragEnd'
}
}
• Start drag
• Drag element
• End drag
Implementation
Drag & drop plugin
onDragStart: function(e){
var draw = this.getDraw();
var sprite = draw.getItemFromEvent(e);
var ghost = sprite.ghost;
var surface = draw.getSurface();
var xy = surface.getEventXY(e);
this.startX = xy[0];
this.startY = xy[1];
this.translationX = sprite.attr.translationX;
this.translationY = sprite.attr.translationY;
ghost = Ext.apply(ghost, {
translationX: this.translationX,
translationY: this.translationY
});
surface.add(ghost);
surface.renderFrame();
}
• Ghost element
• Start position
Start drag
Implementation
onDrag: function(e){
var draw = this.getDraw();
var surface = draw.getSurface();
var xy = surface.getEventXY(e);
var deltaX = xy[0] - this.startX;
var deltaY = xy[1] - this.startY;
var positionX = this.translationX + deltaX;
var positionY = this.translationY + deltaY;
this.ghost.setAttributes({
translationX: positionX,
translationY: positionY
});
surface.renderFrame();
}
Implementation
Drag
• Move vs translate
onDragEnd: function(e){
var draw = this.getDraw();
var item = draw.getItemFromEvent(e);
var surface = draw.getSurface();
var translation = this.getRulerSnapPosition();
item.record.set(translation);
this.ghost.destroy(true);
delete this.ghost;
surface.renderFrame();
}
Implementation
End drag
• Snap to position
• Set new coordinates
updateViewBox: function(x, y){
var draw = this.getDraw();
var surface = draw.getSurface();
var viewBox = surface.getViewBox();
var updatedViewBox = [
(0 - x),
(0 - y),
viewBox.width,
viewBox.height
].join();
surface.setViewBox(updatedViewBox);
}
Implementation
Pan plugin
• Draw surface
• ViewBox
Implementation
ViewBox
Designer
Designer
• Basic elements
• Composite elements
Sprite
inheritableStatics: {
def: {
processors: {
selected: 'bool'
},
dirtyTriggers: {
selected: 'setSelected'
},
defaults: {
selected: false
},
updaters: {
setSelected: function(attr){
var stroke = this.baseClr;
if (attr.selected) {
stroke = this.selectedClr;
}
this.setAttributes({
strokeStyle: strokeStyle
});
this.redraw();
}
}
}
}
Designer
Processors & updaters
• Attribute
• Processor
• Trigger
• Updater
Designer
• Start
• Automatic
• Human
• Gate
• Transition
• End
Designer steps
Designer
Final view
SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package - Jovan Cvetkovic

SenchaCon 2016: Improve Workflow Driven Applications with Ext JS Draw Package - Jovan Cvetkovic