diff --git a/cypress/integration/rendering/flowchart-elk.spec.js b/cypress/integration/rendering/flowchart-elk.spec.js index 221806b073..e931025e91 100644 --- a/cypress/integration/rendering/flowchart-elk.spec.js +++ b/cypress/integration/rendering/flowchart-elk.spec.js @@ -844,3 +844,42 @@ end }); }); }); + +describe('Title and arrow styling #4813', () => { + it('should render a flowchart with title', () => { + const titleString = 'Test Title'; + renderGraph( + `--- + title: ${titleString} + --- + flowchart LR + A-->B + A-->C`, + { flowchart: { defaultRenderer: 'elk' } } + ); + cy.get('svg').should((svg) => { + const title = svg[0].querySelector('text'); + expect(title.textContent).to.contain(titleString); + }); + }); + + it('Render with stylized arrows', () => { + renderGraph( + ` + flowchart LR + A-->B + B-.-oC + C==xD + D ~~~ A`, + { flowchart: { defaultRenderer: 'elk' } } + ); + cy.get('svg').should((svg) => { + const edges = svg[0].querySelectorAll('.edges path'); + console.log(edges); + expect(edges[0]).to.have.attr('pattern', 'solid'); + expect(edges[1]).to.have.attr('pattern', 'dotted'); + expect(edges[2]).to.have.css('stroke-width', '3.5px'); + expect(edges[3]).to.have.css('stroke-width', '1.5px'); + }); + }); +}); diff --git a/packages/mermaid-flowchart-elk/src/diagram-definition.ts b/packages/mermaid-flowchart-elk/src/diagram-definition.ts index a4e678dcc3..4a6b5b0766 100644 --- a/packages/mermaid-flowchart-elk/src/diagram-definition.ts +++ b/packages/mermaid-flowchart-elk/src/diagram-definition.ts @@ -1,6 +1,6 @@ // @ts-ignore: JISON typing missing import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison'; -import * as db from '../../mermaid/src/diagrams/flowchart/flowDb.js'; +import db from '../../mermaid/src/diagrams/flowchart/flowDb.js'; import styles from '../../mermaid/src/diagrams/flowchart/styles.js'; import renderer from './flowRenderer-elk.js'; diff --git a/packages/mermaid-flowchart-elk/src/flowRenderer-elk.js b/packages/mermaid-flowchart-elk/src/flowRenderer-elk.js index 01ccdd9d96..ea6b9af750 100644 --- a/packages/mermaid-flowchart-elk/src/flowRenderer-elk.js +++ b/packages/mermaid-flowchart-elk/src/flowRenderer-elk.js @@ -6,6 +6,7 @@ import { findCommonAncestor } from './render-utils.js'; import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js'; import { getConfig } from '../../mermaid/src/config.js'; import { log } from '../../mermaid/src/logger.js'; +import utils from '../../mermaid/src/utils.js'; import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js'; import common from '../../mermaid/src/diagrams/common/common.js'; import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.js'; @@ -655,6 +656,11 @@ const insertEdge = function (edgesEl, edge, edgeData, diagObj, parentLookupDb, i .attr('d', curve(points)) .attr('class', 'path ' + edgeData.classes) .attr('fill', 'none'); + Object.entries(edgeData).forEach(([key, value]) => { + if (key !== 'classes') { + edgePath.attr(key, value); + } + }); const edgeG = edgesEl.insert('g').attr('class', 'edgeLabel'); const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl)); const box = edgeWithLabel.node().firstChild.getBoundingClientRect(); @@ -702,21 +708,15 @@ const insertChildren = (nodeArray, parentLookupDb) => { */ export const draw = async function (text, id, _version, diagObj) { - // Add temporary render element - diagObj.db.clear(); + const { securityLevel, flowchart: conf } = getConfig(); nodeDb = {}; portPos = {}; - diagObj.db.setGen('gen-2'); - // Parse the graph definition - diagObj.parser.parse(text); - const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy'); let graph = { id: 'root', layoutOptions: { 'elk.hierarchyHandling': 'INCLUDE_CHILDREN', - 'org.eclipse.elk.padding': '[top=100, left=100, bottom=110, right=110]', - 'elk.layered.spacing.edgeNodeBetweenLayers': '30', + 'elk.layered.spacing.edgeNodeBetweenLayers': conf?.nodeSpacing ? `${conf.nodeSpacing}` : '30', // 'elk.layered.mergeEdges': 'true', 'elk.direction': 'DOWN', // 'elk.ports.sameLayerEdges': true, @@ -744,7 +744,6 @@ export const draw = async function (text, id, _version, diagObj) { graph.layoutOptions['elk.direction'] = 'LEFT'; break; } - const { securityLevel, flowchart: conf } = getConfig(); // Find the root dom node to ne used in rendering // Handle root and document for when rendering in sandbox mode @@ -759,7 +758,6 @@ export const draw = async function (text, id, _version, diagObj) { const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document; const svg = root.select(`[id="${id}"]`); - // Define the supported markers for the diagram const markers = ['point', 'circle', 'cross']; @@ -841,6 +839,7 @@ export const draw = async function (text, id, _version, diagObj) { log.info('after layout', JSON.stringify(graph, null, 2)); const g = await elk.layout(graph); drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0); + utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle()); log.info('after layout', g); g.edges?.map((edge) => { insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id);