diff --git a/lib/features/modeling/BpmnLayouter.js b/lib/features/modeling/BpmnLayouter.js index b708e6a9..8eb96234 100644 --- a/lib/features/modeling/BpmnLayouter.js +++ b/lib/features/modeling/BpmnLayouter.js @@ -81,7 +81,7 @@ BpmnLayouter.prototype.layoutConnection = function(connection, hints) { if (source === target) { manhattanOptions = { - preferredLayouts: [ 'b:l' ] + preferredLayouts: getLoopPreferredLayout(source, connection) }; } else @@ -264,6 +264,22 @@ function isHorizontalOrientation(orientation) { return orientation === 'right' || orientation === 'left'; } +function getLoopPreferredLayout(source, connection) { + var waypoints = connection.waypoints; + + var orientation = waypoints && waypoints.length && getOrientation(waypoints[0], source); + + if (orientation === 'top') { + return [ 't:r' ]; + } else if (orientation === 'right') { + return [ 'r:b' ]; + } else if (orientation === 'left') { + return [ 'l:t' ]; + } + + return [ 'b:l' ]; +} + function getBoundaryEventPreferredLayouts(source, target, end) { var sourceMid = getMid(source), targetMid = getMid(target), diff --git a/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.flowElements.bpmn b/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.flowElements.bpmn index 0491d1be..b6c701f3 100644 --- a/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.flowElements.bpmn +++ b/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.flowElements.bpmn @@ -1,10 +1,13 @@ - + SequenceFlow_1 + SequenceFlow_2 + SequenceFlow_3 + SequenceFlow_4 @@ -14,6 +17,18 @@ + + SequenceFlow_2 + + + + SequenceFlow_3 + + + + SequenceFlow_4 + + @@ -57,14 +72,39 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.js b/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.js index 6b572347..d44bf068 100644 --- a/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.js +++ b/test/spec/features/modeling/layout/LayoutSequenceFlowSpec.js @@ -10,6 +10,8 @@ import { reconnectEnd } from './Helper'; +import { getMid } from 'diagram-js/lib/layout/LayoutUtil'; + import modelingModule from 'lib/features/modeling'; import coreModule from 'lib/core'; @@ -306,6 +308,85 @@ describe('features/modeling - layout', function() { ]); }); + + it('should NOT relayout loop', inject(function(elementRegistry) { + + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_1'), + task = elementRegistry.get('Task_1'); + + // when + reconnectEnd(sequenceFlow, task, getMid(task)); + + // then + expect(sequenceFlow).to.have.waypoints([ + { x: 382, y: 241 }, + { x: 559, y: 241 }, + { x: 559, y: 220 }, + { x: 382, y: 220 } + ]); + })); + + + it('should relayout loop (b:l)', inject(function(elementRegistry) { + + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_2'), + task = elementRegistry.get('Task_1'); + + // when + reconnectEnd(sequenceFlow, task, getMid(task)); + + // then + expect(sequenceFlow).to.have.waypoints([ + { x: 332, y: 260 }, + { x: 332, y: 280 }, + { x: 262, y: 280 }, + { x: 262, y: 220 }, + { x: 282, y: 220 } + ]); + })); + + + it('should relayout loop (l:t)', inject(function(elementRegistry) { + + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_3'), + task = elementRegistry.get('Task_1'); + + // when + reconnectEnd(sequenceFlow, task, getMid(task)); + + // then + expect(sequenceFlow).to.have.waypoints([ + { x: 282, y: 220 }, + { x: 262, y: 220 }, + { x: 262, y: 160 }, + { x: 332, y: 160 }, + { x: 332, y: 180 } + ]); + })); + + + it('should relayout loop (t:r)', inject(function(elementRegistry) { + + // given + var sequenceFlow = elementRegistry.get('SequenceFlow_4'), + task = elementRegistry.get('Task_1'); + + // when + reconnectEnd(sequenceFlow, task, getMid(task)); + + // then + expect(sequenceFlow).to.have.waypoints([ + { x: 332, y: 180 }, + { x: 332, y: 160 }, + { x: 402, y: 160 }, + { x: 402, y: 220 }, + { x: 382, y: 220 } + ]); + })); + });