Connector lines for the bpmn flow overlaps, I use bpmn-moddle for this and use a function that reconnectElements. How to avoid overlapping of the arrows?
Code for reconnectElements:
const elementRegistry = ModelerService.getModeler().get('elementRegistry');
const connections = elementRegistry.filter((element) => element.waypoints);
// Create a map to store node positions by ID
const nodePositions = new Map();
// Create an array to store connections for each target element
const targetElementConnections = new Map();
// Initialize an offset to adjust connection positions
let yOffset = 0;
let nodes = [];
// Iterate through connections and distribute them
connections.forEach((connection) => {
if (FlowLayoutService.allowReConnect(connection)) {
const sourceNodeId = connection.source.id;
const targetNodeId = connection.target.id;
// Add source and target nodes to the nodes array if not already added
if (!nodePositions.has(sourceNodeId)) {
nodes.push(connection.source);
nodePositions.set(sourceNodeId, { x: connection.source.x, y: connection.source.y });
}
if (!nodePositions.has(targetNodeId)) {
nodes.push(connection.target);
nodePositions.set(targetNodeId, { x: connection.target.x, y: connection.target.y });
}
// Calculate the new waypoints for the connection to avoid overlap
const targetConnections = targetElementConnections.get(targetNodeId) || [];
const yOffsetMultiplier = targetConnections.length > 0 ? 1 : 0; // Offset multiplier for vertical separation
// Calculate the new waypoints for the connection
const waypoints = connection.waypoints.map((waypoint, index) => {
if (index === 0 || index === connection.waypoints.length - 1) {
return waypoint; // Preserve source and target waypoints
}
// Distribute connections vertically with an offset
const sourceNodePosition = nodePositions.get(sourceNodeId);
const targetNodePosition = nodePositions.get(targetNodeId);
const yOffsetDelta = (yOffsetMultiplier + index - 1) * 20; // Adjust the vertical spacing as needed
return {
x: waypoint.x + sourceNodePosition.x - targetNodePosition.x,
y: waypoint.y + sourceNodePosition.y - targetNodePosition.y + yOffsetDelta,
};
});
// Update the connection with the new waypoints
const modeling = ModelerService.getModeler().get('modeling');
modeling.updateWaypoints(connection, waypoints);
modeling.layoutConnection(connection, {
connectionStart: waypoints[0],
connectionEnd: waypoints[waypoints.length - 1],
});
// Store this connection for the target element
if (!targetElementConnections.has(targetNodeId)) {
targetElementConnections.set(targetNodeId, [connection]);
} else {
targetElementConnections.get(targetNodeId).push(connection);
}
// Increment the vertical offset for the next connection
yOffset += 20; // Adjust the vertical spacing as needed
}
});