From 84fc95d7cfffeac380ec147c2a57ec59102685b7 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Fri, 28 Jun 2024 17:50:24 +0200 Subject: [PATCH] Divider layout fix --- .../layout-algorithms/dagre/index.js | 6 +- packages/mermaid/src/rendering-util/render.ts | 37 ++----- .../rendering-elements/clusters.js | 98 ++++++++++++++++++- .../rendering-elements/nodes.js | 9 +- packages/mermaid/src/themes/theme-neo.js | 4 +- 5 files changed, 114 insertions(+), 40 deletions(-) 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 c5855849b..0c382f79f 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js @@ -28,7 +28,7 @@ import { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js' import { getConfig } from '../../../diagram-api/diagramAPI.js'; const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => { - log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster); + log.info('Graph in recursive render: IPI', id, graphlibJson.write(graph), parentCluster); const dir = graph.graph().rankdir; log.trace('Dir in recursive render - dir:', dir); @@ -55,7 +55,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); // data.clusterPositioning = true; log.trace( - 'Setting data for parent cluster XXX\n Node.id = ', + 'Setting data for parent cluster IPI\n Node.id = ', v, '\n data=', data.height, @@ -96,7 +96,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit // node.height = o.diff; node.diff = o.diff || 0; log.info( - 'New compound node after recursive render XAX', + 'New compound node after recursive render IPI', v, 'width', // node, diff --git a/packages/mermaid/src/rendering-util/render.ts b/packages/mermaid/src/rendering-util/render.ts index 8fd3b00ea..8e4572801 100644 --- a/packages/mermaid/src/rendering-util/render.ts +++ b/packages/mermaid/src/rendering-util/render.ts @@ -50,12 +50,14 @@ export const render = async (data4Layout: any, svg: any, element: any, positions // console.log('IPI data4Layout', svg.attr('id')); if (useGradient) { - const gradient = svg.append('linearGradient'); - - gradient + const gradient = svg + .append('linearGradient') .attr('id', svg.attr('id') + '-gradient') - .attr('gradientUnits', 'userSpaceOnUse') - .attr('spreadMethod', 'pad'); + .attr('gradientUnits', 'objectBoundingBox') // Changed to objectBoundingBox for relative sizing + .attr('x1', '0%') + .attr('y1', '0%') + .attr('x2', '100%') + .attr('y2', '0%'); gradient .append('svg:stop') @@ -65,30 +67,7 @@ export const render = async (data4Layout: any, svg: any, element: any, positions gradient .append('svg:stop') - .attr('offset', '10%') - .attr('stop-color', gradientStop) - .attr('stop-opacity', 1); - - gradient - .append('svg:stop') - .attr('offset', '30%') - .attr('stop-color', gradientStart) - .attr('stop-opacity', 1); - - gradient - .append('svg:stop') - .attr('offset', '35%') - .attr('stop-color', gradientStop) - .attr('stop-opacity', 1); - gradient - .append('svg:stop') - .attr('offset', '60%') - .attr('stop-color', gradientStart) - .attr('stop-opacity', 1); - - gradient - .append('svg:stop') - .attr('offset', '80%') + .attr('offset', '100%') // Adjusted to 100% to ensure full gradient spread .attr('stop-color', gradientStop) .attr('stop-opacity', 1); } diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index 11e275a67..6a3acfb28 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -224,7 +224,7 @@ const roundedWithTitle = async (parent, node) => { const innerHeight = node.height + padding - bbox.height - 6; const x = node.x - width / 2; const y = node.y - height / 2; - + node.width = width; const innerY = node.y - node.height / 2 - halfPadding + bbox.height + 2; const look = siteConfig.look; @@ -297,8 +297,94 @@ const roundedWithTitle = async (parent, node) => { return { cluster: shapeSvg, labelBBox: bbox }; }; +const divider = async (parent, node) => { + const siteConfig = getConfig(); -const divider = (parent, node) => { + const { themeVariables, handdrawnSeed } = siteConfig; + const { altBackground, compositeBackground, compositeTitleBackground, nodeBorder } = + themeVariables; + + // Add outer g element + const shapeSvg = parent + .insert('g') + .attr('class', node.cssClasses) + .attr('id', node.id) + .attr('data-et', 'node') + .attr('data-node', 'true') + .attr('data-id', node.id) + .attr('data-look', node.look); + + // add the rect + const outerRectG = shapeSvg.insert('g', ':first-child'); + + // Create the label and insert it after the rect + let innerRect = shapeSvg.append('rect'); + + const padding = 0 * node.padding; + const halfPadding = padding / 2; + + const width = node.width + padding; + + node.diff = -node.padding; + + const height = node.height + padding; + // const height = node.height + padding; + const x = node.x - width / 2; + const y = node.y - height / 2; + node.width = width; + const look = siteConfig.look; + + // add the rect + let rect; + if (node.look === 'handdrawn') { + const isAlt = node.cssClasses.includes('statediagram-cluster-alt'); + const rc = rough.svg(shapeSvg); + const roughOuterNode = + node.rx || node.ry + ? rc.path(createRoundedRectPathD(x, y, width, height, 10), { + roughness: 0.7, + fill: compositeTitleBackground, + fillStyle: 'solid', + stroke: nodeBorder, + seed: handdrawnSeed, + }) + : rc.rectangle(x, y, width, height, { seed: handdrawnSeed }); + + rect = shapeSvg.insert(() => roughOuterNode, ':first-child'); + } else { + rect = outerRectG.insert('rect', ':first-child'); + let outerRectClass = 'outer'; + if (look === 'neo') { + outerRectClass = 'divider'; + } else { + outerRectClass = 'divider'; + } + + // center the rect around its coordinate + rect + .attr('class', outerRectClass) + .attr('x', x) + .attr('y', y) + .attr('width', width) + .attr('height', height) + .attr('data-look', node.look); + } + + const rectBox = rect.node().getBBox(); + node.height = rectBox.height; + node.offsetX = 0; + // Used by layout engine to position subgraph in parent + node.offsetY = 0; + + node.intersect = function (point) { + return intersectRect(node, point); + }; + + return { cluster: shapeSvg, labelBBox: {} }; +}; + +const dividerorg = (parent, node) => { + console.log('Divider node IPI', node); const { handdrawnSeed } = getConfig(); // Add outer g element const shapeSvg = parent @@ -351,7 +437,13 @@ const divider = (parent, node) => { return { cluster: shapeSvg, labelBBox: { width: 0, height: 0 } }; }; const squareRect = rect; -const shapes = { rect, squareRect, roundedWithTitle, noteGroup, divider }; +const shapes = { + rect, + squareRect, + roundedWithTitle, + noteGroup, + divider, +}; let clusterElems = {}; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js b/packages/mermaid/src/rendering-util/rendering-elements/nodes.js index 988598586..e468a086c 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/nodes.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/nodes.js @@ -107,11 +107,12 @@ export const clear = () => { export const positionNode = (node) => { const el = nodeElems[node.id]; - log.trace( - 'Transforming node', - node.diff, + log.info( + 'Transforming node IPI', + node.id, + node?.diff, node, - 'translate(' + (node.x - node.width / 2 - 5) + ', ' + node.width / 2 + ')' + 'translate(' + (node.x - +(node.diff || 0) - node.width / 2) + ', ' + node.width / 2 + ')' ); const padding = 8; const diff = node.diff || 0; diff --git a/packages/mermaid/src/themes/theme-neo.js b/packages/mermaid/src/themes/theme-neo.js index 85f3e6253..899218ca8 100644 --- a/packages/mermaid/src/themes/theme-neo.js +++ b/packages/mermaid/src/themes/theme-neo.js @@ -33,7 +33,9 @@ class Theme { this.useGradient = true; this.gradientStart = '#0042eb'; this.gradientStop = '#eb0042'; - this.dropShadow = 'drop-shadow( 1px 2px 2px rgba(185,185,185,1))'; + // this.dropShadow = 'drop-shadow( 1px 2px 2px rgba(185,185,185,1))'; + // this.dropShadow = 'drop-shadow(0px 2px 2px rgba(0, 0, 0, 0.25));'; + this.dropShadow = 'drop-shadow( 0px 1px 2px rgba(0, 0, 0, 0.25));'; this.tertiaryColor = '#ffffff'; } updateColors() {