fix: edge issue in tidy tree layout

on-behalf-of: @Mermaid-Chart <hello@mermaidchart.com>
This commit is contained in:
darshanr0107
2025-08-20 15:54:44 +05:30
parent 45edeb9307
commit 1b0bc05fc2

View File

@@ -406,53 +406,69 @@ function computeCircleEdgeIntersection(
}; };
} }
/**
* Calculate intersection point of a line with a rectangle
* This is a simplified version that we'll use instead of importing from mermaid
*/
function intersection( function intersection(
node: { x: number; y: number; width?: number; height?: number }, node: { x: number; y: number; width?: number; height?: number },
point1: { x: number; y: number }, outsidePoint: { x: number; y: number },
point2: { x: number; y: number } insidePoint: { x: number; y: number }
): { x: number; y: number } { ): { x: number; y: number } {
const nodeWidth = node.width ?? 100; const x = node.x;
const nodeHeight = node.height ?? 50; const y = node.y;
const centerX = node.x; if (!node.width || !node.height) {
const centerY = node.y; return { x: outsidePoint.x, y: outsidePoint.y };
const dx = point2.x - point1.x;
const dy = point2.y - point1.y;
if (dx === 0 && dy === 0) {
return { x: centerX, y: centerY };
} }
const dx = Math.abs(x - insidePoint.x);
const w = node?.width / 2;
let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;
const h = node.height / 2;
const halfWidth = nodeWidth / 2; const Q = Math.abs(outsidePoint.y - insidePoint.y);
const halfHeight = nodeHeight / 2; const R = Math.abs(outsidePoint.x - insidePoint.x);
let intersectionX = centerX; if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) {
let intersectionY = centerY; // Intersection is top or bottom of rect.
const q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;
r = (R * q) / Q;
const res = {
x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r,
y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q,
};
if (Math.abs(dx) > Math.abs(dy)) { if (r === 0) {
if (dx > 0) { res.x = outsidePoint.x;
intersectionX = centerX + halfWidth; res.y = outsidePoint.y;
intersectionY = centerY + (halfWidth * dy) / dx;
} else {
intersectionX = centerX - halfWidth;
intersectionY = centerY - (halfWidth * dy) / dx;
} }
if (R === 0) {
res.x = outsidePoint.x;
}
if (Q === 0) {
res.y = outsidePoint.y;
}
return res;
} else { } else {
if (dy > 0) { if (insidePoint.x < outsidePoint.x) {
intersectionY = centerY + halfHeight; r = outsidePoint.x - w - x;
intersectionX = centerX + (halfHeight * dx) / dy;
} else { } else {
intersectionY = centerY - halfHeight; r = x - w - outsidePoint.x;
intersectionX = centerX - (halfHeight * dx) / dy;
} }
} const q = (Q * r) / R;
let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r;
let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q;
return { x: intersectionX, y: intersectionY }; if (r === 0) {
_x = outsidePoint.x;
_y = outsidePoint.y;
}
if (R === 0) {
_x = outsidePoint.x;
}
if (Q === 0) {
_y = outsidePoint.y;
}
return { x: _x, y: _y };
}
} }
/** /**