diff --git a/cypress/integration/rendering/appli.spec.js b/cypress/integration/rendering/appli.spec.js index 5def96815..51eeb657e 100644 --- a/cypress/integration/rendering/appli.spec.js +++ b/cypress/integration/rendering/appli.spec.js @@ -11,6 +11,27 @@ describe('Git Graph diagram', () => { {} ); }); + it('Should render subgraphs with title margins and edge labels', () => { + imgSnapshotTest( + `flowchart LR + + subgraph TOP + direction TB + subgraph B1 + direction RL + i1 --lb1-->f1 + end + subgraph B2 + direction BT + i2 --lb2-->f2 + end + end + A --lb3--> TOP --lb4--> B + B1 --lb5--> B2 + `, + { flowchart: { subGraphTitleMargin: { top: 10, bottom: 5 } } } + ); + }); // it(`ultraFastTest`, function () { // // Navigate to the url we want to test // // ⭐️ Note to see visual bugs, run the test using the above URL for the 1st run. diff --git a/cypress/integration/rendering/stateDiagram-v2.spec.js b/cypress/integration/rendering/stateDiagram-v2.spec.js index 7bc467c83..4523e38fc 100644 --- a/cypress/integration/rendering/stateDiagram-v2.spec.js +++ b/cypress/integration/rendering/stateDiagram-v2.spec.js @@ -581,6 +581,20 @@ style AState fill:#636,border:1px solid red,color:white; { logLevel: 0, fontFamily: 'courier' } ); }); + it(' should allow styles to take effect in stubgraphs', () => { + imgSnapshotTest( + ` + stateDiagram + state roundWithTitle { + C: Black with white text + } + D: Black with white text + + style C,D stroke:#00f, fill:black, color:white + `, + { logLevel: 0, fontFamily: 'courier' } + ); + }); }); it('1433: should render a simple state diagram with a title', () => { imgSnapshotTest( diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index b5b5130d4..4b81ace68 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -901,6 +901,8 @@ export const getData = () => { arrowTypeStart, arrowTypeEnd, arrowheadStyle: 'fill: #333', + labelStyle: rawEdge.style, + style: rawEdge.style, pattern: rawEdge.stroke, look: config.look, }; diff --git a/packages/mermaid/src/rendering-util/createText.ts b/packages/mermaid/src/rendering-util/createText.ts index c656ef78b..ae22f31dd 100644 --- a/packages/mermaid/src/rendering-util/createText.ts +++ b/packages/mermaid/src/rendering-util/createText.ts @@ -115,7 +115,7 @@ function createFormattedText( ) { const lineHeight = 1.1; const labelGroup = g.append('g'); - const bkg = labelGroup.insert('rect').attr('class', 'background'); + const bkg = labelGroup.insert('rect').attr('class', 'background').attr('style', 'stroke: none'); const textElement = labelGroup.append('text').attr('y', '-10.1'); let lineIndex = 0; for (const line of structuredText) { @@ -202,16 +202,16 @@ export const createText = async ( } = {}, config: MermaidConfig ) => { - // log.info( - // 'IPI createText', - // text, - // style, - // isTitle, - // classes, - // useHtmlLabels, - // isNode, - // addSvgBackground - // ); + log.info( + 'XXX createText', + text, + style, + isTitle, + classes, + useHtmlLabels, + isNode, + addSvgBackground + ); if (useHtmlLabels) { // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that? @@ -227,6 +227,10 @@ export const createText = async ( } else { const structuredText = markdownToLines(text, config); const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + svgLabel.setAttribute( + 'style', + style.replace('fill:', 'color:') + (isNode ? ';text-anchor: middle;' : '') + ); return svgLabel; } }; 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 699027d97..95a44ab5b 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js @@ -252,7 +252,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit node.height, graph.parent(v) ); - node.height += 0; + node.height += subGraphTitleTotalMargin; graph.node(node.parentId); const halfPadding = node?.padding / 2 || 0; const labelHeight = node?.labelBBox?.height || 0; @@ -267,7 +267,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit } else { // Regular node const parent = graph.node(node.parentId); - node.y += (parent?.offsetY || 0) / 2; + node.y += subGraphTitleTotalMargin / 2; log.info( 'A regular node XBX1 - using the padding', node.id, @@ -297,7 +297,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge); // OBS HERE - // edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2)); + edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2)); const startNode = graph.node(e.v); var endNode = graph.node(e.w); const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, startNode, endNode, id); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edges.js b/packages/mermaid/src/rendering-util/rendering-elements/edges.js index ef90b5c13..88096ac4f 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/edges.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/edges.js @@ -19,17 +19,29 @@ export const clear = () => { terminalLabels = {}; }; +export const getLabelStyles = (styleArray) => { + let styles = styleArray ? styleArray.reduce((acc, style) => acc + ';' + style, '') : ''; + return styles; +}; + export const insertEdgeLabel = async (elem, edge) => { const useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels); + // Create the actual text element - const labelElement = - edge.labelType === 'markdown' - ? await createText(elem, edge.label, { - style: edge.labelStyle, - useHtmlLabels, - addSvgBackground: true, - }) - : await createLabel(edge.label, edge.labelStyle); + // const labelElement = + // edge.labelType === 'markdown' + // ? await createText(elem, edge.label, { + // style: labelStyles, + // useHtmlLabels, + // addSvgBackground: true, + // }) + // : await createLabel(edge.label, getLabelStyles(edge.labelStyle)); + const labelElement = await createText(elem, edge.label, { + style: getLabelStyles(edge.labelStyle), + useHtmlLabels, + addSvgBackground: true, + isNode: false, + }); log.info('abc82', edge, edge.labelType); // Create outer g, edgeLabel, this will be positioned after graph layout @@ -60,7 +72,10 @@ export const insertEdgeLabel = async (elem, edge) => { let fo; if (edge.startLabelLeft) { // Create the actual text element - const startLabelElement = await createLabel(edge.startLabelLeft, edge.labelStyle); + const startLabelElement = await createLabel( + edge.startLabelLeft, + getLabelStyles(edge.labelStyle) + ); const startEdgeLabelLeft = elem.insert('g').attr('class', 'edgeTerminals'); const inner = startEdgeLabelLeft.insert('g').attr('class', 'inner'); fo = inner.node().appendChild(startLabelElement); @@ -74,7 +89,10 @@ export const insertEdgeLabel = async (elem, edge) => { } if (edge.startLabelRight) { // Create the actual text element - const startLabelElement = await createLabel(edge.startLabelRight, edge.labelStyle); + const startLabelElement = await createLabel( + edge.startLabelRight, + getLabelStyles(edge.labelStyle) + ); const startEdgeLabelRight = elem.insert('g').attr('class', 'edgeTerminals'); const inner = startEdgeLabelRight.insert('g').attr('class', 'inner'); fo = startEdgeLabelRight.node().appendChild(startLabelElement); @@ -90,7 +108,7 @@ export const insertEdgeLabel = async (elem, edge) => { } if (edge.endLabelLeft) { // Create the actual text element - const endLabelElement = await createLabel(edge.endLabelLeft, edge.labelStyle); + const endLabelElement = await createLabel(edge.endLabelLeft, getLabelStyles(edge.labelStyle)); const endEdgeLabelLeft = elem.insert('g').attr('class', 'edgeTerminals'); const inner = endEdgeLabelLeft.insert('g').attr('class', 'inner'); fo = inner.node().appendChild(endLabelElement); @@ -107,7 +125,7 @@ export const insertEdgeLabel = async (elem, edge) => { } if (edge.endLabelRight) { // Create the actual text element - const endLabelElement = await createLabel(edge.endLabelRight, edge.labelStyle); + const endLabelElement = await createLabel(edge.endLabelRight, getLabelStyles(edge.labelStyle)); const endEdgeLabelRight = elem.insert('g').attr('class', 'edgeTerminals'); const inner = endEdgeLabelRight.insert('g').attr('class', 'inner'); @@ -137,7 +155,7 @@ function setTerminalWidth(fo, value) { } export const positionEdgeLabel = (edge, paths) => { - log.info('Moving label abc78 ', edge.id, edge.label, edgeLabels[edge.id]); + log.debug('Moving label abc88 ', edge.id, edge.label, edgeLabels[edge.id], paths); let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; const siteConfig = getConfig(); const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); @@ -148,8 +166,8 @@ export const positionEdgeLabel = (edge, paths) => { if (path) { // // debugger; const pos = utils.calcLabelPosition(path); - log.info( - 'Moving label ' + edge?.id + ' from (', + log.debug( + 'Moving label ' + edge.label + ' from (', x, ',', y, @@ -157,7 +175,7 @@ export const positionEdgeLabel = (edge, paths) => { pos.x, ',', pos.y, - ') abc78' + ') abc88' ); if (paths.updatedPath) { x = pos.x; diff --git a/packages/mermaid/src/rendering-util/types.d.ts b/packages/mermaid/src/rendering-util/types.d.ts index bece69659..52d158b77 100644 --- a/packages/mermaid/src/rendering-util/types.d.ts +++ b/packages/mermaid/src/rendering-util/types.d.ts @@ -72,7 +72,7 @@ interface Edge { id: string; label?: string; classes?: string; - style?: string; + style?: string[]; // Properties common to both Flowchart and State Diagram edges arrowhead?: string; arrowheadStyle?: string; @@ -91,7 +91,7 @@ interface Edge { // Rendering specific properties curve?: string; labelpos?: string; - labelStyle?: string; + labelStyle?: string[]; minlen?: number; pattern?: string; thickness?: 'normal' | 'thick' | 'invisible';