diff --git a/cypress/platform/knsv-pos.html b/cypress/platform/knsv-pos.html index ce54d42d9..b53598ff4 100644 --- a/cypress/platform/knsv-pos.html +++ b/cypress/platform/knsv-pos.html @@ -105,6 +105,12 @@ stateDiagram S:Stillas T:Tiger U:Ulv + state Z { + state X { + Y:Ypsilon + } + } + A S --> T: angrepp T --> U: Apa @@ -116,7 +122,11 @@ stateDiagram S: { x: 0, y: 0 }, T: { x: 100, y: 100, width: 100, height: 100 }, U: { x: 200, y: 200 }, - V: { x: 300, y: 100 }, + V: { x: 300, y: 120 }, + Z: { x: 300, y: 10, width: 160, height: 100 }, + X: { x: 300, y: 20, width: 80, height: 60 }, + Y: { x: 300, y: 30, width: 50, height: 20 }, + A: { x: 300, y: 75, width: 20, height: 20 }, }, edges: { edge0: { diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html index e4d904528..76c4608fe 100644 --- a/cypress/platform/knsv2.html +++ b/cypress/platform/knsv2.html @@ -75,37 +75,28 @@ -
-%%{
-  init: {
-  "theme":"base",
-  "fontFamily": "Kalam",
-  "themeVariables":
-    {
-      "background": "#FFFFFF",
-      "primaryColor": "#7bdfa7",
-      "primaryTextColor": "#3c3c3b",
-      "secondaryColor": "#642470",
-      "secondaryTextColor": "#3c3c3b",
-      "tertiaryColor": "#1c736D",
-      "tertiaryTextColor": "#3c3c3b",
-      "noteBkgColor": "#9fd8ef",
-      "loopTextColor": "#636362",
-      "labelBoxBkgColor": "#642470",
-      "labelBoxBorderColor": "#642470",
-      "labelTextColor": "#d4d4d4",
-      "signalTextColor": "#636362",
-      "signalColor": "#642470"
-    }
-  }
-}%%
-sequenceDiagram
-    Alice->>+John: Hello John, how are you?
-    Alice->>+John: John, can you hear me?
-    John-->>-Alice: Hi Alice, I can hear you!
-    John-->>-Alice: I feel great!
+    
+stateDiagram
+direction LR
+      state Gorilla0 {
+        state Apa0 {
+          A0 --> B0
+        }
+
+      }
+      Apa0 --> C0
+      A0 --> C0
       
+
+flowchart LR
+    subgraph Gorilla
+      subgraph Apa
+        A[A] --- B
+      end
+    end
+    Apa --- C
+    A --x C
 
     
 stateDiagram
@@ -115,8 +106,16 @@ stateDiagram
       
-stateDiagram
-  state "This is a state description" as S
+      %%{init: {"layout": "dagre", "mergeEdges": false} }%%
+flowchart LR
+      A ==> B(This is B)
+    A[Start] --> B(Is it?)
+    B -- Yes --> C[OK]
+    C --> D[Rethink]
+    D --> B
+    B -. No ...-> E[End]
+
+
       
@@ -135,7 +134,7 @@ flowchart
     if_state --> True : if n >= 0
       
-
+    
       %%{init: {"layout": "elk", "mergeEdges": false, "elk.nodePlacement.strategy": "SIMPLE"} }%%
       stateDiagram
     state if_state <<choice>>
@@ -150,8 +149,10 @@ flowchart
 stateDiagram
   direction TB
   State T1 {
-    T11
+    T11 --> T12
   }
+  T1 --> T2
+  T11 --> T2
       
@@ -211,7 +212,7 @@ stateDiagram
   end note
       
-
+    
 stateDiagram-v2
     direction LR
     [*] --> Active
@@ -234,12 +235,13 @@ stateDiagram-v2
       };
       mermaid.initialize({
         // theme: 'base',
-        handdrawnSeed: 12,
+        // handdrawnSeed: 12,
         look: 'handdrawn',
-        'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
+        // 'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
         // layout: 'dagre',
-        // layout: 'elk',
-        layout: 'fixed',
+        layout: 'elk',
+        // layout: 'fixed',
+        // htmlLabels: false,
         flowchart: { titleTopMargin: 10 },
         // fontFamily: 'Caveat',
         fontFamily: 'Kalam',
diff --git a/packages/mermaid-layout-elk/package.json b/packages/mermaid-layout-elk/package.json
index 45f3871b9..bef3dee6a 100644
--- a/packages/mermaid-layout-elk/package.json
+++ b/packages/mermaid-layout-elk/package.json
@@ -1,5 +1,5 @@
 {
-  "name": "@mermaid-js/layout-elk",
+  "name": "@mermaid-chart/layout-elk",
   "version": "0.0.1",
   "description": "ELK layout engine for mermaid",
   "module": "dist/mermaid-layout-elk.core.mjs",
@@ -40,4 +40,4 @@
   "files": [
     "dist"
   ]
-}
+}
\ No newline at end of file
diff --git a/packages/mermaid-layout-elk/src/render.ts b/packages/mermaid-layout-elk/src/render.ts
index 6b18e2e5d..912066c92 100644
--- a/packages/mermaid-layout-elk/src/render.ts
+++ b/packages/mermaid-layout-elk/src/render.ts
@@ -60,7 +60,7 @@ export const addVertex = async (nodeEl, graph, nodeArr, node) => {
   graph.children.push(child);
   nodeDb[node.id] = child;
 
-  //     // Add the element to the DOM
+  // Add the element to the DOM
   if (!node.isGroup) {
     const childNodeEl = await insertNode(nodeEl, node, node.dir);
     boundingBox = childNodeEl.node().getBBox();
@@ -93,7 +93,7 @@ export const addVertex = async (nodeEl, graph, nodeArr, node) => {
 
 export const addVertices = async function (nodeEl, nodeArr, graph, parentId) {
   const siblings = nodeArr.filter((node) => node.parentId === parentId);
-  log.info('addVertices DAGA', siblings, parentId);
+  log.info('addVertices APA12', siblings, parentId);
   // Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
   await Promise.all(
     siblings.map(async (node) => {
@@ -512,9 +512,7 @@ export const render = async (data4Layout, svg, element, algorithm) => {
     const node = nodeDb[n.id];
 
     // Subgraph
-    console.log('Subgraph XCX before');
     if (parentLookupDb.childrenById[node.id] !== undefined) {
-      console.log('Subgraph XCX', node.id, node, node.labelData);
       node.labels = [
         {
           text: node.labelText,
@@ -553,21 +551,21 @@ export const render = async (data4Layout, svg, element, algorithm) => {
     }
   });
 
-  console.log('before layout', JSON.stringify(elkGraph, null, 2));
+  // log.info('before layout', JSON.stringify(elkGraph, null, 2));
   const g = await elk.layout(elkGraph);
-  log.info('after layout', JSON.stringify(g));
+  // log.info('after layout', JSON.stringify(g));
 
   // debugger;
   drawNodes(0, 0, g.children, svg, subGraphsEl, 0);
   g.edges?.map((edge) => {
     // (elem, edge, clusterDb, diagramType, graph, id)
-    edge.start = nodeDb[edge.sources[0]];
-    edge.end = nodeDb[edge.targets[0]];
-    const sourceId = edge.start.id;
-    const targetId = edge.end.id;
+    const startNode = nodeDb[edge.sources[0]];
+    const endNode = nodeDb[edge.targets[0]];
+    const sourceId = edge.start;
+    const targetId = edge.end;
 
     const offset = calcOffset(sourceId, targetId, parentLookupDb);
-
+    log.info('APA12 offset', offset, sourceId, targetId, edge);
     if (edge.sections) {
       const src = edge.sections[0].startPoint;
       const dest = edge.sections[0].endPoint;
@@ -586,9 +584,11 @@ export const render = async (data4Layout, svg, element, algorithm) => {
         edge,
         clusterDb,
         data4Layout.type,
-        g,
+        startNode,
+        endNode,
         data4Layout.diagramId
       );
+      log.info('APA12 edge points after insert', JSON.stringify(edge.points));
 
       edge.x = edge.labels[0].x + offset.x + edge.labels[0].width / 2;
       edge.y = edge.labels[0].y + offset.y + edge.labels[0].height / 2;
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index 5dbc9ee43..064774c4c 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@mermaid-chart/mermaid",
-  "version": "11.0.0-beta.6",
+  "version": "11.0.0-beta.12",
   "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/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index 605e8d5ea..b2c38efe8 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -1,5 +1,5 @@
 import { select } from 'd3';
-import utils from '../../utils.js';
+import utils, { getEdgeId } from '../../utils.js';
 import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js';
 import common from '../common/common.js';
 import type { LayoutData, LayoutMethod, Node, Edge } from '../../rendering-util/types.js';
@@ -767,6 +767,39 @@ const getTypeFromVertex = (vertex: FlowVertex) => {
   return vertex.type || 'squareRect';
 };
 
+const findNode = (nodes: Node[], id: string) => nodes.find((node) => node.id === id);
+
+const addNodeFromVertex = (
+  vertex: FlowVertex,
+  nodes: Node[],
+  parentDB: Map,
+  subGraphDB: Map,
+  config: any,
+  useRough: boolean
+): Node => {
+  let parentId = parentDB.get(vertex.id);
+  let isGroup = subGraphDB.get(vertex.id) || false;
+
+  let node = findNode(nodes, vertex.id);
+  if (!node) {
+    nodes.push({
+      id: vertex.id,
+      label: vertex.text,
+      labelStyle: '',
+      parentId,
+      padding: config.flowchart?.padding || 8,
+      cssStyles: vertex.styles.join(' '),
+      cssClasses: vertex.classes.join(' '),
+      shape: getTypeFromVertex(vertex),
+      dir: vertex.dir,
+      domId: vertex.domId,
+      type: isGroup ? 'group' : undefined,
+      isGroup,
+      useRough,
+    });
+  }
+};
+
 export const getData = () => {
   const config = getConfig();
   const nodes: Node[] = [];
@@ -775,23 +808,76 @@ export const getData = () => {
   // extract(getRootDocV2());
   // const diagramStates = getStates();
   const useRough = config.look === 'handdrawn';
+  const subGraphs = getSubGraphs();
+  log.info('Subgraphs - APA12', subGraphs);
+  const parentDB = new Map();
+  const subGraphDB = new Map();
+
+  for (let i = subGraphs.length - 1; i >= 0; i--) {
+    const subGraph = subGraphs[i];
+    if (subGraph.nodes.length > 0) {
+      subGraphDB.set(subGraph.id, true);
+    }
+    subGraph.nodes.forEach((id) => {
+      parentDB.set(id, subGraph.id);
+    });
+    nodes.push({
+      id: subGraph.id,
+      label: subGraph.title,
+      labelStyle: '',
+      parentId: parentDB.get(subGraph.id),
+      padding: config.flowchart?.padding || 8,
+      cssStyles: '',
+      cssClasses: '',
+      shape: 'rect',
+      dir: subGraph.dir,
+      domId: subGraph.domId,
+      type: 'group',
+      isGroup: true,
+      useRough,
+    });
+  }
+  console.log('APA12 nodes - 1', nodes.length);
+
   const n = getVertices();
   n.forEach((vertex) => {
-    const node: Node = {
-      id: vertex.id,
-      label: vertex.text,
-      labelStyle: '',
-      padding: config.flowchart?.padding || 8,
-      cssStyles: vertex.styles.join(' '),
-      cssClasses: vertex.classes.join(' '),
-      shape: getTypeFromVertex(vertex),
-      dir: vertex.dir,
-      domId: vertex.domId,
-      type: undefined,
-      isGroup: false,
+    const node = addNodeFromVertex(vertex, nodes, parentDB, subGraphDB, config, useRough);
+    if (node) {
+      nodes.push(node);
+    }
+  });
+
+  console.log('APA12 nodes', nodes.length);
+
+  const e = getEdges();
+  e.forEach((rawEdge, index) => {
+    const edge: Edge = {
+      id: getEdgeId(rawEdge.start, rawEdge.end, { counter: index, prefix: 'edge' }),
+      start: rawEdge.start,
+      end: rawEdge.end,
+      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',
+      arrowheadStyle: 'fill: #333',
+      // stroke: rawEdge.pattern,
+      pattern: rawEdge.stroke,
+      //   shape: getTypeFromVertex(rawEdge),
+      //   dir: rawEdge.dir,
+      //   domId: verawEdgertex.domId,
+      //   rawEdge: undefined,
+      //   isGroup: false,
       useRough,
     };
-    nodes.push(node);
+    // console.log('rawEdge SPLIT', rawEdge, index);
+    edges.push(edge);
   });
 
   //const useRough = config.look === 'handdrawn';
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts b/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
index e3db21540..1be74da55 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDiagram-v2.ts
@@ -1,7 +1,7 @@
 // @ts-ignore: JISON doesn't support types
 import flowParser from './parser/flow.jison';
 import flowDb from './flowDb.js';
-// import flowRendererV2 from './flowRenderer-v2.js';
+import flowRendererV2 from './flowRenderer-v2.js';
 import flowRendererV3 from './flowRenderer-v3-unified.js';
 import flowStyles from './styles.js';
 import type { MermaidConfig } from '../../config.type.js';
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts
index 01bf79fcb..1d6b353d6 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v3-unified.ts
@@ -60,7 +60,8 @@ export const draw = async function (text: string, id: string, _version: string,
   data4Layout.direction = DIR;
   data4Layout.nodeSpacing = conf?.nodeSpacing || 50;
   data4Layout.rankSpacing = conf?.rankSpacing || 50;
-  data4Layout.markers = ['barb'];
+  data4Layout.markers = ['point', 'circle', 'cross'];
+
   data4Layout.diagramId = id;
   console.log('REF1:', data4Layout);
   await render(data4Layout, svg, element);
diff --git a/packages/mermaid/src/diagrams/flowchart/types.ts b/packages/mermaid/src/diagrams/flowchart/types.ts
index 954759f39..59ccf6a1d 100644
--- a/packages/mermaid/src/diagrams/flowchart/types.ts
+++ b/packages/mermaid/src/diagrams/flowchart/types.ts
@@ -23,7 +23,7 @@ export interface FlowEdge {
   end: string;
   interpolate?: string;
   type?: string;
-  stroke?: string;
+  stroke?: 'normal' | 'thick' | 'invisible';
   style?: string[];
   length?: number;
   text: string;
diff --git a/packages/mermaid/src/diagrams/state/dataFetcher.js b/packages/mermaid/src/diagrams/state/dataFetcher.js
index b8302cc22..3bdf1abe0 100644
--- a/packages/mermaid/src/diagrams/state/dataFetcher.js
+++ b/packages/mermaid/src/diagrams/state/dataFetcher.js
@@ -206,8 +206,20 @@ function getClassesFromDbInfo(dbInfoItem) {
   if (dbInfoItem === undefined || dbInfoItem === null) {
     return '';
   } else {
-    if (dbInfoItem.cssClasses) {
-      return dbInfoItem.cssClasses.join(' ');
+    if (dbInfoItem.classes) {
+      let classStr = '';
+      // for each class in classes, add it to the string as comma separated
+      for (let i = 0; i < dbInfoItem.classes.length; i++) {
+        //do not add comma for the last class
+        if (i === dbInfoItem.classes.length - 1) {
+          classStr += dbInfoItem.classes[i];
+        }
+        //add comma for all other classes
+        else {
+          classStr += dbInfoItem.classes[i] + ' ';
+        }
+      }
+      return classStr;
     } else {
       return '';
     }
@@ -224,7 +236,7 @@ export const dataFetcher = (
   look
 ) => {
   const itemId = parsedItem.id;
-  const classStr = getClassesFromDbInfo(diagramStates[itemId]);
+  const classStr = getClassesFromDbInfo(diagramStates.get(itemId));
 
   if (itemId !== 'root') {
     let shape = SHAPE_STATE;
@@ -344,6 +356,7 @@ export const dataFetcher = (
         padding: 0, //getConfig().flowchart.padding
         useRough,
         look,
+        position: parsedItem.note.position,
       };
       const groupData = {
         labelStyle: '',
@@ -358,6 +371,7 @@ export const dataFetcher = (
         padding: 16, //getConfig().flowchart.padding
         useRough,
         look,
+        position: parsedItem.note.position,
       };
       graphItemCount++;
 
diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js
index 1b7f542fb..f6bddf0ea 100644
--- a/packages/mermaid/src/diagrams/state/stateDb.js
+++ b/packages/mermaid/src/diagrams/state/stateDb.js
@@ -579,7 +579,6 @@ export const getData = () => {
   //     nodes.push({...currentDocument.states[key]});
   //   }
   // }
-  extract(getRootDocV2());
   const diagramStates = getStates();
   const config = getConfig();
   const useRough = config.look === 'handdrawn';
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 3ba76ff9f..0237e20b8 100644
--- a/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js
+++ b/packages/mermaid/src/rendering-util/layout-algorithms/dagre/index.js
@@ -230,7 +230,9 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
     log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
 
     edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2));
-    const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, graph, id);
+    const startNode = graph.node(e.v);
+    var endNode = graph.node(e.w);
+    const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, startNode, endNode, id);
     positionEdgeLabel(edge, paths);
   });
 
@@ -284,7 +286,7 @@ export const render = async (data4Layout, svg, element) => {
 
   log.debug('Edges:', data4Layout.edges);
   data4Layout.edges.forEach((edge) => {
-    graph.setEdge(edge.start, edge.end, { ...edge });
+    graph.setEdge(edge.start, edge.end, { ...edge }, edge.id);
   });
 
   log.warn('Graph at first:', JSON.stringify(graphlibJson.write(graph)));
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 f56cba285..73b6797df 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
@@ -159,10 +159,8 @@ export const validate = (graph) => {
  * @param {any} graph
  */
 export const findNonClusterChild = (id, graph) => {
-  // const node = graph.node(id);
   log.trace('Searching', id);
-  // const children = graph.children(id).reverse();
-  const children = graph.children(id); //.reverse();
+  const children = graph.children(id).reverse();
   log.trace('Searching children of id ', id, children);
   if (children.length < 1) {
     log.trace('This is a valid node', id);
diff --git a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js
index 2691e7f3d..510df2855 100644
--- a/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js
+++ b/packages/mermaid/src/rendering-util/layout-algorithms/fixed/index.js
@@ -16,7 +16,11 @@ import {
   clear as clearNodes,
   setNodeElem,
 } from '../../rendering-elements/nodes.js';
-import { insertCluster, clear as clearClusters } from '../../rendering-elements/clusters.js';
+import {
+  insertCluster,
+  clear as clearClusters,
+  positionCluster,
+} from '../../rendering-elements/clusters.js';
 import {
   insertEdgeLabel,
   positionEdgeLabel,
@@ -53,15 +57,28 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => {
   const nodeDB = {};
   await Promise.all(
     data4Layout.nodes.map(async function (node) {
+      let pos;
       if (node.x === undefined || node.y === undefined) {
-        const pos = positions.nodes[node.id];
-        node.x = pos?.x || 0;
-        node.y = pos?.y || 0;
+        pos = positions.nodes[node.id];
         node.height = pos?.height || 0;
         node.width = pos?.width || 0;
       }
-
-      await insertNode(nodes, node, 'TB');
+      if (node.isGroup) {
+        node.x = 0;
+        node.y = 0;
+        await insertCluster(nodes, node, 'TB');
+        // Don't set the coordinates before they "layout", this will mess up the positioning
+        if (pos) {
+          node.x = pos?.x || 0;
+          node.y = pos?.y || 0;
+        }
+      } else {
+        if (pos) {
+          node.x = pos?.x || 0;
+          node.y = pos?.y || 0;
+        }
+        await insertNode(nodes, node, 'TB');
+      }
       nodeDB[node.id] = node;
     })
   );
@@ -79,7 +96,11 @@ const doRender = async (_elem, data4Layout, siteConfig, positions) => {
   // Position the nodes
   await Promise.all(
     data4Layout.nodes.map(async function (node) {
-      positionNode(node);
+      if (node.isGroup) {
+        positionCluster(node);
+      } else {
+        positionNode(node);
+      }
     })
   );
 
diff --git a/packages/mermaid/src/rendering-util/render.ts b/packages/mermaid/src/rendering-util/render.ts
index ece248317..d592334b8 100644
--- a/packages/mermaid/src/rendering-util/render.ts
+++ b/packages/mermaid/src/rendering-util/render.ts
@@ -28,6 +28,10 @@ const registerDefaultLayoutLoaders = () => {
       name: 'fixed',
       loader: async () => await import('./layout-algorithms/fixed/index.js'),
     },
+    // {
+    //   name: 'elk',
+    //   loader: async () => await import('../../../mermaid-layout-elk/src/render.js'),
+    // },
   ]);
 };
 
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js
index 014fc9235..d0133f7d6 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/clusters.js
+++ b/packages/mermaid/src/rendering-util/rendering-elements/clusters.js
@@ -8,6 +8,7 @@ import { createText } from '../createText.ts';
 import intersectRect from '../rendering-elements/intersect/intersect-rect.js';
 import createLabel from './createLabel.js';
 import { createRoundedRectPathD } from './shapes/roundedRectPath.ts';
+import { userNodeOverrides } from '$root/rendering-util/rendering-elements/shapes/handdrawnStyles.js';
 
 // Helper function to calculate the offset correction for the label
 const calcLabelOffsetCorrection = (diff) => {
@@ -17,13 +18,13 @@ const calcLabelOffsetCorrection = (diff) => {
 const rect = (parent, node) => {
   log.info('Creating subgraph rect for ', node.id, node);
   const siteConfig = getConfig();
+  const { themeVariables, handdrawnSeed } = siteConfig;
+  const { clusterBkg, clusterBorder } = themeVariables;
+  let { useRough } = node;
 
   // Add outer g element
   const shapeSvg = parent.insert('g').attr('class', 'cluster').attr('id', node.id);
 
-  // add the rect
-  const rect = shapeSvg.insert('rect', ':first-child');
-
   const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);
 
   // Create the label and insert it after the rect
@@ -49,7 +50,6 @@ const rect = (parent, node) => {
   }
 
   const padding = 0 * node.padding;
-  const halfPadding = padding / 2;
 
   const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
   if (node.width <= bbox.width + padding) {
@@ -58,17 +58,45 @@ const rect = (parent, node) => {
     node.diff = -node.padding / 2;
   }
 
-  log.trace('Data ', node, JSON.stringify(node));
-  // center the rect around its coordinate
-  rect
-    .attr('style', node.cssStyles)
-    .attr('rx', node.rx)
-    .attr('ry', node.ry)
-    .attr('x', node.x - width / 2)
-    .attr('y', node.y - node.height / 2 - halfPadding)
-    .attr('width', width)
-    .attr('height', node.height + padding);
+  const totalWidth = width + padding;
+  const totalHeight = node.height + padding;
+  const x = node.x - totalWidth / 2;
+  const y = node.y - totalHeight / 2;
 
+  log.trace('Data ', node, JSON.stringify(node));
+  let rect;
+  if (useRough) {
+    // @ts-ignore TODO: Fix rough typings
+    const rc = rough.svg(shapeSvg);
+    const options = userNodeOverrides(node, {
+      roughness: 0.7,
+      fill: clusterBkg,
+      // fill: 'red',
+      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);
+      return roughNode;
+    }, ':first-child');
+  } else {
+    // add the rect
+    rect = shapeSvg.insert('rect', ':first-child');
+    // center the rect around its coordinate
+    rect
+      .attr('style', node.cssStyles)
+      .attr('rx', node.rx)
+      .attr('ry', node.ry)
+      .attr('x', x)
+      .attr('y', y)
+      .attr('width', totalWidth)
+      .attr('height', totalHeight);
+  }
   const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);
   if (useHtmlLabels) {
     labelEl.attr(
@@ -311,8 +339,8 @@ const divider = (parent, node) => {
 
   return { cluster: shapeSvg, labelBBox: { width: 0, height: 0 } };
 };
-
-const shapes = { rect, roundedWithTitle, noteGroup, divider };
+const squareRect = rect;
+const shapes = { rect, squareRect, roundedWithTitle, noteGroup, divider };
 
 let clusterElems = {};
 
@@ -335,8 +363,20 @@ export const clear = () => {
 };
 
 export const positionCluster = (node) => {
-  log.info('Position cluster (' + node.id + ', ' + node.x + ', ' + node.y + ')');
+  log.info(
+    'Position cluster (' +
+      node.id +
+      ', ' +
+      node.x +
+      ', ' +
+      node.y +
+      ') (' +
+      node?.width +
+      ', ' +
+      node?.height +
+      ')',
+    clusterElems[node.id]
+  );
   const el = clusterElems[node.id];
-
-  el.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
+  el.cluster.attr('transform', 'translate(' + node.x + ', ' + node.y + ')');
 };
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/edges.js b/packages/mermaid/src/rendering-util/rendering-elements/edges.js
index 68140f705..c8e9a948a 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/edges.js
+++ b/packages/mermaid/src/rendering-util/rendering-elements/edges.js
@@ -494,28 +494,28 @@ function roundedCornersLine(lineData) {
   }
   return path;
 }
-export const insertEdge = function (elem, edge, clusterDb, diagramType, graph, id) {
+export const insertEdge = function (elem, edge, clusterDb, diagramType, startNode, endNode, id) {
   const { handdrawnSeed } = getConfig();
   let points = edge.points;
   let pointsHasChanged = false;
-  const tail = edge.start;
-  var head = edge.end;
+  const tail = startNode;
+  var head = endNode;
 
-  log.info('abc88 InsertEdge: ', points);
+  // log.info('abc88 InsertEdge SPLIT: ', points, edge.start, id);
   if (head.intersect && tail.intersect) {
-    log.info('abc88 InsertEdge: 0.5', points);
-    // points = points.slice(1, edge.points.length - 1);
-    log.info('abc88 InsertEdge: 0.7', points);
-    // points.unshift(tail.intersect(points[0]));
-    //   log.info(
-    //     'Last point abc88',
-    //     points[points.length - 1],
-    //     head,
-    //     head.intersect(points[points.length - 1])
-    //   );
-    //   points.push(head.intersect(points[points.length - 1]));
+    // log.info('abc88 InsertEdge SPLIT: 0.5', points);
+    points = points.slice(1, edge.points.length - 1);
+    // log.info('abc88 InsertEdge SPLIT: 0.7', points);
+    points.unshift(tail.intersect(points[0]));
+    log.info(
+      'Last point abc88',
+      points[points.length - 1],
+      head,
+      head.intersect(points[points.length - 1])
+    );
+    points.push(head.intersect(points[points.length - 1]));
   }
-  log.info('abc88 InsertEdge 2: ', points);
+  // log.info('abc88 InsertEdge 2 SPLIT: ', points);
   if (edge.toCluster) {
     log.info('to cluster abc88', clusterDb[edge.toCluster]);
     points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);
@@ -534,14 +534,14 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, graph, i
   let lineData = points.filter((p) => !Number.isNaN(p.y));
   const { cornerPoints, cornerPointPositions } = extractCornerPoints(lineData);
   lineData = fixCorners(lineData);
-  let lastPoint = lineData[0];
+  let lastPoint = lineData[lineData.length - 1];
   if (lineData.length > 1) {
     lastPoint = lineData[lineData.length - 1];
     const secondLastPoint = lineData[lineData.length - 2];
     // Calculate the mid point of the last two points
-    const diffX = (lastPoint.x - secondLastPoint.x) / 4;
-    const diffY = (lastPoint.y - secondLastPoint.y) / 4;
-    const midPoint = { x: secondLastPoint.x + 3 * diffX, y: secondLastPoint.y + 3 * diffY };
+    const diffX = (lastPoint.x - secondLastPoint.x) / 2;
+    const diffY = (lastPoint.y - secondLastPoint.y) / 2;
+    const midPoint = { x: secondLastPoint.x + diffX, y: secondLastPoint.y + diffY };
     lineData.splice(-1, 0, midPoint);
   }
   // This is the accessor function we talked about above
@@ -597,11 +597,16 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, graph, i
   let useRough = edge.useRough;
   let svgPath;
   let path = '';
-
+  let linePath = lineFunction(lineData);
   if (useRough) {
     const rc = rough.svg(elem);
     const ld = Object.assign([], lineData);
-    const svgPathNode = rc.path(lineFunction(ld.splice(0, ld.length - 1)), {
+    // const svgPathNode = rc.path(lineFunction(ld.splice(0, ld.length-1)), {
+    // const svgPathNode = rc.path(lineFunction(ld), {
+    //   roughness: 0.3,
+    //   seed: handdrawnSeed,
+    // });
+    const svgPathNode = rc.path(linePath, {
       roughness: 0.3,
       seed: handdrawnSeed,
     });
@@ -615,13 +620,12 @@ export const insertEdge = function (elem, edge, clusterDb, diagramType, graph, i
       .attr('class', ' ' + strokeClasses + (edge.classes ? ' ' + edge.classes : ''))
       .attr('style', edge.style);
     let d = svgPath.attr('d');
-    d = d + ' L ' + lastPoint.x + ' ' + lastPoint.y;
     svgPath.attr('d', d);
     elem.node().appendChild(svgPath.node());
   } else {
     svgPath = elem
       .append('path')
-      .attr('d', lineFunction(lineData))
+      .attr('d', linePath)
       .attr('id', edge.id)
       .attr('class', ' ' + strokeClasses + (edge.classes ? ' ' + edge.classes : ''))
       .attr('style', edge.style);
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/markers.js b/packages/mermaid/src/rendering-util/rendering-elements/markers.js
index 55716613b..42c0536da 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/markers.js
+++ b/packages/mermaid/src/rendering-util/rendering-elements/markers.js
@@ -159,11 +159,11 @@ const point = (elem, type, id) => {
     .attr('id', id + '_' + type + '-pointEnd')
     .attr('class', 'marker ' + type)
     .attr('viewBox', '0 0 10 10')
-    .attr('refX', 6)
+    .attr('refX', 5)
     .attr('refY', 5)
     .attr('markerUnits', 'userSpaceOnUse')
-    .attr('markerWidth', 12)
-    .attr('markerHeight', 12)
+    .attr('markerWidth', 8)
+    .attr('markerHeight', 8)
     .attr('orient', 'auto')
     .append('path')
     .attr('d', 'M 0 0 L 10 5 L 0 10 z')
@@ -178,8 +178,8 @@ const point = (elem, type, id) => {
     .attr('refX', 4.5)
     .attr('refY', 5)
     .attr('markerUnits', 'userSpaceOnUse')
-    .attr('markerWidth', 12)
-    .attr('markerHeight', 12)
+    .attr('markerWidth', 11)
+    .attr('markerHeight', 11)
     .attr('orient', 'auto')
     .append('path')
     .attr('d', 'M 0 5 L 10 10 L 10 0 z')
@@ -272,7 +272,7 @@ const barb = (elem, type, id) => {
     .attr('refY', 7)
     .attr('markerWidth', 20)
     .attr('markerHeight', 14)
-    .attr('markerUnits', 'strokeWidth')
+    .attr('markerUnits', 'userSpaceOnUse')
     .attr('orient', 'auto')
     .append('path')
     .attr('d', 'M 19,7 L9,13 L14,7 L9,1 Z');
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts
index 98c6d4707..c72e567cf 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts
@@ -65,7 +65,7 @@ export const question = async (parent: SVGAElement, node: Node): Promise