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 19638ee5f..bf1d27014 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js @@ -206,8 +206,8 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => { await Promise.all( data4Layout.nodes.map(async function (node) { let pos = positions.nodes[node.id]; - node.height = pos?.height || 50; - node.width = pos?.width || 50; + node.height = pos?.height; + node.width = pos?.width; if (node.isGroup) { node.x = 0; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts index 14484c24a..3b3784c84 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts @@ -49,20 +49,39 @@ export const createInnerCylinderPathD = ( ): string => { return [`M${x - width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 ${width},0`].join(' '); }; + +const MIN_HEIGHT = 50; +const MIN_WIDTH = 25; export const cylinder = async (parent: SVGAElement, node: Node) => { const { themeVariables } = getConfig(); const { useGradient } = themeVariables; const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; - const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); const nodePadding = node.padding ?? 0; const labelPaddingX = node.look === 'neo' ? nodePadding * 2 : nodePadding; const labelPaddingY = node.look === 'neo' ? nodePadding * 1 : nodePadding; - const w = Math.max(bbox.width + labelPaddingY, node.width ?? 0); + + if (node.width || node.height) { + node.width = (node.width ?? 0) - labelPaddingY; + if (node.width < MIN_WIDTH) { + node.width = MIN_WIDTH; + } + + // based on this width, height is calculated + const ry = node.width / 2 / (2.5 + node.width / 50); + node.height = (node.height ?? 0) - labelPaddingX - ry * 3; + if (node.height < MIN_HEIGHT) { + node.height = MIN_HEIGHT; + } + } + + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + + const w = Math.max(bbox.width, node.width ?? 0) + labelPaddingY; const rx = w / 2; const ry = rx / (2.5 + w / 50); - const h = Math.max(bbox.height + ry + labelPaddingX, node.height ?? 0); + const h = Math.max(bbox.height, node.height ?? 0) + labelPaddingX + ry; let cylinder: d3.Selection; const { cssStyles } = node; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts index b16ead2c3..9a50df334 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/tiltedCylinder.ts @@ -49,19 +49,34 @@ export const createInnerCylinderPathD = ( return [`M${x + width / 2},${-height / 2}`, `a${rx},${ry} 0,0,0 0,${height}`].join(' '); }; +const MIN_HEIGHT = 25; +const MIN_WIDTH = 50; + export const tiltedCylinder = async (parent: SVGAElement, node: Node) => { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; - const { shapeSvg, bbox, label, halfPadding } = await labelHelper( - parent, - node, - getNodeClasses(node) - ); - const labelPadding = node.look === 'neo' ? halfPadding * 2 : halfPadding; - const h = bbox.height + labelPadding; + const nodePadding = node.padding ?? 0; + const labelPadding = node.look === 'neo' ? nodePadding : nodePadding / 2; + if (node.width || node.height) { + node.height = (node.height ?? 0) - labelPadding; + if (node.height < MIN_HEIGHT) { + node.height = MIN_HEIGHT; + } + const ry = node.height / 2; + // based on this height, width is calculated + const rx = ry / (2.5 + node.height / 50); + + node.width = (node.width ?? 0) - labelPadding - rx * 3; + if (node.width < MIN_WIDTH) { + node.width = MIN_WIDTH; + } + } + const { shapeSvg, bbox, label } = await labelHelper(parent, node, getNodeClasses(node)); + + const h = Math.max(bbox.height, node.height ?? 0) + labelPadding; const ry = h / 2; const rx = ry / (2.5 + h / 50); - const w = bbox.width + rx + labelPadding; + const w = Math.max(bbox.width, node.width ?? 0) + rx + labelPadding; const { cssStyles } = node; let cylinder: d3.Selection;