diff --git a/cypress/platform/saurabh.html b/cypress/platform/saurabh.html index abd8d058e..45c350756 100644 --- a/cypress/platform/saurabh.html +++ b/cypress/platform/saurabh.html @@ -62,18 +62,19 @@
-      flowchart LR
-       B2@{ icon: "fa:bell", form: "square", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "t" }@
+      flowchart TD
+       B2@{ icon: "fa:bell", form: "square", label: "B2 agsyua duadu", pos: "t", h: 80 }@
        
 
        W --> B2
        X --> B2
        Y --> B2
        Z --> B2
+       B2 --sas--> C
 
 
     
-
+    
       flowchart TB
        A --test2--> B2@{ icon: "fa:bell", form: "rounded", label: "B2 aiduaid uyawduad uaduabd uyduadb", pos: "b" }@
        B2 --test--> C
@@ -145,7 +146,7 @@
         // layout: 'elk',
         // layout: 'fixed',
         // htmlLabels: false,
-        flowchart: { titleTopMargin: 10, htmlLables: true },
+        flowchart: { titleTopMargin: 10, htmlLabels: true },
         // fontFamily: 'Caveat',
         fontFamily: 'Kalam',
         // fontFamily: 'courier',
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
index bfdfa1635..96c2df848 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
@@ -8,8 +8,7 @@ import intersect from '../intersect/index.js';
 import { getIconSVG } from '../../icons.js';
 import { getConfig } from '../../../diagram-api/diagramAPI.js';
 
-export const icon = async (parent: SVG, node: Node, dir: string) => {
-  const translateHorizontal = dir === 'TB' || dir === 'BT' || dir === 'TD' || dir === 'DT';
+export const icon = async (parent: SVG, node: Node) => {
   const { labelStyles } = styles2String(node);
   node.labelStyle = labelStyles;
   const assetHeight = node.assetHeight ?? 48;
@@ -50,25 +49,71 @@ export const icon = async (parent: SVG, node: Node, dir: string) => {
     const iconHeight = iconBBox.height;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + (translateHorizontal ? bbox.height / 2 : 0) : -height / 2 - (translateHorizontal ? bbox.height / 2 : 0)})`
+      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})`
     );
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 2.5 - (translateHorizontal ? bbox.height / 2 : bbox.height) : height / 2 + 2.5 - (translateHorizontal ? bbox.height / 2 : 0)})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
   );
 
-  if (translateHorizontal) {
-    iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
-  }
+  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
 
   updateNodeBounds(node, shapeSvg);
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
-    const pos = intersect.rect(node, point);
-    return pos;
+    if (!node.label) {
+      return intersect.rect(node, point);
+    }
+    const dx = node.x ?? 0;
+    const dy = node.y ?? 0;
+    const nodeWidth = node.width ?? 0;
+    const nodeHeight = node.height ?? 0;
+
+    if (topLabel) {
+      const points = [
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    } else {
+      const points = [
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy - nodeHeight / 2 },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width, y: dy - nodeHeight / 2 },
+        {
+          x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width,
+          y: dy - nodeHeight / 2 + height,
+        },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 - bbox.height },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy + nodeHeight / 2 - bbox.height },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    }
   };
 
   return shapeSvg;
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
index 870fb6675..958a93dc3 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
@@ -9,8 +9,7 @@ import { getIconSVG } from '../../icons.js';
 import { getConfig } from '../../../diagram-api/diagramAPI.js';
 import { createRoundedRectPathD } from './roundedRectPath.js';
 
-export const iconRounded = async (parent: SVG, node: Node, dir: string) => {
-  const translateHorizontal = dir === 'TB' || dir === 'BT' || dir === 'TD' || dir === 'DT';
+export const iconRounded = async (parent: SVG, node: Node) => {
   const { labelStyles, nodeStyles } = styles2String(node);
   node.labelStyle = labelStyles;
   const assetHeight = node.assetHeight ?? 48;
@@ -59,18 +58,16 @@ export const iconRounded = async (parent: SVG, node: Node, dir: string) => {
     const iconHeight = iconBBox.height;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + (translateHorizontal ? bbox.height / 2 : 0) : -height / 2 + halfPadding - (translateHorizontal ? bbox.height / 2 : 0)})`
+      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})`
     );
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 2.5 - (translateHorizontal ? bbox.height / 2 : bbox.height) : height / 2 + 5 - (translateHorizontal ? bbox.height / 2 : 0)})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
   );
 
-  if (translateHorizontal) {
-    iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
-  }
+  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
 
   if (cssStyles && node.look !== 'handDrawn') {
     iconShape.selectAll('path').attr('style', cssStyles);
@@ -84,8 +81,56 @@ export const iconRounded = async (parent: SVG, node: Node, dir: string) => {
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
-    const pos = intersect.rect(node, point);
-    return pos;
+    if (!node.label) {
+      return intersect.rect(node, point);
+    }
+    const dx = node.x ?? 0;
+    const dy = node.y ?? 0;
+    const nodeWidth = node.width ?? 0;
+    const nodeHeight = node.height ?? 0;
+
+    if (topLabel) {
+      const points = [
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    } else {
+      const points = [
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy - nodeHeight / 2 },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width, y: dy - nodeHeight / 2 },
+        {
+          x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width,
+          y: dy - nodeHeight / 2 + height,
+        },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 - bbox.height },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy + nodeHeight / 2 - bbox.height },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    }
   };
 
   return shapeSvg;
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
index 7b598d5d7..908210f3d 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
@@ -8,8 +8,7 @@ import intersect from '../intersect/index.js';
 import { getIconSVG } from '../../icons.js';
 import { getConfig } from '../../../diagram-api/diagramAPI.js';
 
-export const iconSquare = async (parent: SVG, node: Node, dir: string) => {
-  const translateHorizontal = dir === 'TB' || dir === 'BT' || dir === 'TD' || dir === 'DT';
+export const iconSquare = async (parent: SVG, node: Node) => {
   const { labelStyles, nodeStyles } = styles2String(node);
   node.labelStyle = labelStyles;
   const assetHeight = node.assetHeight ?? 48;
@@ -58,18 +57,16 @@ export const iconSquare = async (parent: SVG, node: Node, dir: string) => {
     const iconHeight = iconBBox.height;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + (translateHorizontal ? bbox.height / 2 : 0) : -height / 2 + halfPadding - (translateHorizontal ? bbox.height / 2 : 0)})`
+      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})`
     );
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 2.5 - (translateHorizontal ? bbox.height / 2 : bbox.height) : height / 2 + 5 - (translateHorizontal ? bbox.height / 2 : 0)})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
   );
 
-  if (translateHorizontal) {
-    iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
-  }
+  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
 
   if (cssStyles && node.look !== 'handDrawn') {
     iconShape.selectAll('path').attr('style', cssStyles);
@@ -83,8 +80,56 @@ export const iconSquare = async (parent: SVG, node: Node, dir: string) => {
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
-    const pos = intersect.rect(node, point);
-    return pos;
+    if (!node.label) {
+      return intersect.rect(node, point);
+    }
+    const dx = node.x ?? 0;
+    const dy = node.y ?? 0;
+    const nodeWidth = node.width ?? 0;
+    const nodeHeight = node.height ?? 0;
+
+    if (topLabel) {
+      const points = [
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 - bbox.height / 2 },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy + nodeHeight / 2 - bbox.height / 2,
+        },
+        {
+          x: dx + nodeWidth / 2 - (bbox.width - width) / 2 - width,
+          y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2,
+        },
+        { x: dx - nodeWidth / 2, y: dy - nodeHeight / 2 + bbox.height - bbox.height / 2 },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    } else {
+      const points = [
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy - nodeHeight / 2 },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width, y: dy - nodeHeight / 2 },
+        {
+          x: dx - nodeWidth / 2 + (bbox.width - width) / 2 + width,
+          y: dy - nodeHeight / 2 + height,
+        },
+        { x: dx + nodeWidth / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 },
+        { x: dx - nodeWidth / 2, y: dy + nodeHeight / 2 - bbox.height },
+        { x: dx - nodeWidth / 2 + (bbox.width - width) / 2, y: dy + nodeHeight / 2 - bbox.height },
+      ];
+      const pos = intersect.polygon(node, points, point);
+      return pos;
+    }
   };
 
   return shapeSvg;
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js b/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js
index 1a432939b..1e68bb204 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/util.js
@@ -36,7 +36,7 @@ export const labelHelper = async (parent, node, _classes) => {
     width: node.width || getConfig().flowchart.wrappingWidth,
     cssClasses: 'markdown-node-label',
     style: node.labelStyle,
-    addSvgBackground: !!node.icon,
+    addSvgBackground: !!node.icon || !!node.img,
   });
   // Get the size of the label
   let bbox = text.getBBox();