UNPKG

@antv/g6

Version:

A Graph Visualization Framework in JavaScript

542 lines 26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRadians = void 0; exports.getLabelPositionStyle = getLabelPositionStyle; exports.getBadgePositionStyle = getBadgePositionStyle; exports.getCurveControlPoint = getCurveControlPoint; exports.parseCurveOffset = parseCurveOffset; exports.parseCurvePosition = parseCurvePosition; exports.getQuadraticPath = getQuadraticPath; exports.getCubicPath = getCubicPath; exports.getPolylinePath = getPolylinePath; exports.getBorderRadiusPoints = getBorderRadiusPoints; exports.getLoopEndpoints = getLoopEndpoints; exports.getCubicLoopPath = getCubicLoopPath; exports.getCubicLoopControlPoints = getCubicLoopControlPoints; exports.getPolylineLoopPath = getPolylineLoopPath; exports.getPolylineLoopControlPoints = getPolylineLoopControlPoints; exports.getSubgraphRelatedEdges = getSubgraphRelatedEdges; exports.findActualConnectNodeData = findActualConnectNodeData; exports.getArrowSize = getArrowSize; const util_1 = require("@antv/util"); const bbox_1 = require("./bbox"); const collapsibility_1 = require("./collapsibility"); const element_1 = require("./element"); const id_1 = require("./id"); const point_1 = require("./point"); const orth_1 = require("./router/orth"); const vector_1 = require("./vector"); /** * <zh/> 获取标签的位置样式 * * <en/> Get the style of the label's position * @param key - <zh/> 边对象 | <en/> The edge object * @param placement - <zh/> 标签位置 | <en/> Position of the label * @param autoRotate - <zh/> 是否自动旋转 | <en/> Whether to auto-rotate * @param offsetX - <zh/> 标签相对于边的水平偏移量 | <en/> Horizontal offset of the label relative to the edge * @param offsetY - <zh/> 标签相对于边的垂直偏移量 | <en/> Vertical offset of the label relative to the edge * @returns <zh/> 标签的位置样式 | <en/> Returns the style of the label's position */ function getLabelPositionStyle(key, placement, autoRotate, offsetX, offsetY) { const START_RATIO = 0; const MIDDLE_RATIO = 0.5; const END_RATIO = 0.99; let ratio = typeof placement === 'number' ? placement : MIDDLE_RATIO; if (placement === 'start') ratio = START_RATIO; if (placement === 'end') ratio = END_RATIO; const point = (0, point_1.parsePoint)(key.getPoint(ratio)); const pointOffset = (0, point_1.parsePoint)(key.getPoint(ratio + 0.01)); let textAlign = placement === 'start' ? 'left' : placement === 'end' ? 'right' : 'center'; if ((0, point_1.isHorizontal)(point, pointOffset) || !autoRotate) { const [x, y] = getXYByPlacement(key, ratio, offsetX, offsetY); return { transform: [['translate', x, y]], textAlign }; } let angle = Math.atan2(pointOffset[1] - point[1], pointOffset[0] - point[0]); const isRevert = pointOffset[0] < point[0]; if (isRevert) { textAlign = textAlign === 'center' ? textAlign : textAlign === 'left' ? 'right' : 'left'; offsetX *= -1; angle += Math.PI; } const [x, y] = getXYByPlacement(key, ratio, offsetX, offsetY, angle); const transform = [ ['translate', x, y], ['rotate', (angle / Math.PI) * 180], ]; return { textAlign, transform, }; } /** * <zh/> 获取边上徽标的位置样式 * * <en/> Get the position style of the badge on the edge * @param shapeMap - <zh/> 边上的图形映射 | <en/> Shape map on the edge * @param placement - <zh/> 徽标位置 | <en/> Badge position * @param labelPlacement - <zh/> 标签位置 | <en/> Label position * @param offsetX - <zh/> 水平偏移量 | <en/> Horizontal offset * @param offsetY - <zh/> 垂直偏移量 | <en/> Vertical offset * @returns <zh/> 徽标的位置样式 | <en/> Position style of the badge */ function getBadgePositionStyle(shapeMap, placement, labelPlacement, offsetX, offsetY) { var _a, _b; const badgeWidth = ((_a = shapeMap.badge) === null || _a === void 0 ? void 0 : _a.getGeometryBounds().halfExtents[0]) * 2 || 0; const labelWidth = ((_b = shapeMap.label) === null || _b === void 0 ? void 0 : _b.getGeometryBounds().halfExtents[0]) * 2 || 0; return getLabelPositionStyle(shapeMap.key, labelPlacement, true, (labelWidth ? (labelWidth / 2 + badgeWidth / 2) * (placement === 'suffix' ? 1 : -1) : 0) + offsetX, offsetY); } /** * <zh/> 获取给定边上的指定位置的坐标 * * <en/> Get the coordinates at the specified position on the given edge * @param key - <zh/> 边实例 | <en/> Edge instance * @param ratio - <zh/> 位置比率 | <en/> Position ratio * @param offsetX - <zh/> 水平偏移量 | <en/> Horizontal offset * @param offsetY - <zh/> 垂直偏移量 | <en/> Vertical offset * @param angle - <zh/> 旋转角度 | <en/> Rotation angle * @returns <zh/> 坐标 | <en/> Coordinates */ function getXYByPlacement(key, ratio, offsetX, offsetY, angle) { const [pointX, pointY] = (0, point_1.parsePoint)(key.getPoint(ratio)); let actualOffsetX = offsetX; let actualOffsetY = offsetY; if (angle) { actualOffsetX = offsetX * Math.cos(angle) - offsetY * Math.sin(angle); actualOffsetY = offsetX * Math.sin(angle) + offsetY * Math.cos(angle); } return [pointX + actualOffsetX, pointY + actualOffsetY]; } /** ==================== Curve Edge =========================== */ /** * <zh/> 计算曲线的控制点 * * <en/> Calculate the control point of the curve * @param sourcePoint - <zh/> 起点 | <en/> Source point * @param targetPoint - <zh/> 终点 | <en/> Target point * @param curvePosition - <zh/> 控制点在连线上的相对位置(取值范围为 0-1) | <en/> The relative position of the control point on the line (value range from 0 to 1) * @param curveOffset - <zh/> 控制点距离两端点连线的距离 | <en/> The distance between the control point and the line * @returns <zh/> 控制点 | <en/> Control points */ function getCurveControlPoint(sourcePoint, targetPoint, curvePosition, curveOffset) { if ((0, util_1.isEqual)(sourcePoint, targetPoint)) return sourcePoint; const lineVector = (0, vector_1.subtract)(targetPoint, sourcePoint); const controlPoint = [ sourcePoint[0] + curvePosition * lineVector[0], sourcePoint[1] + curvePosition * lineVector[1], ]; const perpVector = (0, vector_1.normalize)((0, vector_1.perpendicular)(lineVector, false)); controlPoint[0] += curveOffset * perpVector[0]; controlPoint[1] += curveOffset * perpVector[1]; return controlPoint; } /** * <zh/> 解析控制点距离两端点连线的距离 `curveOffset` * * <en/> parse the distance of the control point from the line `curveOffset` * @param curveOffset - <zh/> curveOffset | <en/> curveOffset * @returns <zh/> 标准 curveOffset | <en/> standard curveOffset */ function parseCurveOffset(curveOffset) { if ((0, util_1.isNumber)(curveOffset)) return [curveOffset, -curveOffset]; return curveOffset; } /** * <zh/> 解析控制点在两端点连线上的相对位置 `curvePosition`,范围为`0-1` * * <en/> parse the relative position of the control point on the line `curvePosition` * @param curvePosition - <zh/> curvePosition | <en/> curvePosition * @returns <zh/> 标准 curvePosition | <en/> standard curvePosition */ function parseCurvePosition(curvePosition) { if ((0, util_1.isNumber)(curvePosition)) return [curvePosition, 1 - curvePosition]; return curvePosition; } /** * <zh/> 获取二次贝塞尔曲线绘制路径 * * <en/> Calculate the path for drawing a quadratic Bessel curve * @param sourcePoint - <zh/> 边的起点 | <en/> Source point * @param targetPoint - <zh/> 边的终点 | <en/> Target point * @param controlPoint - <zh/> 控制点 | <en/> Control point * @returns <zh/> 返回绘制曲线的路径 | <en/> Returns curve path */ function getQuadraticPath(sourcePoint, targetPoint, controlPoint) { return [ ['M', sourcePoint[0], sourcePoint[1]], ['Q', controlPoint[0], controlPoint[1], targetPoint[0], targetPoint[1]], ]; } /** * <zh/> 获取三次贝塞尔曲线绘制路径 * * <en/> Calculate the path for drawing a cubic Bessel curve * @param sourcePoint - <zh/> 边的起点 | <en/> Source point * @param targetPoint - <zh/> 边的终点 | <en/> Target point * @param controlPoints - <zh/> 控制点 | <en/> Control point * @returns <zh/> 返回绘制曲线的路径 | <en/> Returns curve path */ function getCubicPath(sourcePoint, targetPoint, controlPoints) { return [ ['M', sourcePoint[0], sourcePoint[1]], [ 'C', controlPoints[0][0], controlPoints[0][1], controlPoints[1][0], controlPoints[1][1], targetPoint[0], targetPoint[1], ], ]; } /** ==================== Polyline Edge =========================== */ /** * <zh/> 获取折线的绘制路径 * * <en/> Calculates the path for drawing a polyline * @param points - <zh/> 折线的顶点 | <en/> The vertices of the polyline * @param radius - <zh/> 圆角半径 | <en/> Radius of the rounded corner * @param z - <zh/> 路径是否闭合 | <en/> Whether the path is closed * @returns <zh/> 返回绘制折线的路径 | <en/> Returns the path for drawing a polyline */ function getPolylinePath(points, radius = 0, z = false) { const targetIndex = points.length - 1; const sourcePoint = points[0]; const targetPoint = points[targetIndex]; const controlPoints = points.slice(1, targetIndex); const pathArray = [['M', sourcePoint[0], sourcePoint[1]]]; controlPoints.forEach((midPoint, i) => { const prevPoint = controlPoints[i - 1] || sourcePoint; const nextPoint = controlPoints[i + 1] || targetPoint; if (!(0, point_1.isCollinear)(prevPoint, midPoint, nextPoint) && radius) { const [ps, pt] = getBorderRadiusPoints(prevPoint, midPoint, nextPoint, radius); pathArray.push(['L', ps[0], ps[1]], ['Q', midPoint[0], midPoint[1], pt[0], pt[1]], ['L', pt[0], pt[1]]); } else { pathArray.push(['L', midPoint[0], midPoint[1]]); } }); pathArray.push(['L', targetPoint[0], targetPoint[1]]); if (z) pathArray.push(['Z']); return pathArray; } /** * <zh/> 根据给定的半径计算出不共线的三点生成贝塞尔曲线的控制点,以模拟接近圆弧 * * <en/> Calculates the control points of the Bezier curve generated by three non-collinear points according to the given radius to simulate an arc * @param prevPoint - <zh/> 前一个点 | <en/> Previous point * @param midPoint - <zh/> 中间点 | <en/> Middle point * @param nextPoint - <zh/> 后一个点 | <en/> Next point * @param radius - <zh/> 圆角半径 | <en/> Radius of the rounded corner * @returns <zh/> 返回控制点 | <en/> Returns control points */ function getBorderRadiusPoints(prevPoint, midPoint, nextPoint, radius) { const d0 = (0, vector_1.manhattanDistance)(prevPoint, midPoint); const d1 = (0, vector_1.manhattanDistance)(nextPoint, midPoint); // 取给定的半径和最小半径之间的较小值 | use the smaller value between the given radius and the minimum radius const r = Math.min(radius, Math.min(d0, d1) / 2); const ps = [ midPoint[0] - (r / d0) * (midPoint[0] - prevPoint[0]), midPoint[1] - (r / d0) * (midPoint[1] - prevPoint[1]), ]; const pt = [ midPoint[0] - (r / d1) * (midPoint[0] - nextPoint[0]), midPoint[1] - (r / d1) * (midPoint[1] - nextPoint[1]), ]; return [ps, pt]; } /** ==================== Loop Edge =========================== */ const getRadians = (bbox) => { const halfPI = Math.PI / 2; const halfHeight = (0, bbox_1.getBBoxHeight)(bbox) / 2; const halfWidth = (0, bbox_1.getBBoxWidth)(bbox) / 2; const angleWithX = Math.atan2(halfHeight, halfWidth) / 2; const angleWithY = Math.atan2(halfWidth, halfHeight) / 2; return { top: [-halfPI - angleWithY, -halfPI + angleWithY], 'top-right': [-halfPI + angleWithY, -angleWithX], 'right-top': [-halfPI + angleWithY, -angleWithX], right: [-angleWithX, angleWithX], 'bottom-right': [angleWithX, halfPI - angleWithY], 'right-bottom': [angleWithX, halfPI - angleWithY], bottom: [halfPI - angleWithY, halfPI + angleWithY], 'bottom-left': [halfPI + angleWithY, Math.PI - angleWithX], 'left-bottom': [halfPI + angleWithY, Math.PI - angleWithX], left: [Math.PI - angleWithX, Math.PI + angleWithX], 'top-left': [Math.PI + angleWithX, -halfPI - angleWithY], 'left-top': [Math.PI + angleWithX, -halfPI - angleWithY], }; }; exports.getRadians = getRadians; /** * <zh/> 获取环形边的起点和终点 * * <en/> Get the start and end points of the loop edge * @param node - <zh/> 节点实例 | <en/> Node instance * @param placement - <zh/> 环形边相对于节点位置 | <en/> Loop position relative to the node * @param clockwise - <zh/> 是否顺时针 | <en/> Whether to draw the loop clockwise * @param sourcePort - <zh/> 起点连接桩 | <en/> Source port * @param targetPort - <zh/> 终点连接桩 | <en/> Target port * @returns <zh/> 起点和终点 | <en/> Start and end points */ function getLoopEndpoints(node, placement, clockwise, sourcePort, targetPort) { const bbox = (0, bbox_1.getNodeBBox)(node); const center = node.getCenter(); let sourcePoint = sourcePort && (0, element_1.getPortPosition)(sourcePort); let targetPoint = targetPort && (0, element_1.getPortPosition)(targetPort); if (!sourcePoint || !targetPoint) { const radians = (0, exports.getRadians)(bbox); const angle1 = radians[placement][0]; const angle2 = radians[placement][1]; const [width, height] = (0, bbox_1.getBBoxSize)(bbox); const r = Math.max(width, height); const point1 = (0, vector_1.add)(center, [r * Math.cos(angle1), r * Math.sin(angle1), 0]); const point2 = (0, vector_1.add)(center, [r * Math.cos(angle2), r * Math.sin(angle2), 0]); sourcePoint = (0, element_1.getNodeConnectionPoint)(node, point1); targetPoint = (0, element_1.getNodeConnectionPoint)(node, point2); if (!clockwise) { [sourcePoint, targetPoint] = [targetPoint, sourcePoint]; } } return [sourcePoint, targetPoint]; } /** * <zh/> 获取环形边的绘制路径 * * <en/> Get the path of the loop edge * @param node - <zh/> 节点实例 | <en/> Node instance * @param placement - <zh/> 环形边相对于节点位置 | <en/> Loop position relative to the node * @param clockwise - <zh/> 是否顺时针 | <en/> Whether to draw the loop clockwise * @param dist - <zh/> 从节点 keyShape 边缘到自环顶部的距离 | <en/> The distance from the edge of the node keyShape to the top of the self-loop * @param sourcePortKey - <zh/> 起点连接桩 key | <en/> Source port key * @param targetPortKey - <zh/> 终点连接桩 key | <en/> Target port key * @returns <zh/> 返回绘制环形边的路径 | <en/> Returns the path of the loop edge */ function getCubicLoopPath(node, placement, clockwise, dist, sourcePortKey, targetPortKey) { const sourcePort = node.getPorts()[(sourcePortKey || targetPortKey)]; const targetPort = node.getPorts()[(targetPortKey || sourcePortKey)]; // 1. 获取起点和终点 | Get the start and end points let [sourcePoint, targetPoint] = getLoopEndpoints(node, placement, clockwise, sourcePort, targetPort); // 2. 获取控制点 | Get the control points const controlPoints = getCubicLoopControlPoints(node, sourcePoint, targetPoint, dist); // 3. 如果定义了连接桩,调整端点以与连接桩边界相交 | If the port is defined, adjust the endpoint to intersect with the port boundary if (sourcePort) sourcePoint = (0, element_1.getPortConnectionPoint)(sourcePort, controlPoints[0]); if (targetPort) targetPoint = (0, element_1.getPortConnectionPoint)(targetPort, controlPoints.at(-1)); return getCubicPath(sourcePoint, targetPoint, controlPoints); } /** * <zh/> 获取环形边的控制点 * * <en/> Get the control points of the loop edge * @param node - <zh/> 节点实例 | <en/> Node instance * @param sourcePoint - <zh/> 起点 | <en/> Source point * @param targetPoint - <zh/> 终点 | <en/> Target point * @param dist - <zh/> 从节点 keyShape 边缘到自环顶部的距离 | <en/> The distance from the edge of the node keyShape to the top of the self-loop * @returns <zh/> 控制点 | <en/> Control points */ function getCubicLoopControlPoints(node, sourcePoint, targetPoint, dist) { const center = node.getCenter(); if ((0, util_1.isEqual)(sourcePoint, targetPoint)) { const direction = (0, vector_1.subtract)(sourcePoint, center); const adjustment = [ dist * Math.sign(direction[0]) || dist / 2, dist * Math.sign(direction[1]) || -dist / 2, 0, ]; return [(0, vector_1.add)(sourcePoint, adjustment), (0, vector_1.add)(targetPoint, (0, vector_1.multiply)(adjustment, [1, -1, 1]))]; } return [ (0, point_1.moveTo)(center, sourcePoint, (0, vector_1.distance)(center, sourcePoint) + dist), (0, point_1.moveTo)(center, targetPoint, (0, vector_1.distance)(center, targetPoint) + dist), ]; } /** * <zh/> 获取环形折线边的绘制路径 * * <en/> Get the path of the loop polyline edge * @param node - <zh/> 节点实例 | <en/> Node instance * @param radius - <zh/> 圆角半径 | <en/> Radius of the rounded corner * @param placement - <zh/> 环形边相对于节点位置 | <en/> Loop position relative to the node * @param clockwise - <zh/> 是否顺时针 | <en/> Whether to draw the loop clockwise * @param dist - <zh/> 从节点 keyShape 边缘到自环顶部的距离 | <en/> The distance from the edge of the node keyShape to the top of the self-loop * @param sourcePortKey - <zh/> 起点连接桩 key | <en/> Source port key * @param targetPortKey - <zh/> 终点连接桩 key | <en/> Target port key * @returns <zh/> 返回绘制环形折线边的路径 | <en/> Returns the path of the loop polyline edge */ function getPolylineLoopPath(node, radius, placement, clockwise, dist, sourcePortKey, targetPortKey) { const allPortsMap = (0, element_1.getAllPorts)(node); const sourcePort = allPortsMap[(sourcePortKey || targetPortKey)]; const targetPort = allPortsMap[(targetPortKey || sourcePortKey)]; // 1. 获取起点和终点 | Get the start and end points let [sourcePoint, targetPoint] = getLoopEndpoints(node, placement, clockwise, sourcePort, targetPort); // 2. 获取控制点 | Get the control points const controlPoints = getPolylineLoopControlPoints(node, sourcePoint, targetPoint, dist); // 3. 如果定义了连接桩,调整端点以与连接桩边界相交 | If the port is defined, adjust the endpoint to intersect with the port boundary if (sourcePort) sourcePoint = (0, element_1.getPortConnectionPoint)(sourcePort, controlPoints[0]); if (targetPort) targetPoint = (0, element_1.getPortConnectionPoint)(targetPort, controlPoints.at(-1)); return getPolylinePath([sourcePoint, ...controlPoints, targetPoint], radius); } /** * <zh/> 获取环形折线边的控制点 * * <en/> Get the control points of the loop polyline edge * @param node - <zh/> 节点实例 | <en/> Node instance * @param sourcePoint - <zh/> 起点 | <en/> Source point * @param targetPoint - <zh/> 终点 | <en/> Target point * @param dist - <zh/> 从节点 keyShape 边缘到自环顶部的距离 | <en/> The distance from the edge of the node keyShape to the top of the self-loop * @returns <zh/> 控制点 | <en/> Control points */ function getPolylineLoopControlPoints(node, sourcePoint, targetPoint, dist) { const controlPoints = []; const bbox = (0, bbox_1.getNodeBBox)(node); // 1. 起点和终点相同 | The start and end points are the same if ((0, util_1.isEqual)(sourcePoint, targetPoint)) { const side = (0, bbox_1.getNearestBoundarySide)(sourcePoint, bbox); switch (side) { case 'left': controlPoints.push([sourcePoint[0] - dist, sourcePoint[1]]); controlPoints.push([sourcePoint[0] - dist, sourcePoint[1] + dist]); controlPoints.push([sourcePoint[0], sourcePoint[1] + dist]); break; case 'right': controlPoints.push([sourcePoint[0] + dist, sourcePoint[1]]); controlPoints.push([sourcePoint[0] + dist, sourcePoint[1] + dist]); controlPoints.push([sourcePoint[0], sourcePoint[1] + dist]); break; case 'top': controlPoints.push([sourcePoint[0], sourcePoint[1] - dist]); controlPoints.push([sourcePoint[0] + dist, sourcePoint[1] - dist]); controlPoints.push([sourcePoint[0] + dist, sourcePoint[1]]); break; case 'bottom': controlPoints.push([sourcePoint[0], sourcePoint[1] + dist]); controlPoints.push([sourcePoint[0] + dist, sourcePoint[1] + dist]); controlPoints.push([sourcePoint[0] + dist, sourcePoint[1]]); break; } } else { const sourceSide = (0, bbox_1.getNearestBoundarySide)(sourcePoint, bbox); const targetSide = (0, bbox_1.getNearestBoundarySide)(targetPoint, bbox); // 2. 起点与终点同边 | The start and end points are on the same side if (sourceSide === targetSide) { const side = sourceSide; let x, y; switch (side) { case 'left': x = Math.min(sourcePoint[0], targetPoint[0]) - dist; controlPoints.push([x, sourcePoint[1]]); controlPoints.push([x, targetPoint[1]]); break; case 'right': x = Math.max(sourcePoint[0], targetPoint[0]) + dist; controlPoints.push([x, sourcePoint[1]]); controlPoints.push([x, targetPoint[1]]); break; case 'top': y = Math.min(sourcePoint[1], targetPoint[1]) - dist; controlPoints.push([sourcePoint[0], y]); controlPoints.push([targetPoint[0], y]); break; case 'bottom': y = Math.max(sourcePoint[1], targetPoint[1]) + dist; controlPoints.push([sourcePoint[0], y]); controlPoints.push([targetPoint[0], y]); break; } } else { // 3. 起点与终点不同边 | The start and end points are on different sides const getPointOffSide = (side, point) => { return { left: [point[0] - dist, point[1]], right: [point[0] + dist, point[1]], top: [point[0], point[1] - dist], bottom: [point[0], point[1] + dist], }[side]; }; const p1 = getPointOffSide(sourceSide, sourcePoint); const p2 = getPointOffSide(targetSide, targetPoint); const p3 = (0, orth_1.freeJoin)(p1, p2, bbox); controlPoints.push(p1, p3, p2); } } return controlPoints; } /** * <zh/> 获取子图内的所有边,并按照内部边和外部边分组 * * <en/> Get all the edges in the subgraph and group them into internal and external edges * @param ids - <zh/> 节点 ID 数组 | <en/> Node ID array * @param getRelatedEdges - <zh/> 获取节点邻边 | <en/> Get node edges * @returns <zh/> 子图边 | <en/> Subgraph edges */ function getSubgraphRelatedEdges(ids, getRelatedEdges) { const edges = new Set(); const internal = new Set(); const external = new Set(); ids.forEach((id) => { const relatedEdges = getRelatedEdges(id); relatedEdges.forEach((edge) => { edges.add(edge); if (ids.includes(edge.source) && ids.includes(edge.target)) internal.add(edge); else external.add(edge); }); }); return { edges: Array.from(edges), internal: Array.from(internal), external: Array.from(external) }; } /** * <zh/> 获取边的实际连接节点 * * <en/> Get the actual connected object of the edge * @param node - <zh/> 逻辑连接节点数据 | <en/> Logical connection node data * @param getParentData - <zh/> 获取父节点数据 | <en/> Get parent node data * @returns <zh/> 实际连接节点数据 | <en/> Actual connected node data */ function findActualConnectNodeData(node, getParentData) { const path = []; let current = node; while (current) { path.push(current); const parent = getParentData((0, id_1.idOf)(current)); if (parent) current = parent; else break; } if (path.some((n) => { var _a; return (_a = n.style) === null || _a === void 0 ? void 0 : _a.collapsed; })) { const index = path.reverse().findIndex(collapsibility_1.isCollapsed); return path[index] || path.at(-1); } return node; } /** * <zh/> 获取箭头大小,若用户未指定,则根据线宽自动计算 * * <en/> Get the size of the arrow * @param lineWidth - <zh/> 箭头所在边的线宽 | <en/> The line width of the edge where the arrow is located * @param size - <zh/> 自定义箭头大小 | <en/> Custom arrow size * @returns <zh/> 箭头大小 | <en/> Arrow size */ function getArrowSize(lineWidth, size) { if (size) return size; if (lineWidth < 4) return 10; if (lineWidth === 4) return 12; return lineWidth * 2.5; } //# sourceMappingURL=edge.js.map