feat(snapping): add initial snapping for associations

Snap to target mid when creating associations.

Closes #782
This commit is contained in:
pedesen 2018-04-11 11:53:22 +02:00 committed by Nico Rehwaldt
parent 1f71f7c6ba
commit fcd1e2f12c
3 changed files with 117 additions and 2 deletions

View File

@ -167,8 +167,14 @@ export default function BpmnSnapping(eventBus, canvas, bpmnRules, elementRegistr
context.initialSourcePosition = context.sourcePosition; context.initialSourcePosition = context.sourcePosition;
} }
if (target && connection.type === 'bpmn:SequenceFlow') { if (
target && (
connection.type === 'bpmn:Association' ||
connection.type === 'bpmn:DataOutputAssociation' ||
connection.type === 'bpmn:DataInputAssociation' ||
connection.type === 'bpmn:SequenceFlow'
)
) {
// snap source // snap source
context.sourcePosition = mid(source); context.sourcePosition = mid(source);

View File

@ -7,9 +7,12 @@
<bpmn:process id="Process_1" isExecutable="false"> <bpmn:process id="Process_1" isExecutable="false">
<bpmn:startEvent id="StartEvent_1" /> <bpmn:startEvent id="StartEvent_1" />
<bpmn:task id="Task_1" /> <bpmn:task id="Task_1" />
<bpmn:dataObjectReference id="DataObjectReference_1" dataObjectRef="DataObject_1" />
<bpmn:dataObject id="DataObject_1" />
</bpmn:process> </bpmn:process>
<bpmn:process id="Process_1e043dv" isExecutable="false"> <bpmn:process id="Process_1e043dv" isExecutable="false">
<bpmn:task id="Task_2" /> <bpmn:task id="Task_2" />
<bpmn:dataStoreReference id="DataStoreReference_1" />
</bpmn:process> </bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
@ -31,6 +34,18 @@
<bpmndi:BPMNShape id="Task_0ythg78_di" bpmnElement="Task_2"> <bpmndi:BPMNShape id="Task_0ythg78_di" bpmnElement="Task_2">
<dc:Bounds x="240" y="200" width="100" height="80" /> <dc:Bounds x="240" y="200" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="DataStoreReference_1_di" bpmnElement="DataStoreReference_1">
<dc:Bounds x="101" y="215" width="50" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="81" y="269" width="90" height="12" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="DataObjectReference_1_di" bpmnElement="DataObjectReference_1">
<dc:Bounds x="196" y="93" width="36" height="50" />
<bpmndi:BPMNLabel>
<dc:Bounds x="214" y="147" width="0" height="12" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane> </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram> </bpmndi:BPMNDiagram>
</bpmn:definitions> </bpmn:definitions>

View File

@ -806,6 +806,100 @@ describe('features/snapping - BpmnSnapping', function() {
})); }));
it('should snap data output association on connect', inject(function(connect, dragging, elementRegistry) {
// given
var startEvent = elementRegistry.get('StartEvent_1'),
dataObjectReference = elementRegistry.get('DataObjectReference_1');
var mid = { x: dataObjectReference.x + dataObjectReference.width / 2, y: dataObjectReference.y + dataObjectReference.height / 2 };
// when
connect.start(canvasEvent({ x: 0, y: 0 }), startEvent);
dragging.hover({
element: dataObjectReference,
gfx: elementRegistry.getGraphics(dataObjectReference)
});
dragging.move(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }));
dragging.end();
// then
var expected = [
{
original:
{
x: startEvent.x + startEvent.width / 2,
y: startEvent.y + startEvent.height / 2
},
x: startEvent.x + startEvent.width,
y: startEvent.y + startEvent.height / 2
},
{
original:
{
x: dataObjectReference.x + dataObjectReference.width / 2,
y: dataObjectReference.y + dataObjectReference.height / 2
},
x: dataObjectReference.x,
y: dataObjectReference.y + dataObjectReference.height / 2
}
];
expect(startEvent.outgoing[0].waypoints).to.eql(expected);
}));
it('should snap data input association on connect', inject(function(connect, dragging, elementRegistry) {
// given
var dataStoreReference = elementRegistry.get('DataStoreReference_1'),
task = elementRegistry.get('Task_2');
var mid = { x: task.x + task.width / 2, y: task.y + task.height / 2 };
// when
connect.start(canvasEvent({ x: 0, y: 0 }), dataStoreReference);
dragging.hover({
element: task,
gfx: elementRegistry.getGraphics(task)
});
dragging.move(canvasEvent({ x: mid.x + 10, y: mid.y + 10 }));
dragging.end();
// then
var expected = [
{
original:
{
x: dataStoreReference.x + dataStoreReference.width / 2,
y: dataStoreReference.y + dataStoreReference.height / 2
},
x: dataStoreReference.x + dataStoreReference.width,
y: dataStoreReference.y + dataStoreReference.height / 2
},
{
original:
{
x: task.x + task.width / 2,
y: task.y + task.height / 2
},
x: task.x,
y: task.y + task.height / 2
}
];
expect(dataStoreReference.outgoing[0].waypoints).to.eql(expected);
}));
it('should NOT snap message flow on global connect', inject(function(connect, dragging, elementRegistry) { it('should NOT snap message flow on global connect', inject(function(connect, dragging, elementRegistry) {
// given // given