diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index 0cdef5043..658a2aa9e 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -85,7 +85,7 @@ end Apa --> C -
+flowchart LR subgraph Apa["Apa"] B["This is B"] @@ -95,7 +95,7 @@ end Apa --> C-+flowchart RL subgraph Apa["Apa"] subgraph Gorilla @@ -107,7 +107,7 @@ end Gorilla --> C-+flowchart LR subgraph Apa["Apa"] subgraph Gorilla @@ -154,11 +154,32 @@ flowchart LR Apa --- C A --x C -++--- +config: + look: neo + theme: neo + layout: elk + elk.mergeEdges: true + themeVariables: {} +--- +%% 'elk.stress', +%% 'elk.force' +%%'elk.mrtree' +%% 'elk.sporeOverlap stateDiagram - S:Stillas - T:Tiger - U:Ulv + direction TB + A --> B + A --> C + A --> D + A --> E + A --> F + state F { + Another + } + Another --> A + +@@ -211,7 +232,7 @@ flowchart if_state --> True : if n >= 0-+%%{init: {"layout": "dagre", "mergeEdges": true} }%% stateDiagram direction TB @@ -232,7 +253,7 @@ State T1 { }-+%%{init: {"layouts": "elk2", "mergeEdges": true} }%% stateDiagram State S1 { @@ -242,7 +263,7 @@ State T1 { S1 --> S2-+%%{init: {"layout": "elk", "mergeEdges": true} }%% stateDiagram State T1 { @@ -252,7 +273,7 @@ State T1 { }-+%%{init: {"layout": "elk", "mergeEdges": true} }%% stateDiagram [*] --> T1 diff --git a/packages/mermaid-layout-elk/package.json b/packages/mermaid-layout-elk/package.json index bef3dee6a..b1d0eb93d 100644 --- a/packages/mermaid-layout-elk/package.json +++ b/packages/mermaid-layout-elk/package.json @@ -1,6 +1,6 @@ { "name": "@mermaid-chart/layout-elk", - "version": "0.0.1", + "version": "0.0.2", "description": "ELK layout engine for mermaid", "module": "dist/mermaid-layout-elk.core.mjs", "types": "dist/packages/mermaid-layout-elk/src/index.d.ts", diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts index 912066c92..d8af5487c 100644 --- a/packages/mermaid-layout-elk/src/render.ts +++ b/packages/mermaid-layout-elk/src/render.ts @@ -465,7 +465,7 @@ export const render = async (data4Layout, svg, element, algorithm) => { 'elk.hierarchyHandling': 'INCLUDE_CHILDREN', 'elk.algorithm': algorithm, 'nodePlacement.strategy': data4Layout.config['elk.nodePlacement.strategy'], - 'elk.layered.mergeEdges': data4Layout.config.mergeEdges, + 'elk.layered.mergeEdges': data4Layout.config['elk.mergeEdges'], 'elk.direction': 'DOWN', 'spacing.baseValue': 30, // 'spacing.nodeNode': 40, diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json index 064774c4c..6bdfa7e4e 100644 --- a/packages/mermaid/package.json +++ b/packages/mermaid/package.json @@ -1,6 +1,6 @@ { "name": "@mermaid-chart/mermaid", - "version": "11.0.0-beta.12", + "version": "11.0.0-beta.15", "description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.", "type": "module", "module": "./dist/mermaid.core.mjs", @@ -137,4 +137,4 @@ "README.md" ], "sideEffects": false -} \ No newline at end of file +} diff --git a/packages/mermaid/src/config.type.ts b/packages/mermaid/src/config.type.ts index 88897345f..0da68187a 100644 --- a/packages/mermaid/src/config.type.ts +++ b/packages/mermaid/src/config.type.ts @@ -89,7 +89,7 @@ export interface MermaidConfig { */ maxEdges?: number; /** - * Elk specific option that allows edge egdes to share path where it convenient. It can make for pretty diagrams but can also make it harder to read the diagram. + * Elk specific option that allows egdes to share path where it convenient. It can make for pretty diagrams but can also make it harder to read the diagram. * */ 'elk.mergeEdges'?: boolean; diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 8bb3d0778..fb0126a05 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts @@ -768,7 +768,25 @@ const getTypeFromVertex = (vertex: FlowVertex) => { }; const findNode = (nodes: Node[], id: string) => nodes.find((node) => node.id === id); +const destructEdgeType = (type: string | undefined) => { + let arrowTypeStart = 'none'; + let arrowTypeEnd = 'arrow_point'; + switch (type) { + case 'arrow_point': + case 'arrow_circle': + case 'arrow_cross': + arrowTypeEnd = type; + break; + case 'double_arrow_point': + case 'double_arrow_circle': + case 'double_arrow_cross': + arrowTypeStart = type.replace('double_', ''); + arrowTypeEnd = arrowTypeStart; + break; + } + return { arrowTypeStart, arrowTypeEnd }; +}; const addNodeFromVertex = ( vertex: FlowVertex, nodes: Node[], @@ -776,7 +794,7 @@ const addNodeFromVertex = ( subGraphDB: Map, config: any, look: string -): Node => { +) => { const parentId = parentDB.get(vertex.id); const isGroup = subGraphDB.get(vertex.id) || false; @@ -793,7 +811,6 @@ const addNodeFromVertex = ( shape: getTypeFromVertex(vertex), dir: vertex.dir, domId: vertex.domId, - type: isGroup ? 'group' : undefined, isGroup, look, }); @@ -805,8 +822,6 @@ export const getData = () => { const nodes: Node[] = []; const edges: Edge[] = []; - // extract(getRootDocV2()); - // const diagramStates = getStates(); const subGraphs = getSubGraphs(); log.info('Subgraphs - APA12', subGraphs); const parentDB = new Map (); @@ -830,26 +845,19 @@ export const getData = () => { cssClasses: '', shape: 'rect', dir: subGraph.dir, - domId: subGraph.domId, - type: 'group', isGroup: true, look: config.look, }); } - console.log('APA12 nodes - 1', nodes.length); const n = getVertices(); n.forEach((vertex) => { const node = addNodeFromVertex(vertex, nodes, parentDB, subGraphDB, config, config.look); - if (node) { - nodes.push(node); - } }); - console.log('APA12 nodes', nodes.length); - const e = getEdges(); e.forEach((rawEdge, index) => { + const { arrowTypeStart, arrowTypeEnd } = destructEdgeType(rawEdge.type); const edge: Edge = { id: getEdgeId(rawEdge.start, rawEdge.end, { counter: index, prefix: 'edge' }), start: rawEdge.start, @@ -857,25 +865,16 @@ export const getData = () => { type: rawEdge.type || 'normal', label: rawEdge.text, labelpos: 'c', - // labelStyle: '', - // cssStyles: rawEdge.styles.join(' '), thickness: rawEdge.stroke, minlen: rawEdge.length, classes: 'edge-thickness-normal edge-pattern-solid flowchart-link', - arrowhead: 'none', - arrowTypeEnd: 'arrow_point', - // arrowTypeEnd: 'arrow_barb', + arrowTypeStart, + arrowTypeEnd, arrowheadStyle: 'fill: #333', - // stroke: rawEdge.pattern, pattern: rawEdge.stroke, - // shape: getTypeFromVertex(rawEdge), - // dir: rawEdge.dir, - // domId: verawEdgertex.domId, - // rawEdge: undefined, - // isGroup: false, look: config.look, }; - // console.log('rawEdge SPLIT', rawEdge, index); + console.log('rawEdge SPLIT', rawEdge, index); edges.push(edge); }); diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts index 1d6b353d6..35d687f9b 100644 --- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts +++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts @@ -36,26 +36,13 @@ export const draw = async function (text: string, id: string, _version: string, // The getData method provided in all supported diagrams is used to extract the data from the parsed structure // into the Layout data format - console.log('Before getData: '); + log.debug('Before getData: '); const data4Layout = diag.db.getData() as LayoutData; - console.log('Data: ', data4Layout); + log.debug('Data: ', data4Layout); // Create the root SVG - the element is the div containing the SVG element const { element, svg } = getDiagramElements(id, securityLevel); - // // For some diagrams this call is not needed, but in the state diagram it is - // await insertElementsForSize(element, data4Layout); - - // console.log('data4Layout:', data4Layout); - - // // Now we have layout data with real sizes, we can perform the layout - // const data4Rendering = doLayout(data4Layout, id, _version, 'dagre-wrapper'); - - // // The performRender method provided in all supported diagrams is used to render the data - // performRender(data4Rendering); - data4Layout.type = diag.type; - // data4Layout.layoutAlgorithm = 'dagre-wrapper'; - // data4Layout.layoutAlgorithm = 'elk'; data4Layout.layoutAlgorithm = layout; data4Layout.direction = DIR; data4Layout.nodeSpacing = conf?.nodeSpacing || 50; @@ -63,7 +50,7 @@ export const draw = async function (text: string, id: string, _version: string, data4Layout.markers = ['point', 'circle', 'cross']; data4Layout.diagramId = id; - console.log('REF1:', data4Layout); + log.debug('REF1:', data4Layout); await render(data4Layout, svg, element); const padding = 8; utils.insertTitle( diff --git a/packages/mermaid/src/diagrams/state/dataFetcher.js b/packages/mermaid/src/diagrams/state/dataFetcher.js index 6e4738038..613fd8779 100644 --- a/packages/mermaid/src/diagrams/state/dataFetcher.js +++ b/packages/mermaid/src/diagrams/state/dataFetcher.js @@ -61,11 +61,9 @@ const setupDoc = (parentParsedItem, doc, diagramStates, nodes, edges, altFlag, l switch (item.stmt) { case STMT_STATE: dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look); - break; case DEFAULT_STATE_TYPE: dataFetcher(parentParsedItem, item, diagramStates, nodes, edges, altFlag, look); - break; case STMT_RELATION: { diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js index 2d8ae7c3e..d4de32889 100644 --- a/packages/mermaid/src/diagrams/state/stateDb.js +++ b/packages/mermaid/src/diagrams/state/stateDb.js @@ -71,6 +71,9 @@ function newClassesList() { return new Map(); } +let nodes = []; +let edges = []; + let direction = DEFAULT_DIAGRAM_DIRECTION; let rootDoc = []; let classes = newClassesList(); // style classes defined by a classDef @@ -222,6 +225,12 @@ const extract = (_doc) => { break; } }); + + const diagramStates = getStates(); + const config = getConfig(); + const look = config.look; + resetDataFetching(); + dataFetcher(undefined, getRootDocV2(), diagramStates, nodes, edges, true, look); }; /** @@ -306,6 +315,8 @@ export const addState = function ( }; export const clear = function (saveCommon) { + nodes = []; + edges = []; documents = { root: newDoc(), }; @@ -571,20 +582,7 @@ const setDirection = (dir) => { const trimColon = (str) => (str && str[0] === ':' ? str.substr(1).trim() : str.trim()); export const getData = () => { - const nodes = []; - const edges = []; - - // for (const key in currentDocument.states) { - // if (currentDocument.states.hasOwnProperty(key)) { - // nodes.push({...currentDocument.states[key]}); - // } - // } - const diagramStates = getStates(); const config = getConfig(); - const look = config.look; - resetDataFetching(); - dataFetcher(undefined, getRootDocV2(), diagramStates, nodes, edges, true, look); - return { nodes, edges, other: {}, config }; }; diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts b/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts index a0b9f92ef..8d3421ed0 100644 --- a/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts +++ b/packages/mermaid/src/diagrams/state/stateRenderer-v3-unified.ts @@ -46,6 +46,7 @@ export const draw = async function ( ) { log.info('REF0:', positions); log.info('Drawing state diagram (v2)', id); + log.info('Diagram Configuration:', getConfig()); const { securityLevel, state: conf, layout } = getConfig(); // Extracting the data from the parsed structure into a more usable form // Not related to the refactoring, but this is the first step in the rendering process 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 f8becf61e..3e8d35ccb 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js @@ -183,11 +183,12 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit const halfPadding = node?.padding / 2 || 0; const labelHeight = node?.labelBBox?.height || 0; const offsetY = labelHeight - halfPadding || 0; - node.y += offsetY / 2 + 2; + node.y += offsetY + (parent?.offsetY / 2 || 0); + // node.offsetY = offsetY; insertCluster(clusters, node); // A cluster in the non-recursive way - log.info( + console.log( 'A tainted cluster node with children XBX', v, node.id, @@ -204,7 +205,6 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit node.y += (parent?.offsetY || 0) / 2; log.info( 'A regular node XBX - using the padding', - v, node.id, 'parent', node.parentId, @@ -216,6 +216,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit node.offsetY, 'parent', parent, + parent?.offsetY, node ); diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js index 3699827a1..959bb0edd 100644 --- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js +++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/mermaid-graphlib.js @@ -162,7 +162,7 @@ const findCommonEdges = (graph, id1, id2) => { return { v: edge.v, w: edge.w }; }); const result = edges1Prim.filter((edgeIn1) => { - return edges2Prim.filter((edge) => edgeIn1.v === edge.v && edgeIn1.w === edge.w).length > 0; + return edges2Prim.some((edge) => edgeIn1.v === edge.v && edgeIn1.w === edge.w); }); return result; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js index c6a700ff1..1db8ed7a1 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js @@ -69,13 +69,12 @@ const rect = (parent, node) => { stroke: clusterBorder, fillWeight: 3, seed: handdrawnSeed, - stroke: clusterBorder, }); const roughNode = rc.path(createRoundedRectPathD(x, y, totalWidth, totalHeight, 0), options); // console.log('Rough node insert CXC', roughNode); rect = shapeSvg.insert(() => { - console.log('Rough node insert CXC', roughNode); + log.debug('Rough node insert CXC', roughNode); return roughNode; }, ':first-child'); } else { @@ -178,7 +177,12 @@ const roundedWithTitle = (parent, node) => { themeVariables; // Add outer g element - const shapeSvg = parent.insert('g').attr('class', node.cssClasses).attr('id', node.id); + const shapeSvg = parent + .insert('g') + .attr('class', node.cssClasses) + .attr('id', node.id) + .attr('data-et', 'node') + .attr('data-id', node.id); // add the rect const outerRectG = shapeSvg.insert('g', ':first-child'); @@ -211,6 +215,12 @@ const roundedWithTitle = (parent, node) => { node.diff = -node.padding / 2; } + // if (node.id === 'Apa0') { + // console.log('XBX here', node); + // node.y += 10; + // } else { + // console.log('XBX there', node); + // } const x = node.x - width / 2 - halfPadding; const y = node.y - node.height / 2 - halfPadding; const innerY = node.y - node.height / 2 - halfPadding + bbox.height + 2; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edges.js b/packages/mermaid/src/rendering-util/rendering-elements/edges.js index f4fdce757..8f136601f 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/edges.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/edges.js @@ -444,7 +444,7 @@ const fixCorners = function (lineData) { const a = Math.sqrt(2) * 2; let newCornerPoint = { x: cornerPoint.x, y: cornerPoint.y }; if (Math.abs(nextPoint.x - prevPoint.x) > 10 && Math.abs(nextPoint.y - prevPoint.y) >= 10) { - console.log( + log.debug( 'Corner point fixing', Math.abs(nextPoint.x - prevPoint.x), Math.abs(nextPoint.y - prevPoint.y) @@ -462,7 +462,7 @@ const fixCorners = function (lineData) { }; } } else { - console.log( + log.debug( 'Corner point skipping fixing', Math.abs(nextPoint.x - prevPoint.x), Math.abs(nextPoint.y - prevPoint.y) diff --git a/packages/mermaid/src/rendering-util/rendering-elements/markers.js b/packages/mermaid/src/rendering-util/rendering-elements/markers.js index 42c0536da..83b6ddd17 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/markers.js +++ b/packages/mermaid/src/rendering-util/rendering-elements/markers.js @@ -178,8 +178,8 @@ const point = (elem, type, id) => { .attr('refX', 4.5) .attr('refY', 5) .attr('markerUnits', 'userSpaceOnUse') - .attr('markerWidth', 11) - .attr('markerHeight', 11) + .attr('markerWidth', 8) + .attr('markerHeight', 8) .attr('orient', 'auto') .append('path') .attr('d', 'M 0 5 L 10 10 L 10 0 z') diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts index 1b3fdf47a..17b555bbe 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/circle.ts @@ -18,7 +18,7 @@ export const circle = async (parent: SVGAElement, node: Node): Promise { const { cssStyles } = node; if (node.look === 'handdrawn') { - // @ts-ignore + // @ts-ignore - rough is not typed const rc = rough.svg(shapeSvg); const outerPathData = createOuterCylinderPathD(0, 0, w, h, rx, ry); const innerPathData = createInnerCylinderPathD(0, ry, w, h, rx, ry); diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts index 8cbbe75ff..fa6182c32 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts @@ -21,7 +21,7 @@ export const doublecircle = async (parent: SVGAElement, node: Node): Promise