@myrmidon/ngx-viz
Version:
Angular viz.js wrapper to render DOT graphs.
1 lines • 23.4 kB
Source Map (JSON)
{"version":3,"file":"myrmidon-ngx-viz.mjs","sources":["../../../../projects/myrmidon/ngx-viz/src/lib/viz.component.ts","../../../../projects/myrmidon/ngx-viz/src/lib/viz.component.html","../../../../projects/myrmidon/ngx-viz/src/public-api.ts","../../../../projects/myrmidon/ngx-viz/src/myrmidon-ngx-viz.ts"],"sourcesContent":["import {\r\n Component,\r\n OnInit,\r\n ElementRef,\r\n ViewChild,\r\n effect,\r\n signal,\r\n input,\r\n inject,\r\n DestroyRef,\r\n} from '@angular/core';\r\n\r\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\r\nimport { BehaviorSubject, from, switchMap } from 'rxjs';\r\n\r\ninterface Transform {\r\n x: number;\r\n y: number;\r\n scale: number;\r\n}\r\n\r\ninterface ViewBox {\r\n width: number;\r\n height: number;\r\n x: number;\r\n y: number;\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n define: any;\r\n requirejs: any;\r\n Viz: any;\r\n }\r\n}\r\n\r\nconst VIZ_URL = 'https://unpkg.com/viz.js@2.1.2/viz.js';\r\nconst RENDER_URL = 'https://unpkg.com/viz.js@2.1.2/full.render.js';\r\n\r\n/**\r\n * Wrapper for Viz.js library to render DOT graphs in Angular.\r\n */\r\n@Component({\r\n selector: 'ngx-viz',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './viz.component.html',\r\n styleUrl: './viz.component.css',\r\n})\r\nexport class VizComponent implements OnInit {\r\n private readonly ZOOM_SPEED = 0.1;\r\n private readonly MIN_SCALE = 0.1;\r\n private readonly MAX_SCALE = 5;\r\n\r\n private readonly destroyRef = inject(DestroyRef);\r\n private readonly _transform = signal<Transform>({ x: 0, y: 0, scale: 1 });\r\n\r\n private _isDragging = false;\r\n private _lastPosition = { x: 0, y: 0 };\r\n private _originalViewBox: ViewBox | null = null;\r\n private _vizInstance: any = null;\r\n private _vizPromise: Promise<void> | null = null;\r\n private _scriptsLoaded = new BehaviorSubject<boolean>(false);\r\n\r\n @ViewChild('graphContainer') graphContainer!: ElementRef;\r\n @ViewChild('container') container!: ElementRef;\r\n\r\n /**\r\n * DOT code to render as a graph.\r\n */\r\n public readonly code = input<string>('');\r\n\r\n public readonly error = signal<string | null>(null);\r\n public readonly loading = signal<boolean>(false);\r\n\r\n constructor() {\r\n effect(() => {\r\n if (this.code()) {\r\n this.checkAndRender();\r\n }\r\n });\r\n }\r\n\r\n public ngOnInit() {\r\n this.initViz();\r\n }\r\n\r\n // #region Viewport and Zoom\r\n public fitToContainer() {\r\n if (!this.graphContainer || !this._originalViewBox) return;\r\n\r\n const container = this.container.nativeElement;\r\n const containerRect = container.getBoundingClientRect();\r\n\r\n // get the bounding box of the graph elements\r\n const svg = this.graphContainer.nativeElement.querySelector('svg');\r\n const graphBoundingBox = svg.getBBox();\r\n\r\n // account for potential invisible elements by expanding the bounding box\r\n const expandedBoundingBox = {\r\n x: graphBoundingBox.x - 20,\r\n y: graphBoundingBox.y - 30,\r\n width: graphBoundingBox.width + 40,\r\n height: graphBoundingBox.height + 60,\r\n };\r\n\r\n // calculate padding based on expanded bounding box\r\n const paddingX = Math.max(expandedBoundingBox.width / 10, 10);\r\n const paddingY = Math.max(expandedBoundingBox.height / 10, 10);\r\n\r\n // calculate scale to fit the graph within the container, considering padding\r\n const scaleX =\r\n (containerRect.width - 2 * paddingX) /\r\n (expandedBoundingBox.width + 2 * paddingX);\r\n const scaleY =\r\n (containerRect.height - 2 * paddingY) /\r\n (expandedBoundingBox.height + 2 * paddingY);\r\n const scale = Math.min(scaleX, scaleY);\r\n\r\n // calculate center position based on the expanded bounding box\r\n const x =\r\n (containerRect.width -\r\n (expandedBoundingBox.width + expandedBoundingBox.x) * scale) /\r\n 2;\r\n const y =\r\n (containerRect.height -\r\n (expandedBoundingBox.height + expandedBoundingBox.y) * scale) /\r\n 2;\r\n\r\n // apply transform with animation\r\n this._transform.set({ x, y, scale });\r\n this.applyTransform(true);\r\n }\r\n\r\n public zoomIn() {\r\n this.updateZoom(this._transform().scale + this.ZOOM_SPEED);\r\n }\r\n\r\n public zoomOut() {\r\n this.updateZoom(this._transform().scale - this.ZOOM_SPEED);\r\n }\r\n\r\n public resetView() {\r\n this._transform.set({ x: 0, y: 0, scale: 1 });\r\n this.applyTransform();\r\n }\r\n\r\n private updateZoom(newScale: number) {\r\n const scale = Math.max(this.MIN_SCALE, Math.min(this.MAX_SCALE, newScale));\r\n this._transform.update((t) => ({ ...t, scale }));\r\n this.applyTransform();\r\n }\r\n //#endregion\r\n\r\n //#region Mouse Events\r\n public onWheel(event: WheelEvent) {\r\n event.preventDefault();\r\n const delta = event.deltaY > 0 ? -this.ZOOM_SPEED : this.ZOOM_SPEED;\r\n this.updateZoom(this._transform().scale + delta);\r\n }\r\n\r\n public onMouseDown(event: MouseEvent) {\r\n this._isDragging = true;\r\n this._lastPosition = { x: event.clientX, y: event.clientY };\r\n }\r\n\r\n public onMouseMove(event: MouseEvent) {\r\n if (!this._isDragging) return;\r\n\r\n const dx = event.clientX - this._lastPosition.x;\r\n const dy = event.clientY - this._lastPosition.y;\r\n\r\n this._transform.update((t) => ({\r\n ...t,\r\n x: t.x + dx,\r\n y: t.y + dy,\r\n }));\r\n\r\n this._lastPosition = { x: event.clientX, y: event.clientY };\r\n this.applyTransform();\r\n }\r\n\r\n public onMouseUp() {\r\n this._isDragging = false;\r\n }\r\n //#endregion\r\n\r\n private applyTransform(animate: boolean = false) {\r\n if (!this.graphContainer) return;\r\n\r\n const svg = this.graphContainer.nativeElement.querySelector('svg');\r\n if (!svg) return;\r\n\r\n const { x, y, scale } = this._transform();\r\n const transform = `translate(${x}px, ${y}px) scale(${scale})`;\r\n\r\n if (animate) {\r\n svg.style.transition = 'transform 0.3s ease-out';\r\n // remove transition after animation\r\n setTimeout(() => {\r\n svg.style.transition = 'none';\r\n }, 300);\r\n } else {\r\n svg.style.transition = 'none';\r\n }\r\n\r\n svg.style.transform = transform;\r\n svg.style.transformOrigin = 'center';\r\n }\r\n\r\n private storeOriginalViewBox(svg: SVGElement) {\r\n // get original viewBox or computed size\r\n const viewBox = svg.getAttribute('viewBox');\r\n if (viewBox) {\r\n const [x, y, width, height] = viewBox.split(' ').map(Number);\r\n this._originalViewBox = { x, y, width, height };\r\n } else {\r\n const rect = svg.getBoundingClientRect();\r\n this._originalViewBox = {\r\n x: 0,\r\n y: 0,\r\n width: rect.width,\r\n height: rect.height,\r\n };\r\n }\r\n }\r\n\r\n private loadScript(url: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n // check if script is already loaded\r\n const existingScript = document.querySelector(`script[src=\"${url}\"]`);\r\n if (existingScript) {\r\n resolve();\r\n return;\r\n }\r\n\r\n const script = document.createElement('script');\r\n script.type = 'text/javascript';\r\n script.src = url;\r\n script.async = true;\r\n script.onerror = () => reject(new Error(`Failed to load script: ${url}`));\r\n script.onload = () => resolve();\r\n document.head.appendChild(script);\r\n });\r\n }\r\n\r\n private async initViz(): Promise<void> {\r\n if (this._vizPromise) {\r\n return this._vizPromise;\r\n }\r\n\r\n this._vizPromise = new Promise<void>((resolve, reject) => {\r\n // First, check if Viz is already available\r\n if (window.Viz) {\r\n resolve();\r\n return;\r\n }\r\n\r\n // Create a temporary AMD environment if none exists\r\n const hadAMD = 'define' in window && 'requirejs' in window;\r\n let originalDefine: any;\r\n let originalRequire: any;\r\n\r\n if (!hadAMD) {\r\n // Save original values if they exist\r\n originalDefine = window.define;\r\n originalRequire = window.requirejs;\r\n\r\n // Create minimal AMD environment\r\n window.define = function (factory: () => any) {\r\n try {\r\n window.Viz = factory();\r\n } catch (e) {\r\n console.error('Error in Viz.js factory:', e);\r\n }\r\n };\r\n window.define.amd = true;\r\n }\r\n\r\n // Load Viz.js first\r\n this.loadScript(VIZ_URL)\r\n .then(() => {\r\n // Restore original AMD environment before loading render.js\r\n if (!hadAMD) {\r\n if (originalDefine) {\r\n window.define = originalDefine;\r\n } else {\r\n delete window.define;\r\n }\r\n if (originalRequire) {\r\n window.requirejs = originalRequire;\r\n } else {\r\n delete window.requirejs;\r\n }\r\n }\r\n\r\n // Now load the renderer\r\n return this.loadScript(RENDER_URL);\r\n })\r\n .then(() => {\r\n if (window.Viz) {\r\n resolve();\r\n } else {\r\n reject(new Error('Viz.js failed to initialize'));\r\n }\r\n })\r\n .catch(reject);\r\n });\r\n\r\n try {\r\n await this._vizPromise;\r\n this._scriptsLoaded.next(true);\r\n } catch (error) {\r\n console.error('Error initializing Viz.js:', error);\r\n this.error.set('Failed to initialize Viz.js');\r\n this._scriptsLoaded.next(false);\r\n }\r\n\r\n return this._vizPromise;\r\n }\r\n\r\n private async checkAndRender() {\r\n this.loading.set(true);\r\n this.error.set(null);\r\n\r\n try {\r\n await this.initViz();\r\n await this.renderGraph();\r\n } catch (e) {\r\n this.error.set(\r\n e instanceof Error ? e.message : 'Error initializing or rendering graph'\r\n );\r\n console.error('Viz.js error:', e);\r\n } finally {\r\n this.loading.set(false);\r\n }\r\n }\r\n\r\n private async renderGraph(): Promise<void> {\r\n if (!this.graphContainer || !window.Viz) return;\r\n\r\n try {\r\n // create a new Viz instance if we don't have one\r\n if (!this._vizInstance) {\r\n this._vizInstance = new window.Viz();\r\n }\r\n\r\n const result = await this._vizInstance.renderSVGElement(this.code());\r\n\r\n // clear previous content\r\n this.graphContainer.nativeElement.innerHTML = '';\r\n\r\n // add new SVG\r\n this.graphContainer.nativeElement.appendChild(result);\r\n\r\n // store original viewBox and prepare SVG\r\n const svg = this.graphContainer.nativeElement.querySelector('svg');\r\n if (svg) {\r\n this.storeOriginalViewBox(svg);\r\n svg.style.transition = 'transform 0.3s ease-out';\r\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\r\n }\r\n\r\n // fit to container after rendering\r\n this.fitToContainer();\r\n } catch (e) {\r\n if (\r\n e instanceof Error &&\r\n e.message.includes('Worker is already disposed')\r\n ) {\r\n // if worker is disposed, create a new instance and retry\r\n this._vizInstance = new window.Viz();\r\n return this.renderGraph();\r\n }\r\n throw new Error(e instanceof Error ? e.message : 'Error rendering graph');\r\n }\r\n }\r\n\r\n /**\r\n * Exports the rendered graph as an SVG file.\r\n */\r\n public exportSVG() {\r\n const svgElement = this.graphContainer.nativeElement.querySelector('svg');\r\n if (svgElement) {\r\n const serializer = new XMLSerializer();\r\n const svgString = serializer.serializeToString(svgElement);\r\n const blob = new Blob([svgString], { type: 'image/svg+xml' });\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = 'graph.svg';\r\n a.click();\r\n URL.revokeObjectURL(url);\r\n }\r\n }\r\n}\r\n","<div\n class=\"viz-container\"\n #container\n (wheel)=\"onWheel($event)\"\n (mousedown)=\"onMouseDown($event)\"\n (mousemove)=\"onMouseMove($event)\"\n (mouseup)=\"onMouseUp()\"\n (mouseleave)=\"onMouseUp()\"\n >\n <div #graphContainer></div>\n @if (error()) {\n <div class=\"error-message\">\n {{ error() }}\n </div>\n }\n @if (loading()) {\n <div class=\"loading\">Loading...</div>\n }\n <div class=\"zoom-controls\">\n <button type=\"button\" (click)=\"zoomIn()\" class=\"zoom-btn\" title=\"Zoom In\">\n +\n </button>\n <button type=\"button\" (click)=\"zoomOut()\" class=\"zoom-btn\" title=\"Zoom Out\">\n -\n </button>\n <button\n type=\"button\"\n (click)=\"fitToContainer()\"\n class=\"zoom-btn fit-btn\"\n title=\"Fit to Container\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n stroke=\"currentColor\"\n fill=\"none\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"\n />\n </svg>\n </button>\n <button type=\"button\" (click)=\"resetView()\" class=\"zoom-btn\" title=\"Reset\">\n ↺\n </button>\n <button type=\"button\" (click)=\"exportSVG()\" class=\"zoom-btn\" title=\"Save\">\n 💾\n </button>\n </div>\n </div>\n","/*\r\n * Public API Surface of ngx-viz\r\n */\r\n\r\nexport * from './lib/viz.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}