feat(modeling/BpmnLayouter): handle boundary events
This adds proper connection layouting for sequence flows leaving from boundary events. If needed, such connections will be layoute with an U-turn. Closes #467
This commit is contained in:
parent
b3c05b6949
commit
220c0a73f3
|
@ -7,7 +7,8 @@ import {
|
||||||
import BaseLayouter from 'diagram-js/lib/layout/BaseLayouter';
|
import BaseLayouter from 'diagram-js/lib/layout/BaseLayouter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
repairConnection
|
repairConnection,
|
||||||
|
withoutRedundantPoints
|
||||||
} from 'diagram-js/lib/layout/ManhattanLayout';
|
} from 'diagram-js/lib/layout/ManhattanLayout';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -15,10 +16,6 @@ import {
|
||||||
getOrientation
|
getOrientation
|
||||||
} from 'diagram-js/lib/layout/LayoutUtil';
|
} from 'diagram-js/lib/layout/LayoutUtil';
|
||||||
|
|
||||||
import {
|
|
||||||
pointsOnLine
|
|
||||||
} from 'diagram-js/lib/util/Geometry';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isExpanded
|
isExpanded
|
||||||
} from '../../util/DiUtil';
|
} from '../../util/DiUtil';
|
||||||
|
@ -32,7 +29,6 @@ inherits(BpmnLayouter, BaseLayouter);
|
||||||
|
|
||||||
|
|
||||||
BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
|
BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
|
||||||
|
|
||||||
hints = hints || {};
|
hints = hints || {};
|
||||||
|
|
||||||
var source = connection.source,
|
var source = connection.source,
|
||||||
|
@ -107,29 +103,18 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
|
||||||
//
|
//
|
||||||
// except for
|
// except for
|
||||||
//
|
//
|
||||||
// (1) outgoing of BoundaryEvents -> layout h:v or v:h based on attach orientation
|
// (1) outgoing of BoundaryEvents -> layout based on attach orientation and target orientation
|
||||||
// (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming)
|
// (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming)
|
||||||
//
|
//
|
||||||
if (is(connection, 'bpmn:SequenceFlow') ||
|
if (is(connection, 'bpmn:SequenceFlow') ||
|
||||||
isCompensationAssociation(connection)) {
|
isCompensationAssociation(connection)) {
|
||||||
|
|
||||||
// make sure boundary event connections do
|
|
||||||
// not look ugly =:>
|
|
||||||
if (is(source, 'bpmn:BoundaryEvent')) {
|
if (is(source, 'bpmn:BoundaryEvent')) {
|
||||||
|
|
||||||
var orientation = getAttachOrientation(source);
|
manhattanOptions = {
|
||||||
|
preferredLayouts: getBoundaryEventPreferredLayouts(source, target)
|
||||||
|
};
|
||||||
|
|
||||||
if (/left|right/.test(orientation)) {
|
|
||||||
manhattanOptions = {
|
|
||||||
preferredLayouts: [ 'h:v' ]
|
|
||||||
};
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (/top|bottom/.test(orientation)) {
|
|
||||||
manhattanOptions = {
|
|
||||||
preferredLayouts: [ 'v:h' ]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
|
|
||||||
if (is(source, 'bpmn:Gateway')) {
|
if (is(source, 'bpmn:Gateway')) {
|
||||||
|
@ -146,7 +131,6 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply horizontal love <3
|
|
||||||
else {
|
else {
|
||||||
manhattanOptions = {
|
manhattanOptions = {
|
||||||
preferredLayouts: [ 'h:h' ]
|
preferredLayouts: [ 'h:h' ]
|
||||||
|
@ -159,25 +143,14 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
|
||||||
manhattanOptions = assign(manhattanOptions, hints);
|
manhattanOptions = assign(manhattanOptions, hints);
|
||||||
|
|
||||||
updatedWaypoints =
|
updatedWaypoints =
|
||||||
repairConnection(
|
withoutRedundantPoints(
|
||||||
source, target,
|
repairConnection(
|
||||||
start, end,
|
source, target,
|
||||||
waypoints,
|
start, end,
|
||||||
manhattanOptions);
|
waypoints,
|
||||||
|
manhattanOptions
|
||||||
// filter un-needed waypoints that may be the result of
|
)
|
||||||
// bundle collapsing
|
);
|
||||||
updatedWaypoints = updatedWaypoints && updatedWaypoints.reduce(function(points, p, idx) {
|
|
||||||
|
|
||||||
var previous = points[points.length - 1],
|
|
||||||
next = updatedWaypoints[idx + 1];
|
|
||||||
|
|
||||||
if (!pointsOnLine(previous, next, p, 0)) {
|
|
||||||
points.push(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
return points;
|
|
||||||
}, []);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedWaypoints || [ start, end ];
|
return updatedWaypoints || [ start, end ];
|
||||||
|
@ -210,4 +183,151 @@ function isCompensationAssociation(connection) {
|
||||||
|
|
||||||
function isExpandedSubProcess(element) {
|
function isExpandedSubProcess(element) {
|
||||||
return is(element, 'bpmn:SubProcess') && isExpanded(element);
|
return is(element, 'bpmn:SubProcess') && isExpanded(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSame(a, b) {
|
||||||
|
return a === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAnyOrientation(orientation, orientations) {
|
||||||
|
return orientations.indexOf(orientation) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var oppositeOrientationMapping = {
|
||||||
|
'top': 'bottom',
|
||||||
|
'top-right': 'bottom-left',
|
||||||
|
'top-left': 'bottom-right',
|
||||||
|
'right': 'left',
|
||||||
|
'bottom': 'top',
|
||||||
|
'bottom-right': 'top-left',
|
||||||
|
'bottom-left': 'top-right',
|
||||||
|
'left': 'right'
|
||||||
|
};
|
||||||
|
|
||||||
|
var orientationDirectionMapping = {
|
||||||
|
top: 't',
|
||||||
|
right: 'r',
|
||||||
|
bottom: 'b',
|
||||||
|
left: 'l'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getHorizontalOrientation(orientation) {
|
||||||
|
var matches = /right|left/.exec(orientation);
|
||||||
|
|
||||||
|
return matches && matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVerticalOrientation(orientation) {
|
||||||
|
var matches = /top|bottom/.exec(orientation);
|
||||||
|
|
||||||
|
return matches && matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOppositeOrientation(a, b) {
|
||||||
|
return oppositeOrientationMapping[a] === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOppositeHorizontalOrientation(a, b) {
|
||||||
|
var horizontalOrientation = getHorizontalOrientation(a);
|
||||||
|
|
||||||
|
var oppositeHorizontalOrientation = oppositeOrientationMapping[horizontalOrientation];
|
||||||
|
|
||||||
|
return b.indexOf(oppositeHorizontalOrientation) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOppositeVerticalOrientation(a, b) {
|
||||||
|
var verticalOrientation = getVerticalOrientation(a);
|
||||||
|
|
||||||
|
var oppositeVerticalOrientation = oppositeOrientationMapping[verticalOrientation];
|
||||||
|
|
||||||
|
return b.indexOf(oppositeVerticalOrientation) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHorizontalOrientation(orientation) {
|
||||||
|
return orientation === 'right' || orientation === 'left';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBoundaryEventPreferredLayouts(source, target) {
|
||||||
|
var sourceMid = getMid(source),
|
||||||
|
targetMid = getMid(target),
|
||||||
|
attachOrientation = getAttachOrientation(source),
|
||||||
|
sourceLayout,
|
||||||
|
targetlayout;
|
||||||
|
|
||||||
|
var isLoop = isSame(source.host, target);
|
||||||
|
|
||||||
|
var attachedToSide = isAnyOrientation(attachOrientation, [ 'top', 'right', 'bottom', 'left' ]);
|
||||||
|
|
||||||
|
var isHorizontalAttachOrientation = isHorizontalOrientation(attachOrientation);
|
||||||
|
|
||||||
|
var targetOrientation = getOrientation(targetMid, sourceMid, {
|
||||||
|
x: source.width / 2 + target.width / 2,
|
||||||
|
y: source.height / 2 + target.height / 2
|
||||||
|
});
|
||||||
|
|
||||||
|
// source layout
|
||||||
|
|
||||||
|
// attached to either top, right, bottom or left side
|
||||||
|
if (attachedToSide) {
|
||||||
|
|
||||||
|
sourceLayout = orientationDirectionMapping[
|
||||||
|
isHorizontalAttachOrientation ?
|
||||||
|
getHorizontalOrientation(attachOrientation) :
|
||||||
|
getVerticalOrientation(attachOrientation)
|
||||||
|
];
|
||||||
|
|
||||||
|
} else
|
||||||
|
|
||||||
|
// attached to either top-right, top-left, bottom-right or bottom-left corner
|
||||||
|
{
|
||||||
|
|
||||||
|
// loop, same vertical or opposite horizontal orientation
|
||||||
|
if (isLoop ||
|
||||||
|
isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) ||
|
||||||
|
isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))
|
||||||
|
) {
|
||||||
|
sourceLayout = orientationDirectionMapping[getVerticalOrientation(attachOrientation)];
|
||||||
|
} else {
|
||||||
|
sourceLayout = orientationDirectionMapping[getHorizontalOrientation(attachOrientation)];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// target layout
|
||||||
|
|
||||||
|
// attached to either top, right, bottom or left side
|
||||||
|
if (attachedToSide) {
|
||||||
|
|
||||||
|
// loop or opposite horizontal/vertical orientation
|
||||||
|
if (
|
||||||
|
isLoop ||
|
||||||
|
(isHorizontalAttachOrientation ?
|
||||||
|
isOppositeHorizontalOrientation(attachOrientation, targetOrientation) :
|
||||||
|
isOppositeVerticalOrientation(attachOrientation, targetOrientation))
|
||||||
|
) {
|
||||||
|
targetlayout = isHorizontalAttachOrientation ? 'h' : 'v';
|
||||||
|
} else {
|
||||||
|
targetlayout = isHorizontalAttachOrientation ? 'v' : 'h';
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
|
||||||
|
// attached to either top-right, top-left, bottom-right or bottom-left corner
|
||||||
|
{
|
||||||
|
|
||||||
|
// orientation is 'right', 'left'
|
||||||
|
// or same vertical orientation but also 'right' or 'left'
|
||||||
|
if (
|
||||||
|
isHorizontalOrientation(targetOrientation) ||
|
||||||
|
(isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) &&
|
||||||
|
getHorizontalOrientation(targetOrientation))
|
||||||
|
) {
|
||||||
|
targetlayout = 'h';
|
||||||
|
} else {
|
||||||
|
targetlayout = 'v';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ sourceLayout + ':' + targetlayout ];
|
||||||
}
|
}
|
|
@ -1,64 +1,44 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.16.0">
|
||||||
<bpmn:process id="Process_1" isExecutable="false">
|
<bpmn:process id="Process_1" isExecutable="false">
|
||||||
|
<bpmn:task id="Task_Left" />
|
||||||
<bpmn:subProcess id="SubProcess" />
|
<bpmn:subProcess id="SubProcess" />
|
||||||
<bpmn:boundaryEvent id="BoundaryEvent_D" name="D" attachedToRef="SubProcess" />
|
<bpmn:task id="Task_Right" />
|
||||||
<bpmn:boundaryEvent id="BoundaryEvent_C" name="C" attachedToRef="SubProcess" />
|
<bpmn:boundaryEvent id="BoundaryEvent_TopLeft" attachedToRef="SubProcess" />
|
||||||
<bpmn:boundaryEvent id="BoundaryEvent_B" name="B" attachedToRef="SubProcess" />
|
<bpmn:boundaryEvent id="BoundaryEvent_BottomRight" attachedToRef="SubProcess" />
|
||||||
<bpmn:boundaryEvent id="BoundaryEvent_A" name="A" attachedToRef="SubProcess" />
|
<bpmn:boundaryEvent id="BoundaryEvent_BottomLeft" attachedToRef="SubProcess" />
|
||||||
<bpmn:task id="Task_1" name="1" />
|
<bpmn:boundaryEvent id="BoundaryEvent_TopRight" attachedToRef="SubProcess" />
|
||||||
<bpmn:task id="Task_2" name="2" />
|
<bpmn:task id="Task_Bottom" />
|
||||||
<bpmn:task id="Task_3" name="3" />
|
<bpmn:task id="Task_Top" />
|
||||||
<bpmn:task id="Task_4" name="4" />
|
|
||||||
<bpmn:task id="Task_5" name="5" />
|
|
||||||
<bpmn:task id="Task_6" name="6" />
|
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||||
<bpmndi:BPMNShape id="SubProcess_di" bpmnElement="SubProcess" isExpanded="true">
|
<bpmndi:BPMNShape id="Task_0b6k3xo_di" bpmnElement="Task_Left">
|
||||||
<dc:Bounds x="505" y="258" width="350" height="200" />
|
<dc:Bounds x="0" y="350" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="BoundaryEvent_D_di" bpmnElement="BoundaryEvent_D">
|
<bpmndi:BPMNShape id="SubProcess_12qmapm_di" bpmnElement="SubProcess" isExpanded="true">
|
||||||
<dc:Bounds x="797" y="440" width="36" height="36" />
|
<dc:Bounds x="300" y="300" width="350" height="200" />
|
||||||
<bpmndi:BPMNLabel>
|
|
||||||
<dc:Bounds x="744" y="424" width="90" height="20" />
|
|
||||||
</bpmndi:BPMNLabel>
|
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="BoundaryEvent_C_di" bpmnElement="BoundaryEvent_C">
|
<bpmndi:BPMNShape id="Task_174r9fd_di" bpmnElement="Task_Right">
|
||||||
<dc:Bounds x="837" y="275" width="36" height="36" />
|
<dc:Bounds x="850" y="350" width="100" height="80" />
|
||||||
<bpmndi:BPMNLabel>
|
|
||||||
<dc:Bounds x="775" y="284" width="90" height="20" />
|
|
||||||
</bpmndi:BPMNLabel>
|
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="BoundaryEvent_B_di" bpmnElement="BoundaryEvent_B">
|
<bpmndi:BPMNShape id="BoundaryEvent_0s0nl1k_di" bpmnElement="BoundaryEvent_TopLeft">
|
||||||
<dc:Bounds x="568" y="240" width="36" height="36" />
|
<dc:Bounds x="282" y="320" width="36" height="36" />
|
||||||
<bpmndi:BPMNLabel>
|
|
||||||
<dc:Bounds x="540" y="280" width="90" height="20" />
|
|
||||||
</bpmndi:BPMNLabel>
|
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="BoundaryEvent_A_di" bpmnElement="BoundaryEvent_A">
|
<bpmndi:BPMNShape id="BoundaryEvent_0nomac7_di" bpmnElement="BoundaryEvent_BottomRight">
|
||||||
<dc:Bounds x="487" y="399" width="36" height="36" />
|
<dc:Bounds x="632" y="450" width="36" height="36" />
|
||||||
<bpmndi:BPMNLabel>
|
|
||||||
<dc:Bounds x="495" y="407" width="90" height="20" />
|
|
||||||
</bpmndi:BPMNLabel>
|
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
|
<bpmndi:BPMNShape id="BoundaryEvent_1spolhy_di" bpmnElement="BoundaryEvent_BottomLeft">
|
||||||
<dc:Bounds x="287" y="354" width="100" height="80" />
|
<dc:Bounds x="282" y="482" width="36" height="36" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="Task_2_di" bpmnElement="Task_2">
|
<bpmndi:BPMNShape id="BoundaryEvent_13iwzlu_di" bpmnElement="BoundaryEvent_TopRight">
|
||||||
<dc:Bounds x="362" y="503" width="100" height="80" />
|
<dc:Bounds x="632" y="282" width="36" height="36" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="Task_3_di" bpmnElement="Task_3">
|
<bpmndi:BPMNShape id="Task_0ygk7bh_di" bpmnElement="Task_Bottom">
|
||||||
<dc:Bounds x="378" y="122" width="100" height="80" />
|
<dc:Bounds x="400" y="650" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNShape id="Task_4_di" bpmnElement="Task_4">
|
<bpmndi:BPMNShape id="Task_1bc634w_di" bpmnElement="Task_Top">
|
||||||
<dc:Bounds x="536" y="81" width="100" height="80" />
|
<dc:Bounds x="400" y="0" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
|
||||||
<bpmndi:BPMNShape id="Task_5_di" bpmnElement="Task_5">
|
|
||||||
<dc:Bounds x="966" y="175" width="100" height="80" />
|
|
||||||
</bpmndi:BPMNShape>
|
|
||||||
<bpmndi:BPMNShape id="Task_6_di" bpmnElement="Task_6">
|
|
||||||
<dc:Bounds x="991" y="443" width="100" height="80" />
|
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
</bpmndi:BPMNPlane>
|
</bpmndi:BPMNPlane>
|
||||||
</bpmndi:BPMNDiagram>
|
</bpmndi:BPMNDiagram>
|
||||||
|
|
|
@ -31,14 +31,139 @@ describe('features/modeling - layout', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe.skip('overall experience, boundary events', function() {
|
describe('boundary events', function() {
|
||||||
|
|
||||||
var diagramXML = require('./LayoutSequenceFlowSpec.boundaryEvents.bpmn');
|
var diagramXML = require('./LayoutSequenceFlowSpec.boundaryEvents.bpmn');
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(diagramXML, { modules: Modeler.prototype._modules }));
|
var testModules = [ coreModule, modelingModule ];
|
||||||
|
|
||||||
|
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
||||||
|
|
||||||
|
|
||||||
it('should feel awesome', inject(function() { }));
|
describe('loops', function() {
|
||||||
|
|
||||||
|
it('attached top right', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopRight', 'SubProcess');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 300 }, x: 650, y: 282 },
|
||||||
|
{ x: 650, y: 262 },
|
||||||
|
{ x: 475, y: 262 },
|
||||||
|
{ original: { x: 475, y: 400 }, x: 475, y: 300 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached bottom right', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_BottomRight', 'SubProcess');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 468 }, x: 668, y: 468 },
|
||||||
|
{ x: 688, y: 468 },
|
||||||
|
{ x: 688, y: 400 },
|
||||||
|
{ original: { x: 475, y: 400 }, x: 650, y: 400 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached bottom left', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_BottomLeft', 'SubProcess');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 300, y: 500 }, x: 300, y: 518 },
|
||||||
|
{ x: 300, y: 538 },
|
||||||
|
{ x: 475, y: 538 },
|
||||||
|
{ original: { x: 475, y: 400 }, x: 475, y: 500 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached top left', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopLeft', 'SubProcess');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 300, y: 338 }, x: 282, y: 338 },
|
||||||
|
{ x: 262, y: 338 },
|
||||||
|
{ x: 262, y: 400 },
|
||||||
|
{ original: { x: 475, y: 400 }, x: 300, y: 400 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('non-loops', function() {
|
||||||
|
|
||||||
|
it('attached top right, orientation top', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopRight', 'Task_Top');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 300 }, x: 650, y: 282 },
|
||||||
|
{ x: 650, y: 40 },
|
||||||
|
{ original: { x: 450, y: 40 }, x: 500, y: 40 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached top right, orientation right', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopRight', 'Task_Right');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 300 }, x: 668, y: 300 },
|
||||||
|
{ x: 900, y: 300 },
|
||||||
|
{ original: { x: 900, y: 390 }, x: 900, y: 350 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached top right, orientation bottom', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopRight', 'Task_Bottom');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 300 }, x: 650, y: 282 },
|
||||||
|
{ x: 650, y: 262 },
|
||||||
|
{ x: 450, y: 262 },
|
||||||
|
{ original: { x: 450, y: 690 }, x: 450, y: 650 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('attached top right, orientation left', function() {
|
||||||
|
|
||||||
|
// when
|
||||||
|
var connection = connect('BoundaryEvent_TopRight', 'Task_Left');
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(connection).to.have.waypoints([
|
||||||
|
{ original: { x: 650, y: 300 }, x: 650, y: 282 },
|
||||||
|
{ x: 650, y: 262 },
|
||||||
|
{ x: 50, y: 262 },
|
||||||
|
{ original: { x: 50, y: 390 }, x: 50, y: 350 }
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -210,113 +335,4 @@ describe('features/modeling - layout', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('boundary events', function() {
|
|
||||||
|
|
||||||
var diagramXML = require('./LayoutSequenceFlowSpec.boundaryEvents.bpmn');
|
|
||||||
|
|
||||||
var testModules = [ coreModule, modelingModule ];
|
|
||||||
|
|
||||||
beforeEach(bootstrapModeler(diagramXML, { modules: testModules }));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout h:h connecting BoundaryEvent -> left Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_A', 'Task_1');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 505, y: 417 }, x: 487, y: 417 },
|
|
||||||
{ x: 437, y: 417 },
|
|
||||||
{ x: 437, y: 394 },
|
|
||||||
{ original: { x: 337, y: 394 }, x: 387, y: 394 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout h:v connecting BoundaryEvent -> bottom-left Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_A', 'Task_2');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 505, y: 417 }, x: 487, y: 417 },
|
|
||||||
{ x: 412, y: 417 },
|
|
||||||
{ original: { x: 412, y: 543 }, x: 412, y: 503 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout h:v connecting BoundaryEvent -> top-right Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_A', 'Task_5');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 505, y: 417 }, x: 523, y: 417 },
|
|
||||||
{ x: 1016, y: 417 },
|
|
||||||
{ original: { x: 1016, y: 215 }, x: 1016, y: 255 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout v:v connecting BoundaryEvent -> top Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_B', 'Task_4');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 586, y: 258 }, x: 586, y: 240 },
|
|
||||||
{ original: { x: 586, y: 121 }, x: 586, y: 161 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout v:h connecting BoundaryEvent -> top-left Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_B', 'Task_3');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 586, y: 258 }, x: 586, y: 240 },
|
|
||||||
{ x: 586, y: 162 },
|
|
||||||
{ original: { x: 428, y: 162 }, x: 478, y: 162 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout h:v connecting BoundaryEvent -> bottom-right Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_C', 'Task_6');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 855, y: 293 }, x: 873, y: 293 },
|
|
||||||
{ x: 1041, y: 293 },
|
|
||||||
{ original: { x: 1041, y: 483 }, x: 1041, y: 443 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
|
||||||
it('should layout v:h connecting BoundaryEvent -> bottom-left Task', inject(function() {
|
|
||||||
|
|
||||||
// when
|
|
||||||
var connection = connect('BoundaryEvent_D', 'Task_2');
|
|
||||||
|
|
||||||
// then
|
|
||||||
expect(connection).to.have.waypoints([
|
|
||||||
{ original: { x: 815, y: 458 }, x: 815, y: 476 },
|
|
||||||
{ x: 815, y: 543 },
|
|
||||||
{ original: { x: 412, y: 543 }, x: 462, y: 543 }
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue