diff --git a/packages/mermaid/src/diagram-api/types.ts b/packages/mermaid/src/diagram-api/types.ts index 33dde3ad7..71ac28188 100644 --- a/packages/mermaid/src/diagram-api/types.ts +++ b/packages/mermaid/src/diagram-api/types.ts @@ -111,7 +111,11 @@ interface Point { y: number; } -interface NodePosition extends Point { +export interface IntersectionPoint extends Point { + pos: 't' | 'b' | 'l' | 'r'; +} + +export interface NodePosition extends Point { width?: number; height?: number; } diff --git a/packages/mermaid/src/mermaid.ts b/packages/mermaid/src/mermaid.ts index fba307223..6a5eb22d9 100644 --- a/packages/mermaid/src/mermaid.ts +++ b/packages/mermaid/src/mermaid.ts @@ -457,3 +457,8 @@ const mermaid: Mermaid = { }; export default mermaid; + +export { + calcIntersections, + calcNodeIntersections, +} from './rendering-util/layout-algorithms/fixed/index.js'; diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js index fb7271793..52f8e921c 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js @@ -14,6 +14,14 @@ import { import { select } from 'd3'; import { getConfig } from '../../../diagram-api/diagramAPI.js'; +/** + * @typedef {import('../../types.js').Node} Node + * @typedef {import('../../../types.js').Point} Point + * @typedef {import('../../../diagram-api/types.js').NodePosition} NodePosition + * @typedef {import('../../../diagram-api/types.js').IntersectionPoint} IntersectionPoint + */ + +/** @type {Map} */ let nodeDB = new Map(); // const fixInterSections = (points, startNodeId, endNodeId) => { @@ -29,6 +37,11 @@ let nodeDB = new Map(); // return points; // }; +/** + * @param {Pick} node + * @param {Point} point + * @returns {IntersectionPoint} + */ const calcIntersectionPoint = (node, point) => { const intersection = node.intersect(point); @@ -56,7 +69,13 @@ const calcIntersectionPoint = (node, point) => { return { x: intersection.x, y: intersection.y, pos }; }; -const calcNodeIntersections = async (_node1, _node2) => { + +/** + * @param {Pick} _node1 + * @param {Pick} _node2 + * @returns {Promise | IntersectionPoint[]} + */ +export const calcNodeIntersections = async (_node1, _node2) => { // CReate new nodes in order not to require a rendered diagram const fakeParent = document.createElementNS('http://www.w3.org/2000/svg', 'g'); const parent = select(fakeParent); @@ -75,8 +94,20 @@ const calcNodeIntersections = async (_node1, _node2) => { const endIntersection = calcIntersectionPoint(node2, { x: node1.x, y: node1.y }); return [startIntersection, endIntersection]; }; -const calcIntersections = (startNodeId, endNodeId, startNodeSize, endNodeSize) => { + +/** + * @param {string} startNodeId + * @param {string | undefined} endNodeId + * @param {NodePosition} startNodeSize + * @param {{width?: number, height?: number, x: number, y: number}} endNodeSize + * @returns {IntersectionPoint[]} + * @throws {Error} If the start node doesn't exist in the nodeDB (e.g. `render` hasn't been called yet) + */ +export const calcIntersections = (startNodeId, endNodeId, startNodeSize, endNodeSize) => { const startNode = nodeDB.get(startNodeId); + if (!startNode) { + throw new Error("Start node doesn't exist in the nodeDB"); + } if (startNodeSize) { startNode.x = startNodeSize.x; startNode.y = startNodeSize.y; @@ -297,6 +328,8 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => { positionEdgeLabel(edge, paths); } if (window) { + // TODO: Remove this now that we can do: + // import { calcIntersections, calcNodeIntersections } from '@mermaid-chart/mermaid'; window.calcIntersections = calcIntersections; window.calcNodeIntersections = calcNodeIntersections; }