Merge branch 'develop' of https://github.com/mermaid-js/mermaid into develop

* 'develop' of https://github.com/mermaid-js/mermaid:
  Fix flowchart-elk render test
  chore: Add example page link in index
  fix: ELK diagram remove re-parsing
  Added linting
  fixed title bounds calculation, removed extra title from merging issues
  Centered Title function and changed rendering order for Elk flowchart to find Boundingbox
  Fixed styling for lines for ELK flowchart
This commit is contained in:
Sidharth Vinod
2024-03-23 15:58:30 +05:30
3 changed files with 49 additions and 11 deletions

View File

@@ -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');
});
});
});

View File

@@ -1,6 +1,6 @@
// @ts-ignore: JISON typing missing // @ts-ignore: JISON typing missing
import parser from '../../mermaid/src/diagrams/flowchart/parser/flow.jison'; 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 styles from '../../mermaid/src/diagrams/flowchart/styles.js';
import renderer from './flowRenderer-elk.js'; import renderer from './flowRenderer-elk.js';

View File

@@ -6,6 +6,7 @@ import { findCommonAncestor } from './render-utils.js';
import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js'; import { labelHelper } from '../../mermaid/src/dagre-wrapper/shapes/util.js';
import { getConfig } from '../../mermaid/src/config.js'; import { getConfig } from '../../mermaid/src/config.js';
import { log } from '../../mermaid/src/logger.js'; import { log } from '../../mermaid/src/logger.js';
import utils from '../../mermaid/src/utils.js';
import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js'; import { setupGraphViewbox } from '../../mermaid/src/setupGraphViewbox.js';
import common from '../../mermaid/src/diagrams/common/common.js'; import common from '../../mermaid/src/diagrams/common/common.js';
import { interpolateToCurve, getStylesFromArray } from '../../mermaid/src/utils.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('d', curve(points))
.attr('class', 'path ' + edgeData.classes) .attr('class', 'path ' + edgeData.classes)
.attr('fill', 'none'); .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 edgeG = edgesEl.insert('g').attr('class', 'edgeLabel');
const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl)); const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl));
const box = edgeWithLabel.node().firstChild.getBoundingClientRect(); const box = edgeWithLabel.node().firstChild.getBoundingClientRect();
@@ -702,21 +708,15 @@ const insertChildren = (nodeArray, parentLookupDb) => {
*/ */
export const draw = async function (text, id, _version, diagObj) { export const draw = async function (text, id, _version, diagObj) {
// Add temporary render element const { securityLevel, flowchart: conf } = getConfig();
diagObj.db.clear();
nodeDb = {}; nodeDb = {};
portPos = {}; 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'); const renderEl = select('body').append('div').attr('style', 'height:400px').attr('id', 'cy');
let graph = { let graph = {
id: 'root', id: 'root',
layoutOptions: { layoutOptions: {
'elk.hierarchyHandling': 'INCLUDE_CHILDREN', 'elk.hierarchyHandling': 'INCLUDE_CHILDREN',
'org.eclipse.elk.padding': '[top=100, left=100, bottom=110, right=110]', 'elk.layered.spacing.edgeNodeBetweenLayers': conf?.nodeSpacing ? `${conf.nodeSpacing}` : '30',
'elk.layered.spacing.edgeNodeBetweenLayers': '30',
// 'elk.layered.mergeEdges': 'true', // 'elk.layered.mergeEdges': 'true',
'elk.direction': 'DOWN', 'elk.direction': 'DOWN',
// 'elk.ports.sameLayerEdges': true, // 'elk.ports.sameLayerEdges': true,
@@ -744,7 +744,6 @@ export const draw = async function (text, id, _version, diagObj) {
graph.layoutOptions['elk.direction'] = 'LEFT'; graph.layoutOptions['elk.direction'] = 'LEFT';
break; break;
} }
const { securityLevel, flowchart: conf } = getConfig();
// Find the root dom node to ne used in rendering // Find the root dom node to ne used in rendering
// Handle root and document for when rendering in sandbox mode // 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 doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0].contentDocument : document;
const svg = root.select(`[id="${id}"]`); const svg = root.select(`[id="${id}"]`);
// Define the supported markers for the diagram // Define the supported markers for the diagram
const markers = ['point', 'circle', 'cross']; 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)); log.info('after layout', JSON.stringify(graph, null, 2));
const g = await elk.layout(graph); const g = await elk.layout(graph);
drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0); drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
log.info('after layout', g); log.info('after layout', g);
g.edges?.map((edge) => { g.edges?.map((edge) => {
insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id); insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id);