diff --git a/packages/mermaid/src/diagrams/state/dataFetcher.js b/packages/mermaid/src/diagrams/state/dataFetcher.js index d553a4834..ce93cd865 100644 --- a/packages/mermaid/src/diagrams/state/dataFetcher.js +++ b/packages/mermaid/src/diagrams/state/dataFetcher.js @@ -302,7 +302,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt domId: stateDomId(itemId, graphItemCount), type: newNode.type, isGroup: newNode.type === 'group', - padding: 15, + padding: 8, rx: 10, ry: 10, useRough, @@ -328,7 +328,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt domId: stateDomId(itemId, graphItemCount, NOTE), type: newNode.type, isGroup: newNode.type === 'group', - padding: 15, //getConfig().flowchart.padding + padding: 0, //getConfig().flowchart.padding useRough, }; const groupData = { @@ -341,7 +341,7 @@ export const dataFetcher = (parent, parsedItem, diagramStates, nodes, edges, alt domId: stateDomId(itemId, graphItemCount, PARENT), type: 'group', isGroup: true, - padding: 0, //getConfig().flowchart.padding + padding: 16, //getConfig().flowchart.padding useRough, }; graphItemCount++; diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js index 3a20a2e0e..ff229600f 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js @@ -54,7 +54,14 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit if (parentCluster !== undefined) { const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); // data.clusterPositioning = true; - log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster); + log.trace( + 'Setting data for parent cluster XXX\n Node.id = ', + v, + '\n data=', + data.height, + '\nParent cluster', + parentCluster.height + ); graph.setNode(parentCluster.id, data); if (!graph.parent(v)) { log.trace('Setting parent', v, parentCluster.id); @@ -64,7 +71,8 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v))); if (node && node.clusterNode) { // const children = graph.children(v); - log.info('Cluster identified', v, node.width, graph.node(v)); + log.info('Cluster identified XXX', v, node.width, graph.node(v)); + // "o" will contain the full cluster not just the children const o = await recursiveRender( nodes, node.graph, @@ -76,10 +84,18 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit const newEl = o.elem; updateNodeBounds(node, newEl); node.diff = o.diff || 0; - log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y); + log.trace( + 'New compound node after recursive render XAX', + v, + 'width', + // node, + node.width, + 'height', + node.height + // node.x, + // node.y + ); setNodeElem(newEl, node); - - log.warn('Recursive render complete ', newEl, node); } else { if (graph.children(v).length > 0) { // This is a cluster but not to be rendered recursively @@ -89,7 +105,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; // insertCluster(clusters, graph.node(v)); } else { - log.info('Node - the non recursive path', v, node.id, node); + log.trace('Node - the non recursive path XAX', v, node.id, node); await insertNode(nodes, graph.node(v), dir); } } @@ -113,20 +129,26 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit graph.edges().forEach(function (e) { log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(e)); }); - log.info('#############################################'); - log.info('### Layout ###'); - log.info('#############################################'); - log.info(graph); + + log.info('############################################# XXX'); + log.info('### Layout ### XXX'); + log.info('############################################# XXX'); + dagreLayout(graph); + log.info('Graph after layout:', graphlibJson.write(graph)); // Move the nodes to the correct place let diff = 0; - const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + log.info('Need the size here XAX', graph.node('T1')?.height); + let { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); + subGraphTitleTotalMargin = 0; sortNodesByHierarchy(graph).forEach(function (v) { const node = graph.node(v); - log.info('Position ' + v + ': ' + JSON.stringify(graph.node(v))); + const p = graph.node(node?.parentId); + subGraphTitleTotalMargin = p?.offsetY || subGraphTitleTotalMargin; + log.info( - 'Position ' + v + ': (' + node.x, + 'Position XAX' + v + ': (' + node.x, ',' + node.y, ') width: ', node.width, @@ -134,19 +156,55 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit node.height ); if (node && node.clusterNode) { - // clusterDb[node.id].node = node; - node.y += subGraphTitleTotalMargin; + const parent = graph.node(node.parentId); + node.y += 2; + node.x -= 8; + log.trace('A tainted cluster node XAX', v, node.id, node.width, node.height, node.x, node.y); + clusterDb[node.id].node = node; + // node.y += subGraphTitleTotalMargin - 10; + node.y -= (node.offsetY || 0) / 2; positionNode(node); } else { // Non cluster node if (graph.children(v).length > 0) { - // A cluster in the non-recursive way - // positionCluster(node); - node.height += subGraphTitleTotalMargin; + node.height += 0; + const parent = graph.node(node.parentId); + node.y += (node.offsetY || 0) / 2; insertCluster(clusters, node); + + // A cluster in the non-recursive way + log.trace( + 'A pure cluster node with children XAX', + v, + node.id, + node.width, + node.height, + node.x, + node.y, + 'offset', + parent?.offsetY + ); clusterDb[node.id].node = node; } else { - node.y += subGraphTitleTotalMargin / 2; + const parent = graph.node(node.parentId); + node.y += (parent?.offsetY || 0) / 2; + log.trace( + 'A regular node XAX - using the padding', + v, + node.id, + 'parent', + node.parentId, + node.width, + node.height, + node.x, + node.y, + 'offsetY', + node.offsetY, + 'parent', + parent, + node + ); + positionNode(node); } } @@ -169,9 +227,14 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit diff = n.diff; } }); + log.trace('Returning from recursive render XAX', elem, diff); return { elem, diff }; }; - +/** + * ############################################################### + * Render the graph + * ############################################################### + */ export const render = async (data4Layout, svg, element) => { // Create the input mermaid.graph const graph = new graphlib.Graph({ @@ -223,13 +286,3 @@ export const render = async (data4Layout, svg, element) => { siteConfig ); }; - -// const shapeDefinitions = {}; -// export const addShape = ({ shapeType: fun }) => { -// shapeDefinitions[shapeType] = fun; -// }; - -// const arrowDefinitions = {}; -// export const addArrow = ({ arrowType: fun }) => { -// arrowDefinitions[arrowType] = fun; -// }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index b807409ed..f8eeed633 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -247,6 +247,8 @@ const roundedWithTitle = (parent, node) => { const rectBox = rect.node().getBBox(); node.height = rectBox.height; + node.offsetX = 0; + node.offsetY = 20; node.intersect = function (point) { return intersectRect(node, point); @@ -292,8 +294,9 @@ const divider = (parent, node) => { } const rectBox = rect.node().getBBox(); node.width = rectBox.width; - node.height = rectBox.height; - node.diff = -node.padding / 2; + node.height = rectBox.height - node.padding; + node.diff = 0; //-node.padding / 2; + node.offsetY = 0; node.intersect = function (point) { return intersectRect(node, point); }; @@ -306,7 +309,6 @@ const shapes = { rect, roundedWithTitle, noteGroup, divider }; let clusterElems = {}; export const insertCluster = (elem, node) => { - log.trace('Inserting cluster'); const shape = node.shape || 'rect'; const cluster = shapes[shape](elem, node); clusterElems[node.id] = cluster; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js b/packages/mermaid/src/rendering-util/rendering-elements/nodes.js index 3013d2fba..7216749c8 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/nodes.js @@ -75,16 +75,12 @@ export const positionNode = (node) => { node, 'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')' ); - const padding = 8; - const diff = node.diff || 0; + + const diff = 0; if (node.clusterNode) { el.attr( 'transform', - 'translate(' + - (node.x + diff - node.width / 2) + - ', ' + - (node.y - node.height / 2 - padding) + - ')' + 'translate(' + (node.x + diff - node.width / 2) + ', ' + (node.y - node.height / 2) + ')' ); } else { el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')'); diff --git a/packages/mermaid/src/schemas/config.schema.yaml b/packages/mermaid/src/schemas/config.schema.yaml index 9146e2d94..46f99ad9e 100644 --- a/packages/mermaid/src/schemas/config.schema.yaml +++ b/packages/mermaid/src/schemas/config.schema.yaml @@ -100,6 +100,11 @@ properties: type: integer default: 500 minimum: 0 + mergeEdges: + description: | + Elk specific option that allows edge egdes to share path where it convenient. It can make for pretty diagrams but can also make it harder to read the diagram. + type: boolean + default: false darkMode: type: boolean default: false