Skip to content

Commit

Permalink
chore(layouter): refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Nov 6, 2019
1 parent 28ae1af commit 653cac9
Showing 1 changed file with 57 additions and 87 deletions.
144 changes: 57 additions & 87 deletions lib/features/modeling/BpmnLayouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,27 @@ import {

import { is } from '../../util/ModelUtil';

var ATTACH_ORIENTATION_PADDING = -10,
BOUNDARY_TO_HOST_THRESHOLD = 40;

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'
};

var BOUNDARY_TO_HOST_THRESHOLD = 40;

export default function BpmnLayouter() {}

Expand All @@ -45,11 +64,11 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
updatedWaypoints;

if (!start) {
start = getConnectionDocking(waypoints && waypoints[0], source);
start = getConnectionDocking(waypoints && waypoints[ 0 ], source);
}

if (!end) {
end = getConnectionDocking(waypoints && waypoints[waypoints.length - 1], target);
end = getConnectionDocking(waypoints && waypoints[ waypoints.length - 1 ], target);
}

// TODO(nikku): support vertical modeling
Expand All @@ -63,100 +82,70 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
}
}

// manhattan layout sequence / message flows
if (is(connection, 'bpmn:MessageFlow')) {
manhattanOptions = getMessageFlowManhattanOptions(source, target);
} else if (is(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(source, target)) {

} else


// layout all connection between flow elements h:h,
//
// except for
//
// (1) outgoing of BoundaryEvents -> layout based on attach orientation and target orientation
// (2) incoming / outgoing of Gateway -> v:h (outgoing), h:v (incoming)
// (3) loops from / to the same element
//
if (is(connection, 'bpmn:SequenceFlow') ||
isCompensationAssociation(source, target)) {

// layout all connection between flow elements h:h, except for
// (1) outgoing of boundary events -> layout based on attach orientation and target orientation
// (2) incoming/outgoing of gateways -> v:h for outgoing, h:v for incoming
// (3) loops
if (source === target) {
manhattanOptions = {
preferredLayouts: getLoopPreferredLayout(source, connection)
};
} else

if (is(source, 'bpmn:BoundaryEvent')) {

} else if (is(source, 'bpmn:BoundaryEvent')) {
manhattanOptions = {
preferredLayouts: getBoundaryEventPreferredLayouts(source, target, end)
};

} else

if (is(source, 'bpmn:Gateway')) {

} else if (is(source, 'bpmn:Gateway')) {
manhattanOptions = {
preferredLayouts: [ 'v:h' ]
};
} else

if (is(target, 'bpmn:Gateway')) {

} else if (is(target, 'bpmn:Gateway')) {
manhattanOptions = {
preferredLayouts: [ 'h:v' ]
};
}

else {
} else {
manhattanOptions = {
preferredLayouts: [ 'h:h' ]
};
}

}

if (manhattanOptions) {

manhattanOptions = assign(manhattanOptions, hints);

updatedWaypoints =
withoutRedundantPoints(
repairConnection(
source, target,
start, end,
waypoints,
manhattanOptions
)
);
updatedWaypoints = withoutRedundantPoints(repairConnection(
source, target,
start, end,
waypoints,
manhattanOptions
));
}

return updatedWaypoints || [ start, end ];
};


function getAttachOrientation(attachedElement) {
// helpers //////////

var hostElement = attachedElement.host,
padding = -10;
function getAttachOrientation(attachedElement) {
var hostElement = attachedElement.host;

return getOrientation(getMid(attachedElement), hostElement, padding);
return getOrientation(getMid(attachedElement), hostElement, ATTACH_ORIENTATION_PADDING);
}


function getMessageFlowManhattanOptions(source, target) {
return {
preferredLayouts: [ 'straight', 'v:v' ],
preserveDocking: getMessageFlowPreserveDocking(source, target)
};
}


function getMessageFlowPreserveDocking(source, target) {

// (1) docking element connected to participant has precedence

if (is(target, 'bpmn:Participant')) {
return 'source';
}
Expand All @@ -166,7 +155,6 @@ function getMessageFlowPreserveDocking(source, target) {
}

// (2) docking element connected to expanded sub-process has precedence

if (isExpandedSubProcess(target)) {
return 'source';
}
Expand All @@ -176,7 +164,6 @@ function getMessageFlowPreserveDocking(source, target) {
}

// (3) docking event has precedence

if (is(target, 'bpmn:Event')) {
return 'target';
}
Expand All @@ -188,18 +175,16 @@ function getMessageFlowPreserveDocking(source, target) {
return null;
}


function getConnectionDocking(point, shape) {
return point ? (point.original || point) : getMid(shape);
}

function isCompensationAssociation(source, target) {
return is(target, 'bpmn:Activity') &&
is(source, 'bpmn:BoundaryEvent') &&
target.businessObject.isForCompensation;
is(source, 'bpmn:BoundaryEvent') &&
target.businessObject.isForCompensation;
}


function isExpandedSubProcess(element) {
return is(element, 'bpmn:SubProcess') && isExpanded(element);
}
Expand All @@ -212,24 +197,6 @@ 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);

Expand Down Expand Up @@ -312,8 +279,8 @@ function getBoundaryEventPreferredLayouts(source, target, end) {
}

function getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end) {

var sourceLayout = orientationDirectionMapping[attachedToSide ? attachOrientation : getVerticalOrientation(attachOrientation)],
var orientation = attachedToSide ? attachOrientation : getVerticalOrientation(attachOrientation),
sourceLayout = orientationDirectionMapping[ orientation ],
targetLayout;

if (attachedToSide) {
Expand All @@ -334,20 +301,23 @@ function shouldConnectToSameSide(axis, source, target, end) {

return !(
areCloseOnAxis(axis, end, target, threshold) ||
areCloseOnAxis(axis, end, { x: target.x + target.width, y: target.y + target.height }, threshold) ||
areCloseOnAxis(axis, end, {
x: target.x + target.width,
y: target.y + target.height
}, threshold) ||
areCloseOnAxis(axis, end, getMid(source), threshold)
);
}

function areCloseOnAxis(axis, a, b, threshold) {
return Math.abs(a[axis] - b[axis]) < threshold;
return Math.abs(a[ axis ] - b[ axis ]) < threshold;
}

function getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide) {

// attached to either top, right, bottom or left side
if (attachedToSide) {
return orientationDirectionMapping[attachOrientation];
return orientationDirectionMapping[ attachOrientation ];
}

// attached to either top-right, top-left, bottom-right or bottom-left corner
Expand All @@ -358,11 +328,11 @@ function getBoundaryEventSourceLayout(attachOrientation, targetOrientation, atta
) || isOppositeOrientation(
getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation)
)) {
return orientationDirectionMapping[getVerticalOrientation(attachOrientation)];
return orientationDirectionMapping[ getVerticalOrientation(attachOrientation) ];
}

// fallback
return orientationDirectionMapping[getHorizontalOrientation(attachOrientation)];
return orientationDirectionMapping[ getHorizontalOrientation(attachOrientation) ];
}

function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide) {
Expand All @@ -371,7 +341,7 @@ function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, atta
if (attachedToSide) {
if (isHorizontalOrientation(attachOrientation)) {

// orientation is 'right' or 'left'
// orientation is right or left

// opposite horizontal orientation or same orientation
if (
Expand All @@ -385,7 +355,7 @@ function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, atta
return 'v';
} else {

// orientation is 'top' or 'bottom'
// orientation is top or bottom

// opposite vertical orientation or same orientation
if (
Expand All @@ -402,8 +372,8 @@ function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, atta

// 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'
// orientation is right, left
// or same vertical orientation but also right or left
if (isHorizontalOrientation(targetOrientation) ||
(isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) &&
getHorizontalOrientation(targetOrientation))) {
Expand Down

0 comments on commit 653cac9

Please sign in to comment.