Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect Reverse #1230

Merged
merged 7 commits into from
Nov 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 70 additions & 96 deletions lib/features/modeling/BpmnLayouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,32 +22,53 @@ import {

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

var ATTACH_ORIENTATION_PADDING = -10,
philippfromme marked this conversation as resolved.
Show resolved Hide resolved
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() {}

inherits(BpmnLayouter, BaseLayouter);


BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
hints = hints || {};
if (!hints) {
hints = {};
}

var source = hints.source || connection.source,
target = hints.target || connection.target,
waypoints = connection.waypoints,
start = hints.connectionStart,
end = hints.connectionEnd;
waypoints = hints.waypoints || connection.waypoints,
connectionStart = hints.connectionStart,
connectionEnd = hints.connectionEnd;

var manhattanOptions,
updatedWaypoints;

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

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

// TODO(nikku): support vertical modeling
Expand All @@ -57,104 +78,76 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) {
is(connection, 'bpmn:DataAssociation')) {

if (waypoints && !isCompensationAssociation(source, target)) {
return [].concat([ start ], waypoints.slice(1, -1), [ end ]);
return [].concat([ connectionStart ], waypoints.slice(1, -1), [ connectionEnd ]);
}
}

// 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)
preferredLayouts: getBoundaryEventPreferredLayouts(source, target, connectionEnd)
};

} 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,
connectionStart,
connectionEnd,
waypoints,
manhattanOptions
));
}

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


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 @@ -164,7 +157,6 @@ function getMessageFlowPreserveDocking(source, target) {
}

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

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

// (3) docking event has precedence

if (is(target, 'bpmn:Event')) {
return 'target';
}
Expand All @@ -186,18 +177,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 @@ -210,24 +199,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 @@ -310,8 +281,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 @@ -332,20 +303,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 @@ -356,11 +330,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 @@ -369,7 +343,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 @@ -383,7 +357,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 @@ -400,8 +374,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
Loading