fix(smooth-edge): vertically or horizontally aligned nodes closes

This commit is contained in:
moklick
2023-08-14 15:49:14 +02:00
parent 3d8d6b652f
commit 647c73cc8a

View File

@@ -69,6 +69,9 @@ function getPoints({
let points: XYPosition[] = [];
let centerX, centerY;
const sourceGapOffset = { x: 0, y: 0 };
const targetGapOffset = { x: 0, y: 0 };
const [defaultCenterX, defaultCenterY, defaultOffsetX, defaultOffsetY] = getEdgeCenter({
sourceX: source.x,
sourceY: source.y,
@@ -111,6 +114,20 @@ function getPoints({
points = sourceDir.y === currDir ? sourceTarget : targetSource;
}
if (sourcePosition === targetPosition) {
const diff = Math.abs(source[dirAccessor] - target[dirAccessor]);
// if an edge goes from right to right for example (sourcePosition === targetPosition) and the distance between source.x and target.x is less than the offset, the added point and the gapped source/target will overlap. This leads to a weird edge path. To avoid this we add a gapOffset to the source/target
if (diff <= offset) {
const gapOffset = Math.min(offset - 1, offset - diff);
if (sourceDir[dirAccessor] === currDir) {
sourceGapOffset[dirAccessor] = gapOffset;
} else {
targetGapOffset[dirAccessor] = gapOffset;
}
}
}
// these are conditions for handling mixed handle positions like Right -> Bottom for example
if (sourcePosition !== targetPosition) {
const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';
@@ -126,11 +143,28 @@ function getPoints({
}
}
centerX = points[0].x;
centerY = points[0].y;
const sourceGapPoint = { x: sourceGapped.x - sourceGapOffset.x, y: sourceGapped.y - sourceGapOffset.y };
const targetGapPoint = { x: targetGapped.x - targetGapOffset.x, y: targetGapped.y - targetGapOffset.y };
const maxXDistance = Math.max(Math.abs(sourceGapPoint.x - points[0].x), Math.abs(targetGapPoint.x - points[0].x));
const maxYDistance = Math.max(Math.abs(sourceGapPoint.y - points[0].y), Math.abs(targetGapPoint.y - points[0].y));
// we want to place the label on the longest segment of the edge
if (maxXDistance >= maxYDistance) {
centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;
centerY = points[0].y;
} else {
centerX = points[0].x;
centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;
}
}
const pathPoints = [source, sourceGapped, ...points, targetGapped, target];
const pathPoints = [
source,
{ x: sourceGapped.x - sourceGapOffset.x, y: sourceGapped.y - sourceGapOffset.y },
...points,
{ x: targetGapped.x - targetGapOffset.x, y: targetGapped.y - targetGapOffset.y },
target,
];
return [pathPoints, centerX, centerY, defaultOffsetX, defaultOffsetY];
}