()
| 1453 | } |
| 1454 | |
| 1455 | dispose(): void { |
| 1456 | if (this.isDisposed) { |
| 1457 | return; // Already disposed |
| 1458 | } |
| 1459 | |
| 1460 | this.isDisposed = true; |
| 1461 | this.isInitialized = false; |
| 1462 | |
| 1463 | // Clean up event listeners FIRST to stop event flow |
| 1464 | this.cleanupEventListeners(); |
| 1465 | |
| 1466 | // Clean up resize monitoring (ResizeObserver and DPR monitoring) |
| 1467 | this.cleanupResizeMonitoring(); |
| 1468 | |
| 1469 | // Dispose overlays BEFORE worker disposal to prevent memory leaks |
| 1470 | this.disposeOverlays(); |
| 1471 | |
| 1472 | // Send dispose message to worker |
| 1473 | this.sendMessage({ |
| 1474 | type: 'dispose', |
| 1475 | chartId: this.chartId, |
| 1476 | }); |
| 1477 | |
| 1478 | // Reject all pending requests |
| 1479 | for (const pending of this.pendingRequests.values()) { |
| 1480 | clearTimeout(pending.timeout); |
| 1481 | pending.reject(new ChartGPUWorkerError( |
| 1482 | 'Chart disposed before operation completed', |
| 1483 | 'DISPOSED', |
| 1484 | pending.operation, |
| 1485 | this.chartId |
| 1486 | )); |
| 1487 | } |
| 1488 | this.pendingRequests.clear(); |
| 1489 | |
| 1490 | // Clear all event listeners |
| 1491 | for (const listeners of this.listeners.values()) { |
| 1492 | listeners.clear(); |
| 1493 | } |
| 1494 | |
| 1495 | // Remove worker message handler |
| 1496 | this.worker.removeEventListener('message', this.boundMessageHandler); |
| 1497 | |
| 1498 | // Remove canvas from container |
| 1499 | const canvas = this.container.querySelector('canvas'); |
| 1500 | if (canvas) { |
| 1501 | canvas.remove(); |
| 1502 | } |
| 1503 | } |
| 1504 | |
| 1505 | on(eventName: 'crosshairMove', callback: ChartGPUCrosshairMoveCallback): void; |
| 1506 | on(eventName: ChartGPUEventName, callback: ChartGPUEventCallback): void; |
no test coverage detected