mirror of
https://gitee.com/antv/g6.git
synced 2024-12-03 12:18:40 +08:00
fix: fix issue that cause memory leak (#5587)
* fix: fix issue that may cause memories lack * test: adjust test case to destroy graph
This commit is contained in:
parent
72c5e74611
commit
bcd080432f
@ -9,6 +9,10 @@ describe('behavior combo expand collapse', () => {
|
|||||||
graph = await createDemoGraph(comboExpandCollapse, { animation: false });
|
graph = await createDemoGraph(comboExpandCollapse, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,10 @@ describe('behavior drag canvas', () => {
|
|||||||
graph = await createDemoGraph(behaviorDragCanvas, { animation: false });
|
graph = await createDemoGraph(behaviorDragCanvas, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', () => {
|
it('default status', () => {
|
||||||
expect(graph.getBehaviors()).toEqual([
|
expect(graph.getBehaviors()).toEqual([
|
||||||
'drag-canvas',
|
'drag-canvas',
|
||||||
@ -78,8 +82,4 @@ describe('behavior drag canvas', () => {
|
|||||||
|
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('destroy', () => {
|
|
||||||
graph.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('behavior drag combo', () => {
|
|||||||
graph = await createDemoGraph(comboExpandCollapse, { animation: false });
|
graph = await createDemoGraph(comboExpandCollapse, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
graph.setBehaviors([{ type: 'drag-element', dropEffect: 'link' }]);
|
graph.setBehaviors([{ type: 'drag-element', dropEffect: 'link' }]);
|
||||||
graph.expand('combo-1');
|
graph.expand('combo-1');
|
||||||
|
@ -10,6 +10,10 @@ describe('behavior drag element', () => {
|
|||||||
graph = await createDemoGraph(behaviorDragNode, { animation: false });
|
graph = await createDemoGraph(behaviorDragNode, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
|
|
||||||
|
@ -11,6 +11,10 @@ describe('behavior zoom canvas', () => {
|
|||||||
graph = await createDemoGraph(behaviorZoomCanvas, { animation: false });
|
graph = await createDemoGraph(behaviorZoomCanvas, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', () => {
|
it('default status', () => {
|
||||||
expect(graph.getZoom()).toBe(1);
|
expect(graph.getZoom()).toBe(1);
|
||||||
expect(graph.getBehaviors()).toEqual([{ type: 'zoom-canvas' }]);
|
expect(graph.getBehaviors()).toEqual([{ type: 'zoom-canvas' }]);
|
||||||
@ -191,8 +195,4 @@ describe('behavior zoom canvas', () => {
|
|||||||
container?.dispatchEvent(new Event(ContainerEvent.KEY_DOWN));
|
container?.dispatchEvent(new Event(ContainerEvent.KEY_DOWN));
|
||||||
expect(keydownListener).toHaveBeenCalledTimes(1);
|
expect(keydownListener).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('destroy', () => {
|
|
||||||
graph.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element change type', () => {
|
|||||||
graph = await createDemoGraph(elementChangeType, { animation: false });
|
graph = await createDemoGraph(elementChangeType, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('combo', () => {
|
|||||||
graph = await createDemoGraph(combo, { animation: false });
|
graph = await createDemoGraph(combo, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -26,6 +26,10 @@ describe('edge polyline', () => {
|
|||||||
graph = await createDemoGraph(edgePolyline, { animation: false });
|
graph = await createDemoGraph(edgePolyline, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('Control Points', async () => {
|
it('Control Points', async () => {
|
||||||
updateEdgeStyle(graph, 'edge-1', 'controlPoints', [[300, 190]]);
|
updateEdgeStyle(graph, 'edge-1', 'controlPoints', [[300, 190]]);
|
||||||
|
|
||||||
|
@ -25,6 +25,10 @@ describe('element port', () => {
|
|||||||
graph = await createDemoGraph(elementPort, { animation: false });
|
graph = await createDemoGraph(elementPort, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename, 'port_hidden');
|
await expect(graph).toMatchSnapshot(__filename, 'port_hidden');
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element position combo', () => {
|
|||||||
graph = await createDemoGraph(elementPositionCombo, { animation: false });
|
graph = await createDemoGraph(elementPositionCombo, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element position', () => {
|
|||||||
graph = await createDemoGraph(elementPosition, { animation: false });
|
graph = await createDemoGraph(elementPosition, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element state', () => {
|
|||||||
graph = await createDemoGraph(elementState, { animation: false });
|
graph = await createDemoGraph(elementState, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element visibility', () => {
|
|||||||
graph = await createDemoGraph(elementVisibility, { animation: false });
|
graph = await createDemoGraph(elementVisibility, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('element zIndex', () => {
|
|||||||
graph = await createDemoGraph(elementZIndex, { animation: false });
|
graph = await createDemoGraph(elementZIndex, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', async () => {
|
it('default status', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
});
|
});
|
||||||
|
@ -14,6 +14,10 @@ describe('plugin grid line', () => {
|
|||||||
.getElementsByClassName('g6-grid-line')! as HTMLCollectionOf<HTMLElement>;
|
.getElementsByClassName('g6-grid-line')! as HTMLCollectionOf<HTMLElement>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default status', () => {
|
it('default status', () => {
|
||||||
expect(graph.getPlugins()).toEqual([{ type: 'grid-line', follow: false }]);
|
expect(graph.getPlugins()).toEqual([{ type: 'grid-line', follow: false }]);
|
||||||
expect(gridLineElement.length).toBe(1);
|
expect(gridLineElement.length).toBe(1);
|
||||||
|
@ -8,10 +8,15 @@ import { omit } from '@antv/util';
|
|||||||
|
|
||||||
describe('ElementController', () => {
|
describe('ElementController', () => {
|
||||||
let graph: Graph;
|
let graph: Graph;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
graph = await createDemoGraph(graphElement);
|
graph = await createDemoGraph(graphElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('static', async () => {
|
it('static', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename);
|
await expect(graph).toMatchSnapshot(__filename);
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ describe('Graph', () => {
|
|||||||
it('destroy', () => {
|
it('destroy', () => {
|
||||||
graph.destroy();
|
graph.destroy();
|
||||||
// @ts-expect-error context is private.
|
// @ts-expect-error context is private.
|
||||||
expect(graph.context).toBeUndefined();
|
expect(graph.context).toEqual({});
|
||||||
expect(graph.destroyed).toBe(true);
|
expect(graph.destroyed).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,10 +6,15 @@ import { AABB } from '@antv/g';
|
|||||||
|
|
||||||
describe('ViewportController', () => {
|
describe('ViewportController', () => {
|
||||||
let graph: Graph;
|
let graph: Graph;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
graph = await createDemoGraph(controllerViewport);
|
graph = await createDemoGraph(controllerViewport);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('viewport center', () => {
|
it('viewport center', () => {
|
||||||
expect(graph.getViewportCenter()).toBeCloseTo([250, 250, 0]);
|
expect(graph.getViewportCenter()).toBeCloseTo([250, 250, 0]);
|
||||||
});
|
});
|
||||||
@ -104,18 +109,19 @@ describe('ViewportController', () => {
|
|||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
expect(graph.context.viewport.getBBoxInViewport(bbox).halfExtents).toBeCloseTo([100, 100, 0]);
|
expect(graph.context.viewport.getBBoxInViewport(bbox).halfExtents).toBeCloseTo([100, 100, 0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
graph.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Viewport Fit without Animation', () => {
|
describe('Viewport Fit without Animation', () => {
|
||||||
let graph: Graph;
|
let graph: Graph;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
graph = await createDemoGraph(viewportFit);
|
graph = await createDemoGraph(viewportFit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default', async () => {
|
it('default', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename, 'before-fit');
|
await expect(graph).toMatchSnapshot(__filename, 'before-fit');
|
||||||
});
|
});
|
||||||
@ -144,18 +150,19 @@ describe('Viewport Fit without Animation', () => {
|
|||||||
await graph.fitCenter();
|
await graph.fitCenter();
|
||||||
await expect(graph).toMatchSnapshot(__filename, 're-fitCenter');
|
await expect(graph).toMatchSnapshot(__filename, 're-fitCenter');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
graph.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Viewport Fit with Animation', () => {
|
describe('Viewport Fit with Animation', () => {
|
||||||
let graph: Graph;
|
let graph: Graph;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
graph = await createDemoGraph(viewportFit, { animation: true });
|
graph = await createDemoGraph(viewportFit, { animation: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default', async () => {
|
it('default', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename, 'before-fit-animation');
|
await expect(graph).toMatchSnapshot(__filename, 'before-fit-animation');
|
||||||
});
|
});
|
||||||
@ -184,10 +191,6 @@ describe('Viewport Fit with Animation', () => {
|
|||||||
await graph.fitCenter();
|
await graph.fitCenter();
|
||||||
await expect(graph).toMatchSnapshot(__filename, 're-fitCenter-animation');
|
await expect(graph).toMatchSnapshot(__filename, 're-fitCenter-animation');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
graph.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Viewport Fit with AutoFit and Padding without Animation', () => {
|
describe('Viewport Fit with AutoFit and Padding without Animation', () => {
|
||||||
@ -199,6 +202,10 @@ describe('Viewport Fit with AutoFit and Padding without Animation', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default', async () => {
|
it('default', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename, 'auto-fit-with-padding');
|
await expect(graph).toMatchSnapshot(__filename, 'auto-fit-with-padding');
|
||||||
});
|
});
|
||||||
@ -214,6 +221,10 @@ describe('Viewport Fit with AutoFit and Padding with Animation', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('default', async () => {
|
it('default', async () => {
|
||||||
await expect(graph).toMatchSnapshot(__filename, 'auto-fit-with-padding-animation');
|
await expect(graph).toMatchSnapshot(__filename, 'auto-fit-with-padding-animation');
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,10 @@ describe('spec theme', () => {
|
|||||||
graph = await createDemoGraph(theme, { animation: false });
|
graph = await createDemoGraph(theme, { animation: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
graph.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('theme', async () => {
|
it('theme', async () => {
|
||||||
const theme: ThemeOptions = 'light';
|
const theme: ThemeOptions = 'light';
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"fix": "eslint ./src ./__tests__ --fix && prettier ./src __tests__ --write ",
|
"fix": "eslint ./src ./__tests__ --fix && prettier ./src __tests__ --write ",
|
||||||
"jest": "node --expose-gc --max-old-space-size=4096 --unhandled-rejections=strict --experimental-vm-modules ../../node_modules/jest/bin/jest --coverage --logHeapUsage --detectOpenHandles",
|
"jest": "node --expose-gc --max-old-space-size=4096 --unhandled-rejections=strict --experimental-vm-modules ../../node_modules/jest/bin/jest --coverage --logHeapUsage --detectOpenHandles",
|
||||||
|
"jest:inspect": "node --inspect --expose-gc --max-old-space-size=4096 --unhandled-rejections=strict --experimental-vm-modules ../../node_modules/jest/bin/jest --coverage --logHeapUsage --detectOpenHandles --runInBand",
|
||||||
"lint": "eslint ./src __tests__ --quiet && prettier ./src __tests__ --check",
|
"lint": "eslint ./src __tests__ --quiet && prettier ./src __tests__ --check",
|
||||||
"prepublishOnly": "npm run ci",
|
"prepublishOnly": "npm run ci",
|
||||||
"size": "limit-size",
|
"size": "limit-size",
|
||||||
|
@ -148,4 +148,10 @@ export abstract class BaseShape<StyleProps extends BaseShapeStyleProps> extends
|
|||||||
const { visibility } = this.attributes;
|
const { visibility } = this.attributes;
|
||||||
setVisibility(this, visibility);
|
setVisibility(this, visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
this.shapeMap = {};
|
||||||
|
this.animateMap = {};
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public update(options: Partial<TooltipOptions>) {
|
public update(options: Partial<TooltipOptions>) {
|
||||||
this.unbundEvents();
|
this.unbindEvents();
|
||||||
super.update(options);
|
super.update(options);
|
||||||
if (this.tooltipElement) {
|
if (this.tooltipElement) {
|
||||||
this.container?.removeChild(this.tooltipElement.HTMLTooltipElement);
|
this.container?.removeChild(this.tooltipElement.HTMLTooltipElement);
|
||||||
@ -83,7 +83,7 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
|
|||||||
this.tooltipElement = this.initTooltip();
|
this.tooltipElement = this.initTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private unbundEvents() {
|
private unbindEvents() {
|
||||||
const { graph } = this.context;
|
const { graph } = this.context;
|
||||||
/** The previous event binding needs to be removed when updating the trigger. */
|
/** The previous event binding needs to be removed when updating the trigger. */
|
||||||
const events = this.getEvents();
|
const events = this.getEvents();
|
||||||
@ -259,7 +259,7 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public destroy(): void {
|
public destroy(): void {
|
||||||
this.unbundEvents();
|
this.unbindEvents();
|
||||||
if (this.tooltipElement) {
|
if (this.tooltipElement) {
|
||||||
this.container?.removeChild(this.tooltipElement.HTMLTooltipElement);
|
this.container?.removeChild(this.tooltipElement.HTMLTooltipElement);
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,9 @@ export abstract class ExtensionController<Extension extends BaseExtension<Loosel
|
|||||||
public destroy() {
|
public destroy() {
|
||||||
Object.values(this.extensionMap).forEach((extension) => extension.destroy());
|
Object.values(this.extensionMap).forEach((extension) => extension.destroy());
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
// @ts-expect-error force delete
|
this.extensions = [];
|
||||||
delete this.extensions;
|
this.extensionMap = {};
|
||||||
// @ts-expect-error force delete
|
|
||||||
delete this.extensionMap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,9 +103,9 @@ export class BaseExtension<T extends LooselyExtensionOption> {
|
|||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.options;
|
this.options = {};
|
||||||
|
|
||||||
this.destroyed = true;
|
this.destroyed = true;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ export class BehaviorController extends ExtensionController<BaseBehavior<CustomB
|
|||||||
const container = this.context.canvas.getContainer();
|
const container = this.context.canvas.getContainer();
|
||||||
if (container) {
|
if (container) {
|
||||||
[ContainerEvent.KEY_DOWN, ContainerEvent.KEY_UP].forEach((name) => {
|
[ContainerEvent.KEY_DOWN, ContainerEvent.KEY_UP].forEach((name) => {
|
||||||
container.addEventListener(name, this.forwardContainerEvents.bind(this));
|
container.addEventListener(name, this.forwardContainerEvents);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +105,18 @@ export class BehaviorController extends ExtensionController<BaseBehavior<CustomB
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private forwardContainerEvents(event: FocusEvent | KeyboardEvent) {
|
private forwardContainerEvents = (event: FocusEvent | KeyboardEvent) => {
|
||||||
this.context.graph.emit(event.type, event);
|
this.context.graph.emit(event.type, event);
|
||||||
|
};
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
const container = this.context.canvas.getContainer();
|
||||||
|
if (container) {
|
||||||
|
[ContainerEvent.KEY_DOWN, ContainerEvent.KEY_UP].forEach((name) => {
|
||||||
|
container.removeEventListener(name, this.forwardContainerEvents);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.context.canvas.document.removeAllEventListeners();
|
||||||
|
super.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,10 @@ export class Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
Object.values(this.canvas).forEach((canvas) => {
|
this.config = {};
|
||||||
|
// @ts-expect-error force delete
|
||||||
|
this.renderers = {};
|
||||||
|
Object.entries(this.canvas).forEach(([name, canvas]) => {
|
||||||
const camera = canvas.getCamera();
|
const camera = canvas.getCamera();
|
||||||
// @ts-expect-error landmark is private
|
// @ts-expect-error landmark is private
|
||||||
if (camera.landmarks?.length) {
|
if (camera.landmarks?.length) {
|
||||||
@ -261,6 +264,8 @@ export class Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas.destroy();
|
canvas.destroy();
|
||||||
|
// @ts-expect-error force delete
|
||||||
|
this[name] = undefined;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,7 @@ export class DataController {
|
|||||||
model.removeNodes(nodes.map((node) => node.id));
|
model.removeNodes(nodes.map((node) => node.id));
|
||||||
|
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,14 +718,19 @@ export class ElementController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
Object.values(this.elementMap).forEach((element) => element.destroy());
|
||||||
Object.values(this.container).forEach((container) => container.destroy());
|
Object.values(this.container).forEach((container) => container.destroy());
|
||||||
|
// @ts-expect-error force delete
|
||||||
|
this.container = {};
|
||||||
this.elementMap = {};
|
this.elementMap = {};
|
||||||
this.shapeTypeMap = {};
|
this.shapeTypeMap = {};
|
||||||
this.defaultStyle = {};
|
this.defaultStyle = {};
|
||||||
this.stateStyle = {};
|
this.stateStyle = {};
|
||||||
this.paletteStyle = {};
|
this.paletteStyle = {};
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
|
// @ts-expect-error force delete
|
||||||
|
this.latestElementVisibilityMap = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,16 +503,17 @@ export class Graph extends EventEmitter {
|
|||||||
|
|
||||||
public destroy(): void {
|
public destroy(): void {
|
||||||
const { layout, element, model, canvas, behavior, plugin } = this.context;
|
const { layout, element, model, canvas, behavior, plugin } = this.context;
|
||||||
|
plugin?.destroy();
|
||||||
|
behavior?.destroy();
|
||||||
layout?.destroy();
|
layout?.destroy();
|
||||||
element?.destroy();
|
element?.destroy();
|
||||||
model.destroy();
|
model.destroy();
|
||||||
canvas?.destroy();
|
canvas?.destroy();
|
||||||
behavior?.destroy();
|
|
||||||
plugin?.destroy();
|
|
||||||
this.options = {};
|
this.options = {};
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
|
|
||||||
|
this.off();
|
||||||
window.removeEventListener('resize', this.onResize);
|
window.removeEventListener('resize', this.onResize);
|
||||||
|
|
||||||
this.destroyed = true;
|
this.destroyed = true;
|
||||||
|
@ -381,7 +381,11 @@ export class LayoutController {
|
|||||||
public destroy() {
|
public destroy() {
|
||||||
this.stopLayout();
|
this.stopLayout();
|
||||||
// @ts-expect-error force delete
|
// @ts-expect-error force delete
|
||||||
delete this.context;
|
this.context = {};
|
||||||
|
this.supervisor?.kill();
|
||||||
|
this.supervisor = undefined;
|
||||||
|
this.instance = undefined;
|
||||||
|
this.animationResult = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user