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..ec34b90c58d --- /dev/null +++ b/packages/g6/__tests__/bugs/element-node-icon-switch.spec.ts @@ -0,0 +1,61 @@ +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'); + + graph.updateNodeData([ + { + id: 'node-1', + style: { + iconType: 'text', + iconText: 'Text', + iconSrc: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*AzSISZeq81IAAAAAAAAAAAAADmJ7AQ/original', + }, + }, + ]); + + await graph.draw(); + + await expect(graph).toMatchSnapshot(__filename, 'type-text'); + + graph.updateNodeData([ + { + id: 'node-1', + style: { + iconType: 'image', + }, + }, + ]); + + await graph.draw(); + + await expect(graph).toMatchSnapshot(__filename, 'type-image'); + }); +}); 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/__tests__/snapshots/bugs/element-node-icon-switch/type-image.svg b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/type-image.svg new file mode 100644 index 00000000000..216da1484fe --- /dev/null +++ b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/type-image.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/type-text.svg b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/type-text.svg new file mode 100644 index 00000000000..7a11a1e322a --- /dev/null +++ b/packages/g6/__tests__/snapshots/bugs/element-node-icon-switch/type-text.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..828df3dd40d 100644 --- a/packages/g6/src/elements/shapes/icon.ts +++ b/packages/g6/src/elements/shapes/icon.ts @@ -9,7 +9,18 @@ import { Image as GImage } from './image'; * * Icon style */ -export interface IconStyleProps extends BaseShapeStyleProps, Partial, Omit {} +export interface IconStyleProps extends BaseShapeStyleProps, Partial, Omit { + /** + * 手动指定节点类型 + * - 'text' 文本 + * - 'image' 图片 + * + * Manually specify the node type + * - 'text' text + * - 'image' image + */ + type: 'text' | 'image'; +} /** * 图标 @@ -25,14 +36,16 @@ export class Icon extends BaseShape { super(options); } - private isGImage() { - return !!this.getAttribute('src'); + private isImage() { + const { type, src } = this.attributes; + if (type) return type === 'image'; + 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 +60,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); } }