mermaid
Version:
Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.
8 lines • 52.1 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/rendering-util/createGraph.ts", "../../../src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js", "../../../src/rendering-util/layout-algorithms/common/index.ts"],
"sourcesContent": ["import type { Selection } from 'd3';\nimport * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\nimport type { ClusterNode, LayoutData, NonClusterNode, ShapeRenderOptions } from './types.js';\nimport { getConfig } from '../diagram-api/diagramAPI.js';\nimport { hasEdgeLabel, insertEdgeLabel } from './rendering-elements/edges.js';\nimport { insertNode } from './rendering-elements/nodes.js';\nimport { labelHelper } from './rendering-elements/shapes/util.js';\n\n// Update type:\ntype D3Selection<T extends SVGElement = SVGElement> = Selection<\n T,\n unknown,\n Element | null,\n unknown\n>;\n\ninterface LayoutElementGroups {\n clusters: D3Selection<SVGGElement>;\n edgePaths: D3Selection<SVGGElement>;\n edgeLabels: D3Selection<SVGGElement>;\n nodes: D3Selection<SVGGElement>;\n rootGroups: D3Selection<SVGGElement>;\n}\n\nexport interface CreateLayoutElementGroupsOptions {\n edgePathsClass?: string;\n}\n\nexport function createLayoutElementGroups(\n element: D3Selection,\n { edgePathsClass = 'edges edgePaths' }: CreateLayoutElementGroupsOptions = {}\n): LayoutElementGroups {\n const rootGroups = element.insert('g').attr('class', 'root');\n const clusters = rootGroups.insert('g').attr('class', 'clusters');\n const edgePaths = rootGroups.insert('g').attr('class', edgePathsClass);\n const edgeLabels = rootGroups.insert('g').attr('class', 'edgeLabels');\n const nodes = rootGroups.insert('g').attr('class', 'nodes');\n\n return { clusters, edgePaths, edgeLabels, nodes, rootGroups };\n}\n\nexport async function measureGroupLabel(\n nodesGroup: D3Selection<SVGGElement>,\n node: ClusterNode\n): Promise<void> {\n if (node.label) {\n const { shapeSvg, bbox } = await labelHelper(nodesGroup, node);\n node.labelBBox = { width: bbox.width, height: bbox.height };\n shapeSvg.remove();\n } else {\n node.labelBBox = { width: 0, height: 0 };\n }\n}\n\nexport async function insertMeasuredNode(\n nodesGroup: D3Selection<SVGGElement>,\n node: NonClusterNode,\n renderOptions: ShapeRenderOptions\n): Promise<D3Selection<SVGElement | SVGGElement>> {\n const childNodeEl = await insertNode(nodesGroup, node, renderOptions);\n const boundingBox = childNodeEl.node()?.getBBox() ?? { width: 0, height: 0 };\n node.width = boundingBox.width;\n node.height = boundingBox.height;\n return childNodeEl as D3Selection<SVGElement | SVGGElement>;\n}\n\n/**\n * Creates a graph by merging the graph construction and DOM element insertion.\n *\n * This function creates the graph, inserts the SVG groups (clusters, edgePaths, edgeLabels, nodes)\n * into the provided element, and uses `insertNode` to add nodes to the diagram. Node dimensions\n * are computed using each node's bounding box.\n *\n * @param element - The D3 selection in which the SVG groups are inserted.\n * @param data4Layout - The layout data containing nodes and edges.\n * @returns A promise resolving to an object containing the graph and the inserted groups.\n */\nexport async function createGraphWithElements(\n element: D3Selection,\n data4Layout: LayoutData\n): Promise<{\n graph: graphlib.Graph;\n groups: {\n clusters: D3Selection<SVGGElement>;\n edgePaths: D3Selection<SVGGElement>;\n edgeLabels: D3Selection<SVGGElement>;\n nodes: D3Selection<SVGGElement>;\n rootGroups: D3Selection<SVGGElement>;\n };\n nodeElements: Map<string, D3Selection<SVGElement | SVGGElement>>;\n}> {\n // Create a directed, multi graph.\n const graph = new graphlib.Graph({\n multigraph: true,\n compound: true,\n });\n const edgesToProcess = [...data4Layout.edges];\n const config = getConfig();\n const groups = createLayoutElementGroups(element);\n const { edgeLabels, nodes: nodesGroup } = groups;\n\n const nodeElements = new Map<string, D3Selection<SVGElement | SVGGElement>>();\n\n // When the container element is detached (no real DOM \u2014 e.g. headless unit\n // tests that exercise the layout engine without rendering), `insertNode`\n // cannot measure labels and would dereference a null node. The browser\n // always passes a live container, so render + measure only when one exists;\n // otherwise still build the graph topology with unmeasured (0) sizes.\n const hasDom = element.node() != null;\n\n // Insert nodes into the DOM and add them to the graph.\n await Promise.all(\n data4Layout.nodes.map(async (node) => {\n if (node.isGroup) {\n if (hasDom) {\n await measureGroupLabel(nodesGroup, node);\n }\n graph.setNode(node.id, { ...node });\n } else {\n if (hasDom) {\n const childNodeEl = await insertMeasuredNode(nodesGroup, node, {\n config,\n dir: node.dir,\n });\n nodeElements.set(node.id, childNodeEl);\n }\n graph.setNode(node.id, { ...node });\n }\n })\n );\n // Add edges to the graph.\n\n for (const edge of edgesToProcess) {\n if (hasDom && hasEdgeLabel(edge)) {\n await insertEdgeLabel(edgeLabels, edge);\n }\n graph.setEdge(edge.start!, edge.end!, { ...edge }, edge.id);\n const edgeExists = data4Layout.edges.some((existingEdge) => existingEdge.id === edge.id);\n if (!edgeExists) {\n data4Layout.edges.push(edge);\n }\n }\n\n // DDLT size capture (dev / test tooling only). The capture module is loaded\n // via dynamic import so it is never bundled into the production render path:\n // in published builds `window.mermaidCaptureSizes` is unset, so this guard is\n // a single property read and the import resolves to a lazily-loaded chunk that\n // is only fetched when a developer explicitly enables capture.\n // See layout-algorithms/ddlt/sizeCapture.ts.\n if ((globalThis as unknown as { mermaidCaptureSizes?: boolean }).mermaidCaptureSizes) {\n const { captureNodeSizes } = await import('./layout-algorithms/ddlt/sizeCapture.js');\n captureNodeSizes(element, data4Layout);\n }\n\n return {\n graph,\n groups,\n nodeElements,\n };\n}\n", "/** Decorates with functions required by mermaids dagre-wrapper. */\nimport { log } from '../../../logger.js';\nimport * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\n\nexport let clusterDb = new Map();\nlet descendants = new Map();\nlet parents = new Map();\n\nexport const clear = () => {\n descendants.clear();\n parents.clear();\n clusterDb.clear();\n};\n\nconst isDescendant = (id, ancestorId) => {\n const ancestorDescendants = descendants.get(ancestorId) || [];\n log.trace('In isDescendant', ancestorId, ' ', id, ' = ', ancestorDescendants.includes(id));\n return ancestorDescendants.includes(id);\n};\n\nconst edgeInCluster = (edge, clusterId) => {\n const clusterDescendants = descendants.get(clusterId) || [];\n log.info('Descendants of ', clusterId, ' is ', clusterDescendants);\n log.info('Edge is ', edge);\n if (edge.v === clusterId || edge.w === clusterId) {\n return false;\n }\n\n if (!clusterDescendants) {\n log.debug('Tilt, ', clusterId, ',not in descendants');\n return false;\n }\n\n return (\n clusterDescendants.includes(edge.v) ||\n isDescendant(edge.v, clusterId) ||\n isDescendant(edge.w, clusterId) ||\n clusterDescendants.includes(edge.w)\n );\n};\n\nconst copy = (clusterId, graph, newGraph, rootId) => {\n log.debug(\n 'Copying children of ',\n clusterId,\n 'root',\n rootId,\n 'data',\n graph.node(clusterId),\n rootId\n );\n const nodes = graph.children(clusterId) || [];\n\n if (clusterId !== rootId) {\n nodes.push(clusterId);\n }\n\n log.debug('Copying (nodes) clusterId', clusterId, 'nodes', nodes);\n\n nodes.forEach((node) => {\n if (graph.children(node).length > 0) {\n copy(node, graph, newGraph, rootId);\n } else {\n const data = graph.node(node);\n log.info('cp ', node, ' to ', rootId, ' with parent ', clusterId);\n newGraph.setNode(node, data);\n if (rootId !== graph.parent(node)) {\n log.debug('Setting parent', node, graph.parent(node));\n newGraph.setParent(node, graph.parent(node));\n }\n\n if (clusterId !== rootId && node !== clusterId) {\n log.debug('Setting parent', node, clusterId);\n newGraph.setParent(node, clusterId);\n } else {\n log.info('In copy ', clusterId, 'root', rootId, 'data', graph.node(clusterId), rootId);\n log.debug(\n 'Not Setting parent for node=',\n node,\n 'cluster!==rootId',\n clusterId !== rootId,\n 'node!==clusterId',\n node !== clusterId\n );\n }\n const edges = graph.edges(node);\n log.debug('Copying Edges', edges);\n edges.forEach((edge) => {\n log.info('Edge', edge);\n const data = graph.edge(edge.v, edge.w, edge.name);\n log.info('Edge data', data, rootId);\n try {\n if (edgeInCluster(edge, rootId)) {\n log.info('Copying as ', edge.v, edge.w, data, edge.name);\n newGraph.setEdge(edge.v, edge.w, data, edge.name);\n log.info('newGraph edges ', newGraph.edges(), newGraph.edge(newGraph.edges()[0]));\n } else {\n log.info(\n 'Skipping copy of edge ',\n edge.v,\n '-->',\n edge.w,\n ' rootId: ',\n rootId,\n ' clusterId:',\n clusterId\n );\n }\n } catch (e) {\n log.error(e);\n }\n });\n }\n log.debug('Removing node', node);\n graph.removeNode(node);\n });\n};\n\nexport const extractDescendants = (id, graph) => {\n const children = graph.children(id);\n let res = [...children];\n\n for (const child of children) {\n parents.set(child, id);\n res = [...res, ...extractDescendants(child, graph)];\n }\n\n return res;\n};\n\nexport const validate = (graph) => {\n const edges = graph.edges();\n log.trace('Edges: ', edges);\n for (const edge of edges) {\n if (graph.children(edge.v).length > 0) {\n log.trace('The node ', edge.v, ' is part of and edge even though it has children');\n return false;\n }\n if (graph.children(edge.w).length > 0) {\n log.trace('The node ', edge.w, ' is part of and edge even though it has children');\n return false;\n }\n }\n return true;\n};\n\nconst findCommonEdges = (graph, id1, id2) => {\n const edges1 = graph.edges().filter((edge) => edge.v === id1 || edge.w === id1);\n const edges2 = graph.edges().filter((edge) => edge.v === id2 || edge.w === id2);\n const edges1Prim = edges1.map((edge) => {\n return { v: edge.v === id1 ? id2 : edge.v, w: edge.w === id1 ? id1 : edge.w };\n });\n const edges2Prim = edges2.map((edge) => {\n return { v: edge.v, w: edge.w };\n });\n const result = edges1Prim.filter((edgeIn1) => {\n return edges2Prim.some((edge) => edgeIn1.v === edge.v && edgeIn1.w === edge.w);\n });\n\n return result;\n};\n\nexport const findNonClusterChild = (id, graph, clusterId) => {\n const children = graph.children(id);\n log.trace('Searching children of id ', id, children);\n if (children.length < 1) {\n return id;\n }\n let reserve;\n for (const child of children) {\n const _id = findNonClusterChild(child, graph, clusterId);\n\n const commonEdges = findCommonEdges(graph, clusterId, _id);\n\n if (_id) {\n if (commonEdges.length > 0) {\n reserve = _id;\n } else {\n return _id;\n }\n }\n }\n return reserve;\n};\n\nconst getAnchorId = (id) => {\n if (!clusterDb.has(id)) {\n return id;\n }\n if (!clusterDb.get(id).externalConnections) {\n return id;\n }\n\n if (clusterDb.has(id)) {\n return clusterDb.get(id).id;\n }\n return id;\n};\n\nexport const adjustClustersAndEdges = (graph, depth) => {\n if (!graph || depth > 10) {\n log.debug('Opting out, no graph ');\n return;\n } else {\n log.debug('Opting in, graph ');\n }\n\n graph.nodes().forEach(function (id) {\n const children = graph.children(id);\n if (children.length > 0) {\n log.debug(\n 'Cluster identified',\n id,\n ' Replacement id in edges: ',\n findNonClusterChild(id, graph, id)\n );\n descendants.set(id, extractDescendants(id, graph));\n clusterDb.set(id, { id: findNonClusterChild(id, graph, id), clusterData: graph.node(id) });\n }\n });\n\n graph.nodes().forEach(function (id) {\n const children = graph.children(id);\n const edges = graph.edges();\n if (children.length > 0) {\n log.debug('Cluster identified', id, descendants);\n edges.forEach((edge) => {\n const d1 = isDescendant(edge.v, id);\n const d2 = isDescendant(edge.w, id);\n\n if (d1 ^ d2) {\n log.debug('Edge: ', edge, ' leaves cluster ', id);\n log.debug('Descendants of XXX ', id, ': ', descendants.get(id));\n clusterDb.get(id).externalConnections = true;\n }\n });\n } else {\n log.debug('Not a cluster ', id, descendants);\n }\n });\n\n for (let id of clusterDb.keys()) {\n const nonClusterChild = clusterDb.get(id).id;\n const parent = graph.parent(nonClusterChild);\n\n if (parent !== id && clusterDb.has(parent) && !clusterDb.get(parent).externalConnections) {\n clusterDb.get(id).id = parent;\n }\n // When this cluster has a direct outgoing edge AND its current anchor sits inside\n // a sibling subgraph that will be extracted (collapsed into a clusterNode), the\n // anchor will disappear by render time and the edge endpoint becomes undefined.\n // Re-anchor onto a node that survives extraction.\n const hasDirectOutgoingEdge = graph.edges().some((edge) => edge.v === id);\n if (\n nonClusterChild &&\n clusterDb.get(id)?.externalConnections &&\n hasDirectOutgoingEdge &&\n isNodeInExtractableCluster(graph, nonClusterChild, id)\n ) {\n const safeAnchor = findSafeAnchorNode(graph, id, graph.parent(nonClusterChild));\n if (safeAnchor) {\n clusterDb.get(id).id = safeAnchor;\n }\n }\n }\n\n graph.edges().forEach(function (e) {\n const edge = graph.edge(e);\n log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e));\n log.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(graph.edge(e)));\n\n let v = e.v;\n let w = e.w;\n log.debug(\n 'Fix XXX',\n clusterDb,\n 'ids:',\n e.v,\n e.w,\n 'Translating: ',\n clusterDb.get(e.v),\n ' --- ',\n clusterDb.get(e.w)\n );\n if (clusterDb.get(e.v) || clusterDb.get(e.w)) {\n log.debug('Fixing and trying - removing XXX', e.v, e.w, e.name);\n v = getAnchorId(e.v);\n w = getAnchorId(e.w);\n graph.removeEdge(e.v, e.w, e.name);\n if (v !== e.v) {\n const parent = graph.parent(v);\n clusterDb.get(parent).externalConnections = true;\n edge.fromCluster = e.v;\n }\n if (w !== e.w) {\n const parent = graph.parent(w);\n clusterDb.get(parent).externalConnections = true;\n edge.toCluster = e.w;\n }\n log.debug('Fix Replacing with XXX', v, w, e.name);\n graph.setEdge(v, w, edge, e.name);\n }\n });\n // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n // log.debug('Adjusted Graph', graphlibJson.write(graph));\n extractor(graph, 0);\n\n log.trace(clusterDb);\n};\n\nexport const extractor = (graph, depth) => {\n // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n // log.debug('extractor - ', depth, graphlibJson.write(graph), graph.children('D'));\n if (depth > 10) {\n log.error('Bailing out');\n return;\n }\n let nodes = graph.nodes();\n let hasChildren = false;\n for (const node of nodes) {\n const children = graph.children(node);\n hasChildren = hasChildren || children.length > 0;\n }\n\n if (!hasChildren) {\n log.debug('Done, no node has children', graph.nodes());\n return;\n }\n log.debug('Nodes = ', nodes, depth);\n for (const node of nodes) {\n log.debug(\n 'Extracting node',\n node,\n clusterDb,\n clusterDb.has(node) && !clusterDb.get(node).externalConnections,\n !graph.parent(node),\n graph.node(node),\n graph.children('D'),\n ' Depth ',\n depth\n );\n if (!clusterDb.has(node)) {\n log.debug('Not a cluster', node, depth);\n } else if (\n !clusterDb.get(node).externalConnections &&\n graph.children(node) &&\n graph.children(node).length > 0\n ) {\n // Original behaviour: cluster without external connections gets its own sub-graph.\n log.debug(\n 'Cluster without external connections, without a parent and with children',\n node,\n depth\n );\n\n const graphSettings = graph.graph();\n let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';\n if (clusterDb.get(node)?.clusterData?.dir) {\n dir = clusterDb.get(node).clusterData.dir;\n log.debug('Fixing dir', clusterDb.get(node).clusterData.dir, dir);\n }\n\n const clusterGraph = new graphlib.Graph({\n multigraph: true,\n compound: true,\n })\n .setGraph({\n rankdir: dir,\n nodesep: 50,\n ranksep: 50,\n marginx: 8,\n marginy: 8,\n })\n .setDefaultEdgeLabel(function () {\n return {};\n });\n\n // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n // log.debug('Old graph before copy', graphlibJson.write(graph));\n copy(node, graph, clusterGraph, node);\n graph.setNode(node, {\n clusterNode: true,\n id: node,\n clusterData: clusterDb.get(node).clusterData,\n label: clusterDb.get(node).label,\n graph: clusterGraph,\n });\n // perf: skip eager graphlibJson.write() serialization (the arg runs every render even when the log is a no-op)\n // log.debug('Old graph after copy', graphlibJson.write(graph));\n } else {\n log.debug(\n 'Cluster ** ',\n node,\n ' **not meeting the criteria !externalConnections:',\n !clusterDb.get(node).externalConnections,\n ' no parent: ',\n !graph.parent(node),\n ' children ',\n graph.children(node) && graph.children(node).length > 0,\n graph.children('D'),\n depth\n );\n log.debug(clusterDb);\n }\n }\n\n nodes = graph.nodes();\n log.debug('New list of nodes', nodes);\n for (const node of nodes) {\n const data = graph.node(node);\n log.debug(' Now next level', node, data);\n if (data?.clusterNode) {\n extractor(data.graph, depth + 1);\n }\n }\n};\n\nconst sorter = (graph, nodes) => {\n if (nodes.length === 0) {\n return [];\n }\n let result = Object.assign([], nodes);\n nodes.forEach((node) => {\n const children = graph.children(node);\n const sorted = sorter(graph, children);\n result = [...result, ...sorted];\n });\n\n return result;\n};\n\nexport const sortNodesByHierarchy = (graph) => sorter(graph, graph.children());\n\n/** Checks if a node is inside a cluster that will be extracted (has no external connections). */\nconst isNodeInExtractableCluster = (graph, node, rootId) => {\n let parent = graph.parent(node);\n\n while (parent && parent !== rootId) {\n const cluster = clusterDb.get(parent);\n if (cluster && !cluster.externalConnections) {\n return true;\n }\n parent = graph.parent(parent);\n }\n\n return false;\n};\n\n/** Finds an alternative anchor node for a cluster that is not inside an extractable cluster. */\nconst findSafeAnchorNode = (graph, clusterId, excludedCluster) => {\n const children = graph.children(clusterId) ?? [];\n\n for (const child of children) {\n if (child === excludedCluster || isDescendant(child, excludedCluster)) {\n continue;\n }\n\n // findNonClusterChild returns the leaf itself when child is a leaf, or drills\n // into a subgraph to find a non-cluster descendant. A returned leaf sibling is\n // a perfectly valid anchor \u2014 only skip when the lookup found nothing usable.\n const candidate = findNonClusterChild(child, graph, clusterId);\n if (!candidate) {\n continue;\n }\n\n if (!isNodeInExtractableCluster(graph, candidate, clusterId)) {\n return candidate;\n }\n }\n\n return null;\n};\n", "import type { SVG } from '../../../diagram-api/types.js';\nimport type { InternalHelpers } from '../../../internals.js';\nimport type { D3Selection } from '../../../types.js';\nimport { log } from '../../../logger.js';\nimport { profiler } from '../../../profiler.js';\nimport { getConfig } from '../../../config.js';\nimport utils from '../../../utils.js';\nimport { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js';\nimport { createGraphWithElements } from '../../createGraph.js';\nimport { clear as clearClusters, insertCluster } from '../../rendering-elements/clusters.js';\nimport {\n clear as clearEdges,\n edgeLabels,\n hasEdgeLabel,\n insertEdge,\n insertEdgeLabel,\n terminalLabels,\n} from '../../rendering-elements/edges.js';\nimport insertMarkers from '../../rendering-elements/markers.js';\nimport { clear as clearNodes, positionNode } from '../../rendering-elements/nodes.js';\nimport type { LayoutData, Edge, ClusterNode } from '../../types.js';\nimport type { RenderOptions } from '../../render.js';\nimport { clear as clearGraphlib } from '../dagre/mermaid-graphlib.js';\n\nexport type CommonLayoutMeasure = Awaited<ReturnType<typeof createGraphWithElements>>;\ntype RenderedEdge = Edge & {\n x?: number;\n y?: number;\n startLabelLeft?: string;\n endLabelRight?: string;\n};\ntype EdgeRenderPath = Parameters<typeof utils.calcLabelPosition>[0];\ntype ClusterDb = Map<string, { node?: LayoutData['nodes'][number] } & Record<string, unknown>>;\n\ninterface EdgeRenderPaths {\n originalPath?: EdgeRenderPath;\n updatedPath?: EdgeRenderPath;\n}\n\nexport interface CommonLayoutRenderContext<PreparedLayout = unknown> {\n element: D3Selection<SVGElement>;\n helpers?: InternalHelpers;\n options?: RenderOptions;\n preparedLayout?: PreparedLayout;\n}\n\nexport interface CommonLayoutPaintContext<\n PreparedLayout = unknown,\n MeasureResult = CommonLayoutMeasure,\n> extends CommonLayoutRenderContext<PreparedLayout> {\n measure: MeasureResult;\n}\n\nexport interface CommonLayoutPaintOptions {\n clusterDb?: ClusterDb;\n getNodes?: (\n data4Layout: LayoutData,\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n ) => Iterable<LayoutData['nodes'][number]>;\n getEdgeNode?: (\n id: string | undefined,\n edge: Edge,\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n ) => LayoutData['nodes'][number] | object | undefined;\n skipNode?: (\n node: LayoutData['nodes'][number],\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n ) => boolean;\n isCluster?: (\n node: LayoutData['nodes'][number],\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n ) => boolean;\n skipEdge?: (edge: Edge) => boolean;\n skipIntersect?: boolean | ((edge: Edge) => boolean);\n}\n\nexport interface CommonLayoutRendererDefinition<\n CoreResult = unknown,\n PreparedLayout = void,\n MeasureResult = CommonLayoutMeasure,\n> {\n prepareLayout?: (\n data4Layout: LayoutData,\n context: CommonLayoutRenderContext<PreparedLayout>\n ) => PreparedLayout | Promise<PreparedLayout>;\n measureLayout?: (\n data4Layout: LayoutData,\n context: CommonLayoutRenderContext<PreparedLayout>\n ) => Promise<MeasureResult>;\n runLayoutCore: (\n data4Layout: LayoutData,\n context: CommonLayoutRenderContext<PreparedLayout>\n ) => CoreResult | Promise<CoreResult>;\n paintLayout?: (\n data4Layout: LayoutData,\n context: CommonLayoutPaintContext<PreparedLayout, MeasureResult>,\n coreResult: CoreResult\n ) => void | Promise<void>;\n afterPaint?: (\n data4Layout: LayoutData,\n context: CommonLayoutPaintContext<PreparedLayout, MeasureResult>,\n coreResult: CoreResult\n ) => void | Promise<void>;\n paintOptions?: CommonLayoutPaintOptions;\n}\n\nexport function createCommonLayoutRenderer<\n CoreResult = unknown,\n PreparedLayout = void,\n MeasureResult = CommonLayoutMeasure,\n>({\n prepareLayout,\n measureLayout,\n runLayoutCore,\n paintLayout,\n afterPaint,\n paintOptions,\n}: CommonLayoutRendererDefinition<CoreResult, PreparedLayout, MeasureResult>) {\n // Use the provided measureLayout or default to createGraphWithElements if not provided.\n // This allows layout algorithms to skip the graph creation step if they don't need it,\n // while still providing a default implementation for those that do.\n const measureLayoutFn =\n measureLayout ??\n (defaultMeasureLayout as unknown as NonNullable<\n CommonLayoutRendererDefinition<CoreResult, PreparedLayout, MeasureResult>['measureLayout']\n >);\n\n // This is the actual factory step where the render function is created.\n return async function render(\n data4Layout: LayoutData,\n svg: SVG,\n helpers?: InternalHelpers,\n options?: RenderOptions\n ): Promise<void> {\n const element = svg.select('g') as unknown as D3Selection<SVGElement>;\n // Use the helper handed over by the host mermaid instance when there is one.\n // External layout packages (elk, tidy-tree) are bundled with their own copy of\n // these modules, and that copy's config module never sees `mermaid.initialize()`,\n // so markers created through the statically imported `insertMarkers` read default\n // theme variables instead of the diagram's.\n (helpers?.insertMarkers ?? insertMarkers)(\n element,\n data4Layout.markers,\n data4Layout.type,\n data4Layout.diagramId\n );\n clearLayoutRenderState();\n\n // Convenience struct containing everything you need to render\n // the root element and helper function from core mermaid\n const renderContext: CommonLayoutRenderContext<PreparedLayout> = {\n element, // root SVG <g>\n helpers, // Mermaid helper functions\n options, // { algorithm: \"elk.layered\" }\n };\n\n // Algorithm-specific transformations onto the original parsed layout data so the algorithm-specific\n // layout core has the inputs and setup it needs\n renderContext.preparedLayout = injected.profiling\n ? await profiler.span('prepare', () => prepareLayout?.(data4Layout, renderContext))\n : await prepareLayout?.(data4Layout, renderContext);\n\n // Get the sizes of the labels and other elements by running the measureLayout function,\n // which by default creates a graph with the elements and measures them.\n // This is needed for layout algorithms that require size information to compute the layout.\n const measure = injected.profiling\n ? await profiler.span('measure', () => measureLayoutFn(data4Layout, renderContext))\n : await measureLayoutFn(data4Layout, renderContext);\n\n // Next, run the core layout algorithm to compute the positions of nodes and edges based on the algorithm,\n // layoutData and the measurements. This is the core piece where functions are supposed to be different\n // between different algorithms.\n const coreResult = injected.profiling\n ? await profiler.span('layout', () => runLayoutCore(data4Layout, renderContext))\n : await runLayoutCore(data4Layout, renderContext);\n\n const paintContext: CommonLayoutPaintContext<PreparedLayout, MeasureResult> = {\n ...renderContext,\n measure,\n };\n\n if (injected.profiling) {\n profiler.begin('paint');\n }\n if (paintLayout) {\n // Escape hatch: if a custom paintLayout is provided, we assume it handles everything including painting\n // based on the layout data and measurements, so we just call it directly with the core result. Only to be used\n // sparingly during transitions to the new system or for very custom layouts that don't fit the common pattern.\n await paintLayout(data4Layout, paintContext, coreResult);\n } else {\n await paintLayoutData(\n data4Layout,\n paintContext as unknown as CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n paintOptions\n );\n }\n // Some algorithms may need to do some post-processing after the initial paint, for example to position edge\n // labels after the edges have been rendered and their paths are known.\n await afterPaint?.(data4Layout, paintContext, coreResult);\n if (injected.profiling) {\n profiler.end(); // paint\n }\n };\n}\n\nexport function clearLayoutRenderState(): void {\n clearNodes();\n clearEdges();\n clearClusters();\n clearGraphlib();\n}\n\nexport async function defaultMeasureLayout(\n data4Layout: LayoutData,\n { element }: CommonLayoutRenderContext\n): Promise<CommonLayoutMeasure> {\n return await createGraphWithElements(element, data4Layout);\n}\n\nexport async function paintLayoutData(\n data4Layout: LayoutData,\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n options: CommonLayoutPaintOptions = {}\n): Promise<void> {\n const { measure } = context;\n const { groups } = measure;\n\n // Render clusters and position nodes; this also populates node.intersect on shapes.\n for (const node of options.getNodes?.(data4Layout, context) ?? data4Layout.nodes) {\n if (options.skipNode?.(node, context)) {\n continue;\n }\n await paintLayoutNode(groups, node, context, options);\n }\n\n const nodeById = buildNodeLookup(data4Layout.nodes);\n\n for (const edge of data4Layout.edges) {\n if (shouldSkipPaintEdge(edge, options)) {\n continue;\n }\n\n await paintLayoutEdge(groups, edge, nodeById, data4Layout, options, context);\n }\n}\n\nasync function paintLayoutNode(\n groups: CommonLayoutMeasure['groups'],\n node: LayoutData['nodes'][number],\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n options: CommonLayoutPaintOptions\n): Promise<void> {\n if ((node as { clusterNode?: boolean }).clusterNode) {\n positionNode(node);\n } else if (shouldPaintAsCluster(node, context, options)) {\n await insertCluster(groups.clusters, node);\n } else {\n positionNode(node);\n }\n}\n\nfunction shouldPaintAsCluster(\n node: LayoutData['nodes'][number],\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n options: CommonLayoutPaintOptions\n): node is ClusterNode {\n return node.isGroup === true && (options.isCluster?.(node, context) ?? true);\n}\n\nfunction buildNodeLookup(nodes: LayoutData['nodes']): Map<string, LayoutData['nodes'][number]> {\n const nodeById = new Map<string, LayoutData['nodes'][number]>();\n for (const node of nodes) {\n if (node?.id) {\n nodeById.set(node.id, node);\n }\n }\n return nodeById;\n}\n\nfunction shouldSkipPaintEdge(edge: Edge, options: CommonLayoutPaintOptions): boolean {\n return edge.isLayoutOnly || Boolean(options.skipEdge?.(edge));\n}\n\nasync function paintLayoutEdge(\n groups: CommonLayoutMeasure['groups'],\n edge: Edge,\n nodeById: Map<string, LayoutData['nodes'][number]>,\n data4Layout: LayoutData,\n options: CommonLayoutPaintOptions,\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>\n): Promise<void> {\n const paths = insertEdge(\n groups.edgePaths,\n { ...edge },\n options.clusterDb ?? new Map(),\n data4Layout.type,\n getRenderedNode(edge.start, edge, nodeById, context, options),\n getRenderedNode(edge.end, edge, nodeById, context, options),\n data4Layout.diagramId,\n shouldSkipIntersect(edge, options)\n ) as EdgeRenderPaths | undefined;\n\n if (hasEdgeLabel(edge)) {\n if (!edgeLabels.has(edge.id)) {\n await insertEdgeLabel(groups.edgeLabels, edge);\n }\n positionRenderedEdgeLabel(edge, paths);\n }\n}\n\nfunction getRenderedNode(\n id: string | undefined,\n edge: Edge,\n nodeById: Map<string, LayoutData['nodes'][number]>,\n context: CommonLayoutPaintContext<unknown, CommonLayoutMeasure>,\n options: CommonLayoutPaintOptions\n): LayoutData['nodes'][number] | object {\n return options.getEdgeNode?.(id, edge, context) ?? (id ? (nodeById.get(id) ?? {}) : {});\n}\n\nfunction shouldSkipIntersect(edge: Edge, options: CommonLayoutPaintOptions): boolean {\n return typeof options.skipIntersect === 'function'\n ? options.skipIntersect(edge)\n : (options.skipIntersect ?? false);\n}\n\nfunction positionRenderedEdgeLabel(edge: RenderedEdge, paths?: EdgeRenderPaths): void {\n const path = paths?.updatedPath ?? paths?.originalPath;\n const siteConfig = getConfig();\n const { subGraphTitleTotalMargin } = getSubGraphTitleMargins({\n flowchart: siteConfig.flowchart ?? {},\n });\n if (edge.label) {\n const el = edgeLabels.get(edge.id);\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcLabelPosition(path);\n log.debug(\n 'Moving label ' + edge.label + ' from (',\n x,\n ',',\n y,\n ') to (',\n pos.x,\n ',',\n pos.y,\n ') abc88'\n );\n if (paths?.updatedPath) {\n x = pos.x;\n y = pos.y;\n }\n }\n el.attr('transform', `translate(${x}, ${y! + subGraphTitleTotalMargin / 2})`);\n }\n\n if (edge?.startLabelLeft) {\n const el = terminalLabels.get(edge.id).startLeft;\n let x = edge?.x;\n let y = edge?.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, 'start_left', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.startLabelRight) {\n const el = terminalLabels.get(edge.id).startRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(\n edge.arrowTypeStart ? 10 : 0,\n 'start_right',\n path\n );\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.endLabelLeft) {\n const el = terminalLabels.get(edge.id).endLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_left', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.endLabelRight) {\n const el = terminalLabels.get(edge.id).endRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_right', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n}\n"],
"mappings": "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",
"names": ["createLayoutElementGroups", "element", "edgePathsClass", "rootGroups", "clusters", "edgePaths", "edgeLabels", "nodes", "__name", "measureGroupLabel", "nodesGroup", "node", "shapeSvg", "bbox", "labelHelper", "insertMeasuredNode", "renderOptions", "childNodeEl", "insertNode", "boundingBox", "createGraphWithElements", "data4Layout", "graph", "Graph", "edgesToProcess", "config", "getConfig", "groups", "nodeElements", "hasDom", "edge", "hasEdgeLabel", "insertEdgeLabel", "existingEdge", "captureNodeSizes", "clusterDb", "descendants", "parents", "clear", "__name", "isDescendant", "id", "ancestorId", "ancestorDescendants", "log", "edgeInCluster", "edge", "clusterId", "clusterDescendants", "copy", "graph", "newGraph", "rootId", "nodes", "node", "data", "edges", "e", "extractDescendants", "children", "res", "child", "findCommonEdges", "__name", "graph", "id1", "id2", "edges1", "edge", "edges2", "edges1Prim", "edges2Prim", "edgeIn1", "findNonClusterChild", "id", "clusterId", "children", "log", "reserve", "child", "_id", "commonEdges", "getAnchorId", "clusterDb", "adjustClustersAndEdges", "depth", "descendants", "extractDescendants", "edges", "d1", "isDescendant", "d2", "nonClusterChild", "parent", "hasDirectOutgoingEdge", "isNodeInExtractableCluster", "safeAnchor", "findSafeAnchorNode", "e", "v", "w", "extractor", "nodes", "hasChildren", "node", "dir", "clusterGraph", "Graph", "copy", "data", "sorter", "result", "sorted", "sortNodesByHierarchy", "rootId", "cluster", "excludedCluster", "candidate", "createCommonLayoutRenderer", "prepareLayout", "measureLayout", "runLayoutCore", "paintLayout", "afterPaint", "paintOptions", "measureLayoutFn", "defaultMeasureLayout", "__name", "data4Layout", "svg", "helpers", "options", "element", "markers_default", "clearLayoutRenderState", "renderContext", "measure", "coreResult", "paintContext", "paintLayoutData", "clear", "createGraphWithElements", "context", "groups", "node", "paintLayoutNode", "nodeById", "buildNodeLookup", "edge", "shouldSkipPaintEdge", "paintLayoutEdge", "positionNode", "shouldPaintAsCluster", "insertCluster", "nodes", "paths", "insertEdge", "getRenderedNode", "shouldSkipIntersect", "hasEdgeLabel", "edgeLabels", "insertEdgeLabel", "positionRenderedEdgeLabel", "id", "path", "siteConfig", "getConfig", "subGraphTitleTotalMargin", "getSubGraphTitleMargins", "el", "x", "y", "pos", "utils_default", "log", "terminalLabels"]
}