@ichigo_san/graphing
Version:
A lightweight UML-style diagram editor built with React Flow and Tailwind CSS
85 lines (84 loc) • 3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getEdgeParams = getEdgeParams;
var _reactflow = require("reactflow");
// Calculate intersection point of the line between node centers and the target node
function getNodeIntersection(intersectionNode, targetNode) {
var _intersectionNode$__r;
const {
width: sourceWidth = 0,
height: sourceHeight = 0
} = (_intersectionNode$__r = intersectionNode.__rf) !== null && _intersectionNode$__r !== void 0 && _intersectionNode$__r.width ? {
width: intersectionNode.__rf.width,
height: intersectionNode.__rf.height
} : intersectionNode.measured || {};
const intersectionPos = intersectionNode.positionAbsolute || intersectionNode.position || {
x: 0,
y: 0
};
const targetPosition = targetNode.positionAbsolute || targetNode.position || {
x: 0,
y: 0
};
const w = sourceWidth / 2;
const h = sourceHeight / 2;
if (w === 0 || h === 0) {
// Node dimensions not yet available
return intersectionPos;
}
const x2 = intersectionPos.x + w;
const y2 = intersectionPos.y + h;
const x1 = targetPosition.x + w;
const y1 = targetPosition.y + h;
const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h);
const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h);
const a = 1 / (Math.abs(xx1) + Math.abs(yy1));
const xx3 = a * xx1;
const yy3 = a * yy1;
const x = w * (xx3 + yy3) + x2;
const y = h * (-xx3 + yy3) + y2;
return {
x,
y
};
}
function getEdgePosition(node, intersectionPoint) {
var _n$measured, _node$__rf, _n$measured2, _node$__rf2;
const n = {
...node.position,
...node
};
const nx = Math.round(n.x);
const ny = Math.round(n.y);
const px = Math.round(intersectionPoint.x);
const py = Math.round(intersectionPoint.y);
if (px <= nx + 1) {
return _reactflow.Position.Left;
}
if (px >= nx + (((_n$measured = n.measured) === null || _n$measured === void 0 ? void 0 : _n$measured.width) ?? ((_node$__rf = node.__rf) === null || _node$__rf === void 0 ? void 0 : _node$__rf.width) ?? 0) - 1) {
return _reactflow.Position.Right;
}
if (py <= ny + 1) {
return _reactflow.Position.Top;
}
if (py >= n.y + (((_n$measured2 = n.measured) === null || _n$measured2 === void 0 ? void 0 : _n$measured2.height) ?? ((_node$__rf2 = node.__rf) === null || _node$__rf2 === void 0 ? void 0 : _node$__rf2.height) ?? 0) - 1) {
return _reactflow.Position.Bottom;
}
return _reactflow.Position.Top;
}
function getEdgeParams(source, target) {
const sourceIntersectionPoint = getNodeIntersection(source, target);
const targetIntersectionPoint = getNodeIntersection(target, source);
const sourcePos = getEdgePosition(source, sourceIntersectionPoint);
const targetPos = getEdgePosition(target, targetIntersectionPoint);
return {
sx: sourceIntersectionPoint.x,
sy: sourceIntersectionPoint.y,
tx: targetIntersectionPoint.x,
ty: targetIntersectionPoint.y,
sourcePos,
targetPos
};
}