From 3c93e4640a6c416b7259afbd7f075c67f2ad24d1 Mon Sep 17 00:00:00 2001 From: Knut Sveidqvist Date: Sat, 30 Nov 2024 13:42:50 +0100 Subject: [PATCH] #6097 Next batch of shapes --- .../rendering-elements/shapes/bowTieRect.ts | 26 +++++------- .../rendering-elements/shapes/card.ts | 42 ++++++++----------- .../rendering-elements/shapes/choice.ts | 23 +++++----- .../shapes/curlyBraceLeft.ts | 41 ++++++++---------- .../shapes/curlyBraceRight.ts | 41 ++++++++---------- .../rendering-elements/shapes/cylinder.ts | 31 ++++++++------ .../rendering-elements/shapes/dividedRect.ts | 4 +- .../rendering-elements/shapes/document.ts | 27 ++++++------ .../rendering-elements/shapes/doubleCircle.ts | 1 - .../rendering-elements/shapes/filledCircle.ts | 1 - .../shapes/flippedTriangle.ts | 22 ++++++---- .../rendering-elements/shapes/question.ts | 11 +---- .../rendering-elements/shapes/windowPane.ts | 27 ++++++++---- 13 files changed, 141 insertions(+), 156 deletions(-) diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts index f578824b6..e7fb64875 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/bowTieRect.ts @@ -71,7 +71,15 @@ function generateArcPoints( return points; } - +function getPoints(w: number, h: number, rx: number, ry: number) { + return [ + { x: w / 2, y: -h / 2 }, + { x: -w / 2, y: -h / 2 }, + ...generateArcPoints(-w / 2, -h / 2, -w / 2, h / 2, rx, ry, false), + { x: w / 2, y: h / 2 }, + ...generateArcPoints(w / 2, h / 2, w / 2, -h / 2, rx, ry, true), + ]; +} export async function bowTieRect(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; @@ -85,13 +93,7 @@ export async function bowTieRect(parent: D3Selecti // let shape: d3.Selection; const { cssStyles } = node; - const points = [ - { x: w / 2, y: -h / 2 }, - { x: -w / 2, y: -h / 2 }, - ...generateArcPoints(-w / 2, -h / 2, -w / 2, h / 2, rx, ry, false), - { x: w / 2, y: h / 2 }, - ...generateArcPoints(w / 2, h / 2, w / 2, -h / 2, rx, ry, true), - ]; + const points = getPoints(w, h, rx, ry); // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); @@ -126,13 +128,7 @@ export async function bowTieRect(parent: D3Selecti const ry = h / 2; const rx = ry / (2.5 + h / 50); - const points = [ - { x: w / 2, y: -h / 2 }, - { x: -w / 2, y: -h / 2 }, - ...generateArcPoints(-w / 2, -h / 2, -w / 2, h / 2, rx, ry, false), - { x: w / 2, y: h / 2 }, - ...generateArcPoints(w / 2, h / 2, w / 2, -h / 2, rx, ry, true), - ]; + const points = getPoints(w, h, rx, ry); return intersect.polygon(bounds, points, point); }; node.intersect = function (point) { diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts index a4a48a822..d75b5102d 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/card.ts @@ -8,6 +8,20 @@ import { createPathFromPoints } from './util.js'; import type { D3Selection } from '../../../types.js'; import type { Bounds, Point } from '../../../types.js'; +function getPoints(w: number, h: number, padding: number) { + const left = 0; + const right = w; + const top = -h; + const bottom = 0; + return [ + { x: left + padding, y: top }, + { x: right, y: top }, + { x: right, y: bottom }, + { x: left, y: bottom }, + { x: left, y: top + padding }, + { x: left + padding, y: top }, + ]; +} export async function card(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; @@ -16,18 +30,8 @@ export async function card(parent: D3Selection, const h = bbox.height + node.padding; const padding = 12; const w = bbox.width + node.padding + padding; - const left = 0; - const right = w; - const top = -h; - const bottom = 0; - const points = [ - { x: left + padding, y: top }, - { x: right, y: top }, - { x: right, y: bottom }, - { x: left, y: bottom }, - { x: left, y: top + padding }, - { x: left + padding, y: top }, - ]; + + const points = getPoints(w, h, padding); let polygon: D3Selection | Awaited>; const { cssStyles } = node; @@ -60,18 +64,8 @@ export async function card(parent: D3Selection, const h = bounds.height; const padding = 12; const w = bounds.width; - const left = 0; - const right = w; - const top = -h; - const bottom = 0; - const points = [ - { x: left + padding, y: top }, - { x: right, y: top }, - { x: right, y: bottom }, - { x: left, y: bottom }, - { x: left, y: top + padding }, - { x: left + padding, y: top }, - ]; + + const points = getPoints(w, h, padding); return intersect.polygon(bounds, points, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts index 9be5c3b73..e9e5760a1 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/choice.ts @@ -5,7 +5,14 @@ import { styles2String, userNodeOverrides } from './handDrawnShapeStyles.js'; import { createPathFromPoints, getNodeClasses } from './util.js'; import type { D3Selection } from '../../../types.js'; import type { Bounds, Point } from '../../../types.js'; - +function getPoints(s: number) { + return [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 }, + ]; +} export function choice(parent: D3Selection, node: Node) { const { nodeStyles } = styles2String(node); node.label = ''; @@ -17,12 +24,7 @@ export function choice(parent: D3Selection, nod const s = Math.max(28, node.width ?? 0); - const points = [ - { x: 0, y: s / 2 }, - { x: s / 2, y: 0 }, - { x: 0, y: -s / 2 }, - { x: -s / 2, y: 0 }, - ]; + const points = getPoints(s); // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); @@ -51,12 +53,7 @@ export function choice(parent: D3Selection, nod node.calcIntersect = function (bounds: Bounds, point: Point) { const s = Math.max(28, bounds.width ?? 0); - const points = [ - { x: 0, y: s / 2 }, - { x: s / 2, y: 0 }, - { x: 0, y: -s / 2 }, - { x: -s / 2, y: 0 }, - ]; + const points = getPoints(s); return intersect.circle(bounds, points, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts index ec6c1aab9..2afdb4df0 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceLeft.ts @@ -36,6 +36,21 @@ function generateCirclePoints( return points; } +function getRectPoints(w: number, h: number, radius: number) { + return [ + { x: w / 2, y: -h / 2 - radius }, + { x: -w / 2, y: -h / 2 - radius }, + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: -w / 2 - radius, y: -radius }, + ...generateCirclePoints(w / 2 + w * 0.1, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + w * 0.1, radius, radius, 20, -90, -180), + { x: -w / 2 - radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + { x: -w / 2, y: h / 2 + radius }, + { x: w / 2, y: h / 2 + radius }, + ]; +} + export async function curlyBraceLeft( parent: D3Selection, node: Node @@ -58,18 +73,7 @@ export async function curlyBraceLeft( ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), ]; - const rectPoints = [ - { x: w / 2, y: -h / 2 - radius }, - { x: -w / 2, y: -h / 2 - radius }, - ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), - { x: -w / 2 - radius, y: -radius }, - ...generateCirclePoints(w / 2 + w * 0.1, -radius, radius, 20, -180, -270), - ...generateCirclePoints(w / 2 + w * 0.1, radius, radius, 20, -90, -180), - { x: -w / 2 - radius, y: h / 2 }, - ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), - { x: -w / 2, y: h / 2 + radius }, - { x: w / 2, y: h / 2 + radius }, - ]; + const rectPoints = getRectPoints(w, h, radius); // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); @@ -111,18 +115,7 @@ export async function curlyBraceLeft( const h = bounds.height; const radius = Math.max(5, h * 0.1); - const rectPoints = [ - { x: w / 2, y: -h / 2 - radius }, - { x: -w / 2, y: -h / 2 - radius }, - ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), - { x: -w / 2 - radius, y: -radius }, - ...generateCirclePoints(w / 2 + w * 0.1, -radius, radius, 20, -180, -270), - ...generateCirclePoints(w / 2 + w * 0.1, radius, radius, 20, -90, -180), - { x: -w / 2 - radius, y: h / 2 }, - ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), - { x: -w / 2, y: h / 2 + radius }, - { x: w / 2, y: h / 2 + radius }, - ]; + const rectPoints = getRectPoints(w, h, radius); return intersect.polygon(bounds, rectPoints, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts index 8d70f408b..84a1c9e81 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/curlyBraceRight.ts @@ -36,6 +36,21 @@ function generateCirclePoints( return points; } +function getRectPoints(w: number, h: number, radius: number) { + return [ + { x: -w / 2, y: -h / 2 - radius }, + { x: w / 2, y: -h / 2 - radius }, + ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), + { x: w / 2 + radius, y: -radius }, + ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), + ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), + { x: w / 2 + radius, y: h / 2 }, + ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), + { x: w / 2, y: h / 2 + radius }, + { x: -w / 2, y: h / 2 + radius }, + ]; +} + export async function curlyBraceRight( parent: D3Selection, node: Node @@ -58,18 +73,7 @@ export async function curlyBraceRight( ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), ]; - const rectPoints = [ - { x: -w / 2, y: -h / 2 - radius }, - { x: w / 2, y: -h / 2 - radius }, - ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), - { x: w / 2 + radius, y: -radius }, - ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), - ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), - { x: w / 2 + radius, y: h / 2 }, - ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), - { x: w / 2, y: h / 2 + radius }, - { x: -w / 2, y: h / 2 + radius }, - ]; + const rectPoints = getRectPoints(w, h, radius); // @ts-expect-error -- Passing a D3.Selection seems to work for some reason const rc = rough.svg(shapeSvg); @@ -111,18 +115,7 @@ export async function curlyBraceRight( const h = bounds.height; const radius = Math.max(5, h * 0.1); - const rectPoints = [ - { x: -w / 2, y: -h / 2 - radius }, - { x: w / 2, y: -h / 2 - radius }, - ...generateCirclePoints(w / 2, -h / 2, radius, 20, -90, 0), - { x: w / 2 + radius, y: -radius }, - ...generateCirclePoints(w / 2 + radius * 2, -radius, radius, 20, -180, -270), - ...generateCirclePoints(w / 2 + radius * 2, radius, radius, 20, -90, -180), - { x: w / 2 + radius, y: h / 2 }, - ...generateCirclePoints(w / 2, h / 2, radius, 20, 0, 90), - { x: w / 2, y: h / 2 + radius }, - { x: -w / 2, y: h / 2 + radius }, - ]; + const rectPoints = getRectPoints(w, h, radius); return intersect.polygon(bounds, rectPoints, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts index af0eccc8c..923b67123 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/cylinder.ts @@ -98,27 +98,23 @@ export async function cylinder(parent: D3Selection ); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); - }; - - node.intersect = function (point) { - const pos = intersect.rect(node, point); - const x = pos.x - (node.x ?? 0); - + const w = bounds.width; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bounds.height; + const pos = intersect.rect(bounds, point); + const x = pos.x - (bounds.x ?? 0); if ( rx != 0 && - (Math.abs(x) < (node.width ?? 0) / 2 || - (Math.abs(x) == (node.width ?? 0) / 2 && - Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry)) + (Math.abs(x) < (w ?? 0) / 2 || + (Math.abs(x) == (w ?? 0) / 2 && Math.abs(pos.y - (bounds.y ?? 0)) > (h ?? 0) / 2 - ry)) ) { let y = ry * ry * (1 - (x * x) / (rx * rx)); if (y > 0) { y = Math.sqrt(y); } y = ry - y; - if (point.y - (node.y ?? 0) > 0) { + if (point.y - (bounds.y ?? 0) > 0) { y = -y; } @@ -128,5 +124,14 @@ export async function cylinder(parent: D3Selection return pos; }; + node.intersect = function (point: Point) { + return this.calcIntersect + ? this.calcIntersect( + { x: node.x ?? 0, y: node.y ?? 0, width: node.width ?? 0, height: node.height ?? 0 }, + point + ) + : { x: 0, y: 0 }; + }; + return shapeSvg; } diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts index 7d0d471c0..6145d2d8c 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/dividedRect.ts @@ -64,9 +64,7 @@ export async function dividedRectangle( updateNodeBounds(node, polygon); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); + return intersect.rect(bounds, point); }; node.intersect = function (point) { diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts index 889b385cb..5ee060fe2 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/document.ts @@ -93,34 +93,35 @@ export async function cylinder(parent: D3Selection updateNodeBounds(node, cylinder); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); - }; - - node.intersect = function (point) { - const pos = intersect.rect(node, point); - const x = pos.x - (node.x ?? 0); + const pos = intersect.rect(bounds, point); + const x = pos.x - (bounds.x ?? 0); if ( rx != 0 && - (Math.abs(x) < (node.width ?? 0) / 2 || - (Math.abs(x) == (node.width ?? 0) / 2 && - Math.abs(pos.y - (node.y ?? 0)) > (node.height ?? 0) / 2 - ry)) + (Math.abs(x) < (bounds.width ?? 0) / 2 || + (Math.abs(x) == (bounds.width ?? 0) / 2 && + Math.abs(pos.y - (bounds.y ?? 0)) > (bounds.height ?? 0) / 2 - ry)) ) { let y = ry * ry * (1 - (x * x) / (rx * rx)); if (y != 0) { y = Math.sqrt(y); } y = ry - y; - if (point.y - (node.y ?? 0) > 0) { + if (point.y - (bounds.y ?? 0) > 0) { y = -y; } pos.y += y; } + }; - return pos; + node.intersect = function (point) { + return this.calcIntersect + ? this.calcIntersect( + { x: node.x ?? 0, y: node.y ?? 0, width: node.width ?? 0, height: node.height ?? 0 }, + point + ) + : { x: 0, y: 0 }; }; return shapeSvg; 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 f9e6153f0..80e75d92b 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/doubleCircle.ts @@ -64,7 +64,6 @@ export async function doublecircle( updateNodeBounds(node, circleGroup); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape const radius = bounds.width / 2; return intersect.circle(bounds, radius, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts index 3e73ce9dc..60d895d91 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/filledCircle.ts @@ -48,7 +48,6 @@ export function filledCircle( updateNodeBounds(node, filledCircle); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape const radius = bounds.width / 2; return intersect.circle(bounds, radius, point); }; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts index 9337cb802..651cc5fc8 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/flippedTriangle.ts @@ -8,6 +8,14 @@ import { createPathFromPoints } from './util.js'; import type { D3Selection } from '../../../types.js'; import type { Bounds, Point } from '../../../types.js'; +function getPoints(tw: number, h: number) { + return [ + { x: 0, y: -h }, + { x: tw, y: -h }, + { x: tw / 2, y: 0 }, + ]; +} + export async function flippedTriangle( parent: D3Selection, node: Node @@ -20,11 +28,7 @@ export async function flippedTriangle( const h = w + bbox.height; const tw = w + bbox.height; - const points = [ - { x: 0, y: -h }, - { x: tw, y: -h }, - { x: tw / 2, y: 0 }, - ]; + const points = getPoints(tw, h); const { cssStyles } = node; @@ -62,8 +66,12 @@ export async function flippedTriangle( node.calcIntersect = function (bounds: Bounds, point: Point) { // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); + const w = bounds.width; + const h = bounds.height; + + const tw = w + bounds.height; + const points = getPoints(tw, h); + return intersect.polygon(node, points, point); }; node.intersect = function (point) { 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 b72b40a67..ab8dba522 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/question.ts @@ -92,15 +92,8 @@ export async function question(parent: D3Selection return { x: res.x - 0.5, y: res.y - 0.5 }; // Adjusted result }; - node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); - }; - - node.intersect = function (point) { - // @ts-ignore TODO fix this (KNSV) - return this.calcIntersect(node as Bounds, point); + node.intersect = function (point: Point) { + return this.calcIntersect ? this.calcIntersect(node as Bounds, point) : { x: 0, y: 0 }; }; return shapeSvg; diff --git a/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts b/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts index 60ad5c0af..bb25a05c7 100644 --- a/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts +++ b/packages/mermaid/src/rendering-util/rendering-elements/shapes/windowPane.ts @@ -6,6 +6,15 @@ import intersect from '../intersect/index.js'; import type { D3Selection } from '../../../types.js'; import type { Bounds, Point } from '../../../types.js'; +function getOutPathPoints(x: number, y: number, w: number, h: number, rectOffset: number) { + return [ + { x: x - rectOffset, y: y - rectOffset }, + { x: x - rectOffset, y: y + h }, + { x: x + w, y: y + h }, + { x: x + w, y: y - rectOffset }, + ]; +} + export async function windowPane(parent: D3Selection, node: Node) { const { labelStyles, nodeStyles } = styles2String(node); node.labelStyle = labelStyles; @@ -21,12 +30,7 @@ export async function windowPane(parent: D3Selecti const rc = rough.svg(shapeSvg); const options = userNodeOverrides(node, {}); - const outerPathPoints = [ - { x: x - rectOffset, y: y - rectOffset }, - { x: x - rectOffset, y: y + h }, - { x: x + w, y: y + h }, - { x: x + w, y: y - rectOffset }, - ]; + const outerPathPoints = getOutPathPoints(x, y, w, h, rectOffset); const path = `M${x - rectOffset},${y - rectOffset} L${x + w},${y - rectOffset} L${x + w},${y + h} L${x - rectOffset},${y + h} L${x - rectOffset},${y - rectOffset} M${x - rectOffset},${y} L${x + w},${y} @@ -60,9 +64,14 @@ export async function windowPane(parent: D3Selecti updateNodeBounds(node, windowPane); node.calcIntersect = function (bounds: Bounds, point: Point) { - // TODO: Implement intersect for this shape - const radius = bounds.width / 2; - return intersect.circle(bounds, radius, point); + const w = bounds.width; + const h = bounds.height; + const rectOffset = 5; + const x = -w / 2; + const y = -h / 2; + + const outerPathPoints = getOutPathPoints(x, y, w, h, rectOffset); + return intersect.polygon(node, outerPathPoints, point); }; node.intersect = function (point) {