From c218dccd6ae384ab01f145a7a159582f4b112533 Mon Sep 17 00:00:00 2001 From: antv Date: Tue, 6 Aug 2024 21:21:07 +0800 Subject: [PATCH] fix: destroy shape after change icon type --- .../bugs/element-node-icon-switch.spec.ts | 33 +++++++++++++++++++ .../element-node-icon-switch/image-icon.svg | 19 +++++++++++ .../element-node-icon-switch/text-icon.svg | 21 ++++++++++++ packages/g6/src/elements/shapes/base-shape.ts | 4 ++- packages/g6/src/elements/shapes/icon.ts | 9 ++--- 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/g6/__tests__/bugs/element-node-icon-switch.spec.ts create mode 100644 packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/image-icon.svg create mode 100644 packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/text-icon.svg diff --git a/packages/g6/__tests__/bugs/element-node-icon-switch.spec.ts b/packages/g6/__tests__/bugs/element-node-icon-switch.spec.ts new file mode 100644 index 00000000000..c8a9def94aa --- /dev/null +++ b/packages/g6/__tests__/bugs/element-node-icon-switch.spec.ts @@ -0,0 +1,33 @@ +import { createGraph } from '@@/utils'; + +describe('bug: element-node-icon-switch', () => { + it('change node icon', async () => { + const graph = createGraph({ + animation: false, + data: { + nodes: [{ id: 'node-1', style: { x: 50, y: 50, iconText: 'Text' } }], + }, + node: { + style: {}, + }, + }); + + await graph.draw(); + + await expect(graph).toMatchSnapshot(__filename, 'text-icon'); + + graph.updateNodeData([ + { + id: 'node-1', + style: { + iconText: '', + iconSrc: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*AzSISZeq81IAAAAAAAAAAAAADmJ7AQ/original', + }, + }, + ]); + + await graph.draw(); + + await expect(graph).toMatchSnapshot(__filename, 'image-icon'); + }); +}); diff --git a/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/image-icon.svg b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/image-icon.svg new file mode 100644 index 00000000000..216da1484fe --- /dev/null +++ b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/image-icon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/text-icon.svg b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/text-icon.svg new file mode 100644 index 00000000000..c9f61b67034 --- /dev/null +++ b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/text-icon.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + Text + + + + + + + + \ No newline at end of file diff --git a/packages/g6/src/elements/shapes/base-shape.ts b/packages/g6/src/elements/shapes/base-shape.ts index 0ce181b2db9..39012692300 100644 --- a/packages/g6/src/elements/shapes/base-shape.ts +++ b/packages/g6/src/elements/shapes/base-shape.ts @@ -66,7 +66,9 @@ export abstract class BaseShape extends } // create - if (!target || target.destroyed) { + if (!target || target.destroyed || !(target instanceof Ctor)) { + target?.destroy(); + const instance = new Ctor({ className, style }); container.appendChild(instance); this.shapeMap[className] = instance; diff --git a/packages/g6/src/elements/shapes/icon.ts b/packages/g6/src/elements/shapes/icon.ts index cb70b682d4f..a9a06e2a2d6 100644 --- a/packages/g6/src/elements/shapes/icon.ts +++ b/packages/g6/src/elements/shapes/icon.ts @@ -25,14 +25,15 @@ export class Icon extends BaseShape { super(options); } - private isGImage() { - return !!this.getAttribute('src'); + private isImage() { + const { src } = this.attributes; + return !!src; } protected getIconStyle(attributes: IconStyleProps = this.attributes): IconStyleProps { const { width = 0, height = 0 } = attributes; const style = this.getGraphicStyle(attributes); - if (this.isGImage()) { + if (this.isImage()) { return { x: -width / 2, y: -height / 2, @@ -47,6 +48,6 @@ export class Icon extends BaseShape { } public render(attributes = this.attributes, container: Group = this): void { - this.upsert('icon', (this.isGImage() ? GImage : GText) as any, this.getIconStyle(attributes), container); + this.upsert('icon', (this.isImage() ? GImage : GText) as any, this.getIconStyle(attributes), container); } }