From f035db2febde3aa8159265d1419509a98b14d7b5 Mon Sep 17 00:00:00 2001 From: saurabhg772244 Date: Wed, 18 Sep 2024 21:40:55 +0530 Subject: [PATCH] fixed icon shape padding --- cypress/platform/saurabh.html | 14 +-- .../rendering-elements/shapes/icon.ts | 92 +++++++++---------- .../rendering-elements/shapes/iconCircle.ts | 54 +++++++---- .../rendering-elements/shapes/iconRounded.ts | 88 +++++++++--------- .../rendering-elements/shapes/iconSquare.ts | 86 ++++++++--------- 5 files changed, 175 insertions(+), 159 deletions(-) diff --git a/cypress/platform/saurabh.html b/cypress/platform/saurabh.html index b83aa2a3b..ecf3463c1 100644 --- a/cypress/platform/saurabh.html +++ b/cypress/platform/saurabh.html @@ -62,16 +62,18 @@
-      flowchart TD
-       B2@{ icon: "fa:bell", form: "square", pos: "t", h: 80 }
+      flowchart LR
+       B2@{ icon: "fa:address-book",  form: "square", pos: "b", h: 80 }
 
 
-       W --> B2
-       X --> B2
-       Y --> B2
-       Z --> B2
+       W --> B2 --> x1
+       X --> B2 --> x2
+       Y --> B2 --> x3
+       Z --> B2 --> x4 
        B2 --sas--> C
 
+       A --> B2
+
 
     
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 051ae3119..f1c928346 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/icon.ts
@@ -19,18 +19,20 @@ export const icon = async (
   const iconSize = Math.max(assetHeight, assetWidth);
   const defaultWidth = flowchart?.wrappingWidth;
   node.width = Math.max(iconSize, defaultWidth ?? 0);
-  const { nodeBorder } = themeVariables;
-  const { stylesMap } = compileStyles(node);
   const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
 
   const topLabel = node.pos === 't';
 
   const height = iconSize;
-  const width = Math.max(iconSize, bbox.width);
+  const width = iconSize;
+  const { nodeBorder } = themeVariables;
+  const { stylesMap } = compileStyles(node);
 
   const x = -width / 2;
   const y = -height / 2;
 
+  const labelPadding = node.label ? 8 : 0;
+
   // @ts-ignore - rough is not typed
   const rc = rough.svg(shapeSvg);
   const options = userNodeOverrides(node, { stroke: 'none', fill: 'none' });
@@ -42,7 +44,17 @@ export const icon = async (
 
   const iconNode = rc.rectangle(x, y, width, height, options);
 
+  const outerWidth = Math.max(width, bbox.width);
+  const outerHeight = height + bbox.height + labelPadding;
+
+  const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
+    ...options,
+    fill: 'none',
+    stroke: 'none',
+  });
+
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
+  const outerShape = shapeSvg.insert(() => outerNode);
 
   if (node.icon) {
     const iconElem = shapeSvg.append('g');
@@ -52,21 +64,26 @@ export const icon = async (
     const iconBBox = iconElem.node().getBBox();
     const iconWidth = iconBBox.width;
     const iconHeight = iconBBox.height;
+    const iconX = iconBBox.x;
+    const iconY = iconBBox.y;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight + bbox.height / 2 : -height / 2 - bbox.height / 2})`
+      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - iconY : -outerHeight / 2 - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - bbox.height / 2 - labelPadding / 2 : height / 2 - bbox.height / 2 + labelPadding / 2})`
   );
 
-  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
+  iconShape.attr(
+    'transform',
+    `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
+  );
 
-  updateNodeBounds(node, shapeSvg);
+  updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
@@ -75,51 +92,34 @@ export const icon = async (
     }
     const dx = node.x ?? 0;
     const dy = node.y ?? 0;
-    const nodeWidth = node.width ?? 0;
     const nodeHeight = node.height ?? 0;
-
+    let points = [];
     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 },
+      points = [
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
       ];
-      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 },
+      points = [
+        { x: dx - width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + height },
       ];
-      const pos = intersect.polygon(node, points, point);
-      return pos;
     }
+
+    const pos = intersect.polygon(node, points, point);
+    return pos;
   };
 
   return shapeSvg;
diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
index 2d0072d11..df7c55f53 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconCircle.ts
@@ -19,15 +19,13 @@ export const iconCircle = async (
   const iconSize = Math.max(assetHeight, assetWidth);
   const defaultWidth = flowchart?.wrappingWidth;
   node.width = Math.max(iconSize, defaultWidth ?? 0);
-  const { shapeSvg, bbox, halfPadding, label } = await labelHelper(
-    parent,
-    node,
-    'icon-shape default'
-  );
+  const { shapeSvg, bbox, label } = await labelHelper(parent, node, 'icon-shape default');
+
+  const padding = 20;
+  const labelPadding = node.label ? 8 : 0;
 
   const topLabel = node.pos === 't';
 
-  const diameter = iconSize + halfPadding * 2;
   const { nodeBorder, mainBkg } = themeVariables;
   const { stylesMap } = compileStyles(node);
   // @ts-ignore - rough is not typed
@@ -39,32 +37,48 @@ export const iconCircle = async (
     options.fillStyle = 'solid';
   }
 
-  const iconNode = rc.circle(0, 0, diameter, options);
-
-  const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
   const iconElem = shapeSvg.append('g');
   if (node.icon) {
     iconElem.html(
       `${await getIconSVG(node.icon, { height: iconSize, fallbackPrefix: '' })}`
     );
-    const iconBBox = iconElem.node().getBBox();
-    const iconWidth = iconBBox.width;
-    const iconHeight = iconBBox.height;
-    iconElem.attr(
-      'transform',
-      `translate(${-iconWidth / 2},${topLabel ? diameter / 2 - iconHeight - halfPadding + bbox.height / 2 : -diameter / 2 + halfPadding - bbox.height / 2})`
-    );
-    iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
   }
+  const iconBBox = iconElem.node().getBBox();
+  const iconWidth = iconBBox.width;
+  const iconHeight = iconBBox.height;
+  const iconX = iconBBox.x;
+  const iconY = iconBBox.y;
 
+  const diameter = Math.max(iconWidth, iconHeight) + padding * 2;
+  const iconNode = rc.circle(0, 0, diameter, options);
+
+  const outerWidth = Math.max(diameter, bbox.width);
+  const outerHeight = diameter + bbox.height + labelPadding;
+
+  const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
+    ...options,
+    fill: 'none',
+    stroke: 'none',
+  });
+
+  const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
+  const outerShape = shapeSvg.insert(() => outerNode);
+  iconElem.attr(
+    'transform',
+    `translate(${-iconWidth / 2 - iconX},${topLabel ? diameter / 2 - iconHeight - padding + bbox.height / 2 - iconY : -diameter / 2 + padding - bbox.height / 2 - labelPadding / 2 - iconY})`
+  );
+  iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
   label.attr(
     'transform',
-    `translate(${-diameter / 2 + diameter / 2 - bbox.width / 2},${topLabel ? -diameter / 2 - bbox.height / 2 : diameter / 2 - bbox.height / 2})`
+    `translate(${-diameter / 2 + diameter / 2 - bbox.width / 2},${topLabel ? -diameter / 2 - bbox.height / 2 : diameter / 2 - bbox.height / 2 + labelPadding / 2})`
   );
 
-  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
+  iconShape.attr(
+    'transform',
+    `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2 - labelPadding / 2})`
+  );
 
-  updateNodeBounds(node, shapeSvg);
+  updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
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 8aca67682..1c5d46568 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconRounded.ts
@@ -1,6 +1,6 @@
 import { log } from '../../../logger.js';
 import { labelHelper, updateNodeBounds } from './util.js';
-import type { Node, RenderOptions } from '../../types.js';
+import type { Node, RenderOptions } from '../../types.d.ts';
 import type { SVG } from '../../../diagram-api/types.js';
 import { compileStyles, styles2String, userNodeOverrides } from './handDrawnShapeStyles.js';
 import rough from 'roughjs';
@@ -36,6 +36,8 @@ export const iconRounded = async (
   const x = -width / 2;
   const y = -height / 2;
 
+  const labelPadding = node.label ? 8 : 0;
+
   // @ts-ignore - rough is not typed
   const rc = rough.svg(shapeSvg);
   const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') || mainBkg });
@@ -47,7 +49,17 @@ export const iconRounded = async (
 
   const iconNode = rc.path(createRoundedRectPathD(x, y, width, height, 5), options);
 
+  const outerWidth = Math.max(width, bbox.width);
+  const outerHeight = height + bbox.height + labelPadding;
+
+  const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
+    ...options,
+    fill: 'none',
+    stroke: 'none',
+  });
+
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
+  const outerShape = shapeSvg.insert(() => outerNode);
 
   if (node.icon) {
     const iconElem = shapeSvg.append('g');
@@ -57,21 +69,26 @@ export const iconRounded = async (
     const iconBBox = iconElem.node().getBBox();
     const iconWidth = iconBBox.width;
     const iconHeight = iconBBox.height;
+    const iconX = iconBBox.x;
+    const iconY = iconBBox.y;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})`
+      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - halfPadding - iconY : -outerHeight / 2 + halfPadding - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - bbox.height / 2 - labelPadding / 2 : height / 2 - bbox.height / 2 + labelPadding / 2})`
   );
 
-  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
+  iconShape.attr(
+    'transform',
+    `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
+  );
 
-  updateNodeBounds(node, shapeSvg);
+  updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
@@ -80,51 +97,34 @@ export const iconRounded = async (
     }
     const dx = node.x ?? 0;
     const dy = node.y ?? 0;
-    const nodeWidth = node.width ?? 0;
     const nodeHeight = node.height ?? 0;
-
+    let points = [];
     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 },
+      points = [
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
       ];
-      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 },
+      points = [
+        { x: dx - width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + height },
       ];
-      const pos = intersect.polygon(node, points, point);
-      return pos;
     }
+
+    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 9d0375874..b49d76cf6 100644
--- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
+++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/iconSquare.ts
@@ -35,6 +35,8 @@ export const iconSquare = async (
   const x = -width / 2;
   const y = -height / 2;
 
+  const labelPadding = node.label ? 8 : 0;
+
   // @ts-ignore - rough is not typed
   const rc = rough.svg(shapeSvg);
   const options = userNodeOverrides(node, { stroke: stylesMap.get('fill') || mainBkg });
@@ -46,7 +48,17 @@ export const iconSquare = async (
 
   const iconNode = rc.rectangle(x, y, width, height, options);
 
+  const outerWidth = Math.max(width, bbox.width);
+  const outerHeight = height + bbox.height + labelPadding;
+
+  const outerNode = rc.rectangle(-outerWidth / 2, -outerHeight / 2, outerWidth, outerHeight, {
+    ...options,
+    fill: 'none',
+    stroke: 'none',
+  });
+
   const iconShape = shapeSvg.insert(() => iconNode, ':first-child');
+  const outerShape = shapeSvg.insert(() => outerNode);
 
   if (node.icon) {
     const iconElem = shapeSvg.append('g');
@@ -56,21 +68,26 @@ export const iconSquare = async (
     const iconBBox = iconElem.node().getBBox();
     const iconWidth = iconBBox.width;
     const iconHeight = iconBBox.height;
+    const iconX = iconBBox.x;
+    const iconY = iconBBox.y;
     iconElem.attr(
       'transform',
-      `translate(${-iconWidth / 2},${topLabel ? height / 2 - iconHeight - halfPadding + bbox.height / 2 : -height / 2 + halfPadding - bbox.height / 2})`
+      `translate(${-iconWidth / 2 - iconX},${topLabel ? outerHeight / 2 - iconHeight - halfPadding - iconY : -outerHeight / 2 + halfPadding - iconY})`
     );
     iconElem.selectAll('path').attr('fill', stylesMap.get('stroke') || nodeBorder);
   }
 
   label.attr(
     'transform',
-    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - 5 - bbox.height / 2 : height / 2 - bbox.height / 2})`
+    `translate(${-width / 2 + width / 2 - bbox.width / 2},${topLabel ? -height / 2 - bbox.height / 2 - labelPadding / 2 : height / 2 - bbox.height / 2 + labelPadding / 2})`
   );
 
-  iconShape.attr('transform', `translate(${0},${topLabel ? bbox.height / 2 : -bbox.height / 2})`);
+  iconShape.attr(
+    'transform',
+    `translate(${0},${topLabel ? bbox.height / 2 + labelPadding / 2 : -bbox.height / 2 - labelPadding / 2})`
+  );
 
-  updateNodeBounds(node, shapeSvg);
+  updateNodeBounds(node, outerShape);
 
   node.intersect = function (point) {
     log.info('iconSquare intersect', node, point);
@@ -79,51 +96,34 @@ export const iconSquare = async (
     }
     const dx = node.x ?? 0;
     const dy = node.y ?? 0;
-    const nodeWidth = node.width ?? 0;
     const nodeHeight = node.height ?? 0;
-
+    let points = [];
     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 },
+      points = [
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx + width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + bbox.height + labelPadding },
       ];
-      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 },
+      points = [
+        { x: dx - width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 },
+        { x: dx + width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx + bbox.width / 2 / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy + nodeHeight / 2 },
+        { x: dx - bbox.width / 2, y: dy - nodeHeight / 2 + height },
+        { x: dx - width / 2, y: dy - nodeHeight / 2 + height },
       ];
-      const pos = intersect.polygon(node, points, point);
-      return pos;
     }
+
+    const pos = intersect.polygon(node, points, point);
+    return pos;
   };
 
   return shapeSvg;