From 9acf55069c6a5841f1ca94d19d45e0420828afc8 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Thu, 15 Aug 2024 14:11:02 +0200 Subject: [PATCH] Mermaid version 11.0.0-b.67, handling of fixed layout without defined positions --- packages/mermaid/package.json | 2 +- .../layout-algorithms/fixed/index.js | 55 +++++++++++++++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 7aa0f6c84..623f7bc7b 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "@mermaid-chart/mermaid", - "version": "11.0.0-b.66", + "version": "11.0.0-b.67", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "module": "./dist/mermaid.core.mjs", 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 83e6e506e..269c37d01 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js @@ -62,18 +62,50 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => { const edgeLabels = elem.insert('g').attr('class', 'edgeLabels'); const nodes = elem.insert('g').attr('class', 'nodes'); + // Add positions for nodes that lack them + let maxY = 0; + data4Layout.nodes.map(function (node) { + const pos = positions.nodes[node.id]; + if (pos) { + let y = pos.y; + if (pos.height) { + y += pos.height; + } else if (node.height) { + y += node.height; + } + + maxY = Math.max(y, maxY); + } + }); + + let cnt = 0; + data4Layout.nodes.map(function (node) { + let pos; + if (!positions.nodes[node.id]) { + positions.nodes[node.id] = { x: cnt * 75, y: maxY + 20 }; + cnt = cnt + 1; + } + // if (node.x === undefined || node.y === undefined) { + pos = positions.nodes[node.id] || { x: 0, y: 0, width: 100, height: 100 }; + node.height = pos?.height || 50; + node.width = pos?.width || 50; + }); + // Insert nodes, this will insert them into the dom and each node will get a size. The size is updated // to the abstract node and is later used by dagre for the layout nodeDB = new Map(); await Promise.all( - data4Layout.nodes.map(async function (node) { + data4Layout.nodes.map(async function (node, i) { let pos; - if (node.x === undefined || node.y === undefined) { - pos = positions.nodes[node.id]; - node.height = pos?.height || 0; - node.width = pos?.width || 0; + if (!positions.nodes[node.id]) { + positions.nodes[node.id] = { x: i * 100, y: maxY + 10, width: 50, height: 50 }; } + // if (node.x === undefined || node.y === undefined) { + pos = positions.nodes[node.id] || { x: 0, y: 0, width: 100, height: 100 }; + node.height = pos?.height || 50; + node.width = pos?.width || 50; + // } if (node.isGroup) { node.x = 0; node.y = 0; @@ -116,8 +148,19 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => { // Insert the edges and position the edge labels for (const edge of data4Layout.edges) { - // log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge); + // console.info('Edge : ' + JSON.stringify(edge), edge); + if (!positions.edges[edge.id]) { + const startNode = positions.nodes[edge.start]; + const endNode = positions.nodes[edge.end]; + positions.edges[edge.id] = { + points: [ + { x: startNode.x, y: startNode.y }, + { x: (startNode.x + endNode.x) / 2, y: (startNode.y + endNode.y) / 2 }, + { x: endNode.x, y: endNode.y }, + ], + }; + } edge.points = fixInterSections(positions.edges[edge.id].points, edge.start, edge.end); const paths = insertEdge( edgePaths,