From 6c9174a76658dd3f021ce57394a9b1c92eec8b8e Mon Sep 17 00:00:00 2001 From: Nathan Marrs Date: Wed, 25 Jan 2023 17:32:04 -0700 Subject: [PATCH] Canvas: Fix connection anchors for svg elements (#61895) --- public/app/features/canvas/runtime/scene.tsx | 4 +-- .../app/plugins/panel/canvas/Connections.tsx | 29 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/public/app/features/canvas/runtime/scene.tsx b/public/app/features/canvas/runtime/scene.tsx index 4c48dc32f83..e171741273a 100644 --- a/public/app/features/canvas/runtime/scene.tsx +++ b/public/app/features/canvas/runtime/scene.tsx @@ -268,7 +268,7 @@ export class Scene { } }; - findElementByTarget = (target: HTMLElement | SVGElement): ElementState | undefined => { + findElementByTarget = (target: Element): ElementState | undefined => { // We will probably want to add memoization to this as we are calling on drag / resize const stack = [...this.root.elements]; @@ -288,7 +288,7 @@ export class Scene { return undefined; }; - setNonTargetPointerEvents = (target: HTMLElement | SVGElement, disablePointerEvents: boolean) => { + setNonTargetPointerEvents = (target: Element, disablePointerEvents: boolean) => { const stack = [...this.root.elements]; while (stack.length > 0) { const currentElement = stack.shift(); diff --git a/public/app/plugins/panel/canvas/Connections.tsx b/public/app/plugins/panel/canvas/Connections.tsx index d1ae8dd954b..3edad7621ec 100644 --- a/public/app/plugins/panel/canvas/Connections.tsx +++ b/public/app/plugins/panel/canvas/Connections.tsx @@ -32,28 +32,47 @@ export class Connections { this.connectionLine = connectionLine; }; + // Recursively find the first parent that is a canvas element + findElementTarget = (element: Element): ElementState | undefined => { + let elementTarget = undefined; + + // Cap recursion at the scene level + if (element === this.scene.div) { + return undefined; + } + + elementTarget = this.scene.findElementByTarget(element); + + if (!elementTarget && element.parentElement) { + elementTarget = this.findElementTarget(element.parentElement); + } + + return elementTarget; + }; + handleMouseEnter = (event: React.MouseEvent) => { - if (!(event.target instanceof HTMLElement) || !this.scene.isEditingEnabled) { + if (!(event.target instanceof Element) || !this.scene.isEditingEnabled) { return; } - const element = event.target.parentElement?.parentElement; + let element: ElementState | undefined = this.findElementTarget(event.target); + if (!element) { console.log('no element'); return; } if (this.isDrawingConnection) { - this.connectionTarget = this.scene.findElementByTarget(element); + this.connectionTarget = element; } else { - this.connectionSource = this.scene.findElementByTarget(element); + this.connectionSource = element; if (!this.connectionSource) { console.log('no connection source'); return; } } - const elementBoundingRect = element!.getBoundingClientRect(); + const elementBoundingRect = element.div!.getBoundingClientRect(); const parentBoundingRect = this.scene.div?.getBoundingClientRect(); const relativeTop = elementBoundingRect.top - (parentBoundingRect?.top ?? 0);