@memberjunction/ng-entity-relationship-diagram 5.43.0 → 5.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/entity-details/entity-details.component.js +157 -154
- package/dist/lib/components/entity-details/entity-details.component.js.map +1 -1
- package/dist/lib/components/erd-diagram.component.d.ts +4 -0
- package/dist/lib/components/erd-diagram.component.d.ts.map +1 -1
- package/dist/lib/components/erd-diagram.component.js +19 -25
- package/dist/lib/components/erd-diagram.component.js.map +1 -1
- package/dist/lib/entity-relationship-diagram.module.d.ts +1 -1
- package/dist/lib/entity-relationship-diagram.module.d.ts.map +1 -1
- package/dist/lib/entity-relationship-diagram.module.js +9 -3
- package/dist/lib/entity-relationship-diagram.module.js.map +1 -1
- package/package.json +6 -5
- package/dist/__tests__/compute-erd-layout.test.d.ts +0 -2
- package/dist/__tests__/compute-erd-layout.test.d.ts.map +0 -1
- package/dist/__tests__/compute-erd-layout.test.js +0 -207
- package/dist/__tests__/compute-erd-layout.test.js.map +0 -1
- package/dist/__tests__/entity-to-erd-adapter.test.d.ts +0 -2
- package/dist/__tests__/entity-to-erd-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/entity-to-erd-adapter.test.js +0 -252
- package/dist/__tests__/entity-to-erd-adapter.test.js.map +0 -1
- package/dist/__tests__/erd-types.test.d.ts +0 -2
- package/dist/__tests__/erd-types.test.d.ts.map +0 -1
- package/dist/__tests__/erd-types.test.js +0 -104
- package/dist/__tests__/erd-types.test.js.map +0 -1
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -7
- package/dist/__tests__/index.test.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <div class=\"erd-empty\">\n <div class=\"erd-empty-icon\">\n <i [class]=\"config.emptyStateIcon || 'fa-solid fa-diagram-project'\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"erd-empty-title\">\n {{ totalCount === 0 ? (config.emptyStateMessage || 'No entities to display') : 'No entities match' }}\n </div>\n @if (totalCount > 0) {\n <div class=\"erd-empty-hint\">Try adjusting schema filters or clearing search</div>\n }\n </div>\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"erd-diagram.component.js","sourceRoot":"","sources":["../../../src/lib/components/erd-diagram.component.ts","../../../src/lib/components/erd-diagram.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @module erd-diagram.component\n * @description\n * Schema-grouped Entity Relationship Diagram. Each schema becomes a rounded\n * rectangular band; entities tile in a grid within the band. Click a node to\n * enter focus mode (neighbours highlighted, everything else dimmed) and see a\n * floating details card with its inbound and outbound FKs.\n *\n * The component is pure Angular + SVG (no D3, no Dagre). Layout is computed\n * by a pure function in `../layout/compute-erd-layout.ts` that is easily\n * unit-tested.\n *\n * Public API is preserved from the previous D3-based implementation so\n * existing consumers (Database Designer wizard preview, admin ERD dashboard,\n * Entity Record view) continue to work without changes.\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ElementRef,\n ViewChild,\n HostBinding,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n AfterViewInit,\n OnDestroy,\n OnChanges,\n SimpleChanges,\n inject,\n} from '@angular/core';\nimport {\n ERDNode,\n ERDField,\n ERDLink,\n ERDConfig,\n ERDNodeClickEvent,\n ERDNodeDoubleClickEvent,\n ERDLinkClickEvent,\n ERDZoomEvent,\n ERDState,\n ERDNodeHoverEvent,\n ERDLinkHoverEvent,\n ERDNodeContextMenuEvent,\n ERDLinkContextMenuEvent,\n ERDDiagramContextMenuEvent,\n ERDNodeDragEvent,\n} from '../interfaces/erd-types';\nimport {\n computeErdLayout,\n pointsToPath,\n getNeighbors,\n type ErdLayout,\n type LaidOutNode,\n type LaidOutEdge,\n type LaidOutBand,\n} from '../layout/compute-erd-layout';\nimport { computeDagreLayout } from '../layout/compute-dagre-layout';\n\n// ──────────────────────────────────────────────────────────────────────────\n// Internal view-model types\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface SchemaChip {\n name: string;\n count: number;\n active: boolean;\n}\n\n/** 2D transform (pan x/y + zoom scale) for the SVG stage. */\ninterface Transform {\n x: number;\n y: number;\n k: number;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-erd-diagram',\n templateUrl: './erd-diagram.component.html',\n styleUrls: ['./erd-diagram.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ERDDiagramComponent implements AfterViewInit, OnDestroy, OnChanges {\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly host = inject(ElementRef);\n\n // ─── INPUTS ───────────────────────────────────────────────────────────\n\n @Input() public nodes: ERDNode[] = [];\n @Input() public selectedNodeId: string | null = null;\n @Input() public highlightedNodeIds: string[] = [];\n @Input() public focusNodeId: string | null = null;\n @Input() public focusDepth = 1;\n @Input() public isRefreshing = false;\n @Input() public readOnly = false;\n @Input() public config: ERDConfig = {};\n @Input() public showHeader = true;\n @Input() public headerTitle = 'Entity Relationship Diagram';\n\n // ─── OUTPUTS (preserved from legacy API) ──────────────────────────────\n\n @Output() public nodeClick = new EventEmitter<ERDNodeClickEvent>();\n @Output() public nodeDoubleClick = new EventEmitter<ERDNodeDoubleClickEvent>();\n @Output() public nodeSelected = new EventEmitter<ERDNode>();\n @Output() public nodeDeselected = new EventEmitter<void>();\n @Output() public linkClick = new EventEmitter<ERDLinkClickEvent>();\n @Output() public nodeHover = new EventEmitter<ERDNodeHoverEvent>();\n @Output() public nodeHoverEnd = new EventEmitter<ERDNode>();\n @Output() public linkHover = new EventEmitter<ERDLinkHoverEvent>();\n @Output() public linkHoverEnd = new EventEmitter<ERDLink>();\n @Output() public nodeContextMenu = new EventEmitter<ERDNodeContextMenuEvent>();\n @Output() public linkContextMenu = new EventEmitter<ERDLinkContextMenuEvent>();\n @Output() public diagramContextMenu = new EventEmitter<ERDDiagramContextMenuEvent>();\n @Output() public nodeDragStart = new EventEmitter<ERDNodeDragEvent>();\n @Output() public nodeDragEnd = new EventEmitter<ERDNodeDragEvent>();\n @Output() public zoomChange = new EventEmitter<ERDZoomEvent>();\n @Output() public refreshRequested = new EventEmitter<void>();\n @Output() public layoutComplete = new EventEmitter<void>();\n @Output() public stateChange = new EventEmitter<ERDState>();\n\n // ─── VIEW CHILDREN ────────────────────────────────────────────────────\n\n @ViewChild('canvasRef', { static: false }) private canvasRef?: ElementRef<SVGSVGElement>;\n\n // ─── STATE ────────────────────────────────────────────────────────────\n\n /** Current pan + zoom. */\n public transform: Transform = { x: 0, y: 0, k: 1 };\n\n /** Set of schema names the user has filtered IN. Null means \"all\". */\n public activeSchemas: Set<string> | null = null;\n\n /** Search query string. */\n public searchQuery = '';\n\n /** Node IDs the user has clicked \"+N more fields\" on. */\n public expandedNodeIds = new Set<string>();\n\n /** Node currently being hovered (for highlight preview). */\n public hoverNodeId: string | null = null;\n\n /** Cached layout — recomputed when nodes, filter, search or expansion changes. */\n public layout: ErdLayout = { nodes: [], edges: [], bands: [], totalWidth: 0, totalHeight: 0 };\n\n /**\n * Active layout algorithm. Starts from `config.layoutAlgorithm` (default\n * `schema-grid`) but can be toggled at runtime via `setLayoutAlgorithm`.\n * Exposed so the chrome toggle + saved user state can drive it.\n */\n public activeLayout: 'schema-grid' | 'dagre' = 'schema-grid';\n\n /** Derived schema summary for the chip row. */\n public schemaChips: SchemaChip[] = [];\n\n /** Derived — number of entities currently visible. */\n public visibleCount = 0;\n\n /** Icon for the empty state — honours `config.emptyStateIcon` when provided. */\n public get emptyStateIcon(): string {\n return this.config.emptyStateIcon || 'fa-solid fa-diagram-project';\n }\n\n /** Title for the empty state — distinguishes \"nothing here\" from \"filtered to nothing\". */\n public get emptyStateTitle(): string {\n return this.totalCount === 0\n ? (this.config.emptyStateMessage || 'No entities to display')\n : 'No entities match';\n }\n\n /** Derived — total entities in the input, before any filtering. */\n public totalCount = 0;\n\n /** Derived — the Set of IDs in the focus/hover neighbourhood (null when no highlight active). */\n public highlightSet: Set<string> | null = null;\n\n /** Derived — the single selected entity, if any. */\n public selectedEntity: ERDNode | null = null;\n\n // Panning bookkeeping (not reactive). Public so the template can bind a\n // cursor attribute to it; treat as internal state.\n public panning = false;\n private panStart: { x: number; y: number } | null = null;\n /** Raw mousedown coords — used to compute drag distance for the\n * pan-vs-click threshold. */\n private dragOrigin: { clientX: number; clientY: number } | null = null;\n /** True once movement crossed the drag threshold — used to suppress\n * the synthetic click that follows the mouseup. */\n private dragMoved = false;\n /** Pixels of movement before mousedown is treated as a drag. */\n private static readonly DRAG_THRESHOLD = 4;\n /** Bound window listeners — kept on the instance so we can detach. */\n private boundWindowMove?: (e: MouseEvent) => void;\n private boundWindowUp?: (e: MouseEvent) => void;\n\n private resizeObserver?: ResizeObserver;\n\n @HostBinding('class.erd-root') readonly rootClass = true;\n\n // ─── LIFECYCLE ────────────────────────────────────────────────────────\n\n public ngOnChanges(changes: SimpleChanges): void {\n const nodesChanged = !!changes['nodes'];\n // Compare config by the fields we actually use — consumers that bind\n // an inline `[config]=\"{...}\"` object literal get a new reference\n // every CD cycle, so a naive `changes['config']` check would\n // recompute + refit endlessly.\n const configChanged = this.configAffectsLayout(\n changes['config']?.previousValue as ERDConfig | undefined,\n changes['config']?.currentValue as ERDConfig | undefined,\n );\n if (nodesChanged || configChanged) {\n if (nodesChanged) {\n this.activeSchemas = null;\n this.expandedNodeIds = new Set();\n this.hoverNodeId = null;\n }\n // Honour `config.layoutAlgorithm` on first arrival; runtime\n // changes happen via `setLayoutAlgorithm`.\n if (this.config.layoutAlgorithm === 'dagre') this.activeLayout = 'dagre';\n else if (this.config.layoutAlgorithm === 'schema-grid') this.activeLayout = 'schema-grid';\n this.recompute();\n // Fit-to-view once the DOM has the new canvas dimensions.\n queueMicrotask(() => this.fitToView());\n }\n if (changes['focusNodeId']) {\n this.updateHighlightSet();\n this.cdr.markForCheck();\n }\n }\n\n /** True iff any config field that influences the cached layout changed. */\n private configAffectsLayout(prev: ERDConfig | undefined, curr: ERDConfig | undefined): boolean {\n if (prev === curr) return false;\n return (\n (prev?.nodeWidth ?? null) !== (curr?.nodeWidth ?? null) ||\n (prev?.fieldHeight ?? null) !== (curr?.fieldHeight ?? null) ||\n (prev?.showAllFields ?? null) !== (curr?.showAllFields ?? null) ||\n (prev?.showSchemaBands ?? null) !== (curr?.showSchemaBands ?? null) ||\n (prev?.crowsFoot ?? null) !== (curr?.crowsFoot ?? null) ||\n (prev?.maxFitZoom ?? null) !== (curr?.maxFitZoom ?? null) ||\n (prev?.minZoom ?? null) !== (curr?.minZoom ?? null) ||\n (prev?.maxZoom ?? null) !== (curr?.maxZoom ?? null)\n );\n }\n\n public ngAfterViewInit(): void {\n this.resizeObserver = this.watchResize();\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n // Detach any pan listeners still bound from an in-progress drag.\n if (this.boundWindowMove) window.removeEventListener('mousemove', this.boundWindowMove);\n if (this.boundWindowUp) window.removeEventListener('mouseup', this.boundWindowUp);\n }\n\n // ─── RECOMPUTATION ────────────────────────────────────────────────────\n\n /** Rebuild the layout + derived view-model from current inputs/state. */\n private recompute(): void {\n this.totalCount = this.nodes.length;\n\n const filteredBySchema = this.activeSchemas\n ? this.nodes.filter(n => this.activeSchemas!.has(n.schemaName || '_'))\n : this.nodes;\n\n const q = this.searchQuery.trim().toLowerCase();\n const filtered = q\n ? filteredBySchema.filter(n =>\n n.name.toLowerCase().includes(q) ||\n (n.schemaName?.toLowerCase().includes(q) ?? false) ||\n n.fields.some(f => f.name.toLowerCase().includes(q)))\n : filteredBySchema;\n\n this.visibleCount = filtered.length;\n\n const commonOpts = {\n nodeWidth: this.config.nodeWidth ?? 220,\n fieldHeight: this.config.fieldHeight ?? 22,\n expandedNodeIds: this.expandedNodeIds,\n showAllFields: this.config.showAllFields ?? false,\n };\n\n this.layout = this.activeLayout === 'dagre'\n ? computeDagreLayout(filtered, {\n ...commonOpts,\n rankDir: this.config.dagreConfig?.rankDir ?? 'LR',\n nodeSep: this.config.dagreConfig?.nodeSep,\n rankSep: this.config.dagreConfig?.rankSep,\n })\n : computeErdLayout(filtered, commonOpts);\n\n this.schemaChips = this.buildSchemaChips();\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n /**\n * Switch between the schema-grid and dagre hierarchical layouts at\n * runtime. Emits a state change so the consumer can persist the\n * user's preference (via `userStateChange` on `mj-erd-composite`).\n *\n * Also clears the current focus/selection — switching layouts moves\n * cards to entirely new positions, so the previously-selected entity\n * would otherwise stay highlighted in a different spot with the side\n * panel still open, which is jarring. A clean slate is better.\n */\n public setLayoutAlgorithm(algo: 'schema-grid' | 'dagre'): void {\n if (this.activeLayout === algo) return;\n this.activeLayout = algo;\n\n const hadSelection = !!(this.focusNodeId || this.selectedNodeId);\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.updateSelectedEntity();\n if (hadSelection) this.nodeDeselected.emit();\n\n this.recompute();\n queueMicrotask(() => this.fitToView());\n this.stateChange.emit(this.getState());\n }\n\n private buildSchemaChips(): SchemaChip[] {\n const counts = new Map<string, number>();\n for (const n of this.nodes) {\n const s = n.schemaName || '_';\n counts.set(s, (counts.get(s) ?? 0) + 1);\n }\n return [...counts.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([name, count]) => ({\n name,\n count,\n active: this.activeSchemas ? this.activeSchemas.has(name) : true,\n }));\n }\n\n private updateHighlightSet(): void {\n const id = this.focusNodeId ?? this.hoverNodeId;\n this.highlightSet = id ? getNeighbors(this.nodes, id) : null;\n }\n\n private updateSelectedEntity(): void {\n const id = this.focusNodeId ?? this.selectedNodeId;\n this.selectedEntity = id ? this.nodes.find(n => n.id === id) ?? null : null;\n }\n\n private watchResize(): ResizeObserver {\n const observer = new ResizeObserver(() => this.fitToView());\n observer.observe(this.host.nativeElement);\n return observer;\n }\n\n // ─── PAN / ZOOM / FIT ────────────────────────────────────────────────\n\n /**\n * Mousedown anywhere on the SVG (background OR a node card). We\n * arm a potential pan and attach window-level move/up listeners so\n * the drag continues even if the cursor leaves the canvas (passes\n * over the focus card, scrollbars, the chrome, etc.).\n *\n * The actual `panning = true` flip happens in the move handler once\n * the cursor crosses `DRAG_THRESHOLD` — that way short clicks still\n * register as clicks on cards (no accidental selection-toggle from\n * a tiny mouse jitter).\n */\n public onBackgroundMouseDown(e: MouseEvent): void {\n if (e.button !== 0) return;\n this.dragOrigin = { clientX: e.clientX, clientY: e.clientY };\n this.dragMoved = false;\n this.panStart = { x: e.clientX - this.transform.x, y: e.clientY - this.transform.y };\n\n this.boundWindowMove = (ev: MouseEvent) => this.onWindowMouseMove(ev);\n this.boundWindowUp = (ev: MouseEvent) => this.onWindowMouseUp(ev);\n window.addEventListener('mousemove', this.boundWindowMove);\n window.addEventListener('mouseup', this.boundWindowUp);\n }\n\n private onWindowMouseMove(e: MouseEvent): void {\n if (!this.dragOrigin || !this.panStart) return;\n\n if (!this.panning) {\n const dx = e.clientX - this.dragOrigin.clientX;\n const dy = e.clientY - this.dragOrigin.clientY;\n if (Math.hypot(dx, dy) < ERDDiagramComponent.DRAG_THRESHOLD) return;\n this.panning = true;\n this.dragMoved = true;\n }\n\n this.transform = {\n ...this.transform,\n x: e.clientX - this.panStart.x,\n y: e.clientY - this.panStart.y,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n private onWindowMouseUp(_e: MouseEvent): void {\n // If a drag actually happened, swallow the synthetic click that\n // browsers fire on mouseup so it doesn't reach the node click\n // handler and toggle the focus. We use capture phase + once so\n // we only catch the immediate next click from this mouse-up.\n if (this.dragMoved) {\n const swallow = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n window.addEventListener('click', swallow, { capture: true, once: true });\n }\n\n this.panning = false;\n this.panStart = null;\n this.dragOrigin = null;\n this.dragMoved = false;\n\n if (this.boundWindowMove) {\n window.removeEventListener('mousemove', this.boundWindowMove);\n this.boundWindowMove = undefined;\n }\n if (this.boundWindowUp) {\n window.removeEventListener('mouseup', this.boundWindowUp);\n this.boundWindowUp = undefined;\n }\n }\n\n public onWheel(e: WheelEvent): void {\n if (this.config.enableZoom === false) return;\n e.preventDefault();\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = e.clientX - rect.left;\n const my = e.clientY - rect.top;\n const delta = -e.deltaY * 0.001;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * (1 + delta)));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public zoomBy(factor: number): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n const mx = rect.width / 2;\n const my = rect.height / 2;\n const minZoom = this.config.minZoom ?? 0.15;\n const maxZoom = this.config.maxZoom ?? 2.5;\n const newK = Math.max(minZoom, Math.min(maxZoom, this.transform.k * factor));\n const ratio = newK / this.transform.k;\n this.transform = {\n k: newK,\n x: mx - (mx - this.transform.x) * ratio,\n y: my - (my - this.transform.y) * ratio,\n };\n this.emitZoom();\n this.cdr.markForCheck();\n }\n\n public fitToView(): void {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return;\n const rect = svg.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0 || this.layout.totalWidth === 0) return;\n\n const padding = 60;\n // Allow fit to scale UP for small diagrams (e.g. the Database Designer\n // wizard preview, where a single entity + a couple of satellites\n // would otherwise look lost in the pane). Consumers can override via\n // `config.maxFitZoom`. Default 2.5x: a 220px card becomes ~550px,\n // which comfortably fills a typical preview pane without looking\n // cartoonish (13px text → ~33px, still a readable ceiling).\n const maxFit = this.config.maxFitZoom ?? 2.5;\n const idealK = Math.min(\n (rect.width - padding * 2) / this.layout.totalWidth,\n (rect.height - padding * 2) / this.layout.totalHeight,\n maxFit,\n );\n\n // Clamp the fit zoom so cards stay legible. On very large schemas\n // (hundreds of entities) fit-to-view would otherwise shrink each card\n // to a few pixels wide. We'd rather show part of the canvas at a\n // readable zoom and let the user pan to see the rest.\n const minZoom = this.config.minZoom ?? 0.35;\n const k = Math.max(idealK, minZoom);\n\n // Center horizontally only if the canvas fits; otherwise anchor at left\n // so the user starts at the first schema band instead of the middle.\n const canvasFitsX = this.layout.totalWidth * k <= rect.width - padding * 2;\n const canvasFitsY = this.layout.totalHeight * k <= rect.height - padding * 2;\n\n const newX = canvasFitsX ? (rect.width - this.layout.totalWidth * k) / 2 : padding;\n const newY = canvasFitsY ? (rect.height - this.layout.totalHeight * k) / 2 : padding;\n\n // Idempotent guard. If the computed transform is effectively identical\n // to the current one, bail out without reassigning or calling\n // markForCheck. Without this, a consumer that passes an inline\n // `[config]=\"{...}\"` object literal re-triggers ngOnChanges on every\n // change-detection tick, producing an infinite fitToView → markForCheck\n // → CD → ngOnChanges → fitToView loop (NG0103).\n const TOL = 0.001;\n if (\n Math.abs(this.transform.k - k) < TOL &&\n Math.abs(this.transform.x - newX) < 0.5 &&\n Math.abs(this.transform.y - newY) < 0.5\n ) {\n return;\n }\n\n this.transform = { k, x: newX, y: newY };\n this.emitZoom();\n this.layoutComplete.emit();\n this.cdr.markForCheck();\n }\n\n private centerOn(nodeId: string): void {\n const n = this.layout.nodes.find(x => x.id === nodeId);\n const svg = this.canvasRef?.nativeElement;\n if (!n || !svg) return;\n const rect = svg.getBoundingClientRect();\n const k = Math.max(this.transform.k, 0.9);\n this.transform = {\n k,\n x: rect.width / 2 - (n.x + n.width / 2) * k,\n y: rect.height / 2 - (n.y + n.height / 2) * k,\n };\n this.emitZoom();\n // External callers (e.g. zoomToNode invoked from the side panel)\n // need CD to pick up the new transform — onNodeClick used to do\n // this itself but external pathways were silently no-op'ing.\n this.cdr.markForCheck();\n }\n\n private emitZoom(): void {\n this.zoomChange.emit({\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n });\n }\n\n // ─── NODE INTERACTIONS ───────────────────────────────────────────────\n\n public onNodeClick(node: LaidOutNode, e: MouseEvent): void {\n e.stopPropagation();\n const event: ERDNodeClickEvent = { node, mouseEvent: e, cancel: false };\n this.nodeClick.emit(event);\n if (event.cancel) return;\n\n if (this.focusNodeId === node.id) {\n // Toggle off — deselect.\n this.focusNodeId = null;\n this.selectedNodeId = null;\n this.nodeDeselected.emit();\n } else {\n this.focusNodeId = node.id;\n this.selectedNodeId = node.id;\n this.nodeSelected.emit(node);\n this.centerOn(node.id);\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public onNodeMouseEnter(node: LaidOutNode, e: MouseEvent): void {\n this.hoverNodeId = node.id;\n this.updateHighlightSet();\n const related = this.nodes.filter(n => this.highlightSet?.has(n.id) && n.id !== node.id);\n this.nodeHover.emit({\n node, mouseEvent: e, relatedNodes: related,\n position: { x: e.clientX, y: e.clientY },\n });\n this.cdr.markForCheck();\n }\n\n public onNodeMouseLeave(node: LaidOutNode): void {\n this.hoverNodeId = null;\n this.updateHighlightSet();\n this.nodeHoverEnd.emit(node);\n this.cdr.markForCheck();\n }\n\n public onToggleExpand(nodeId: string, e: Event): void {\n e.stopPropagation();\n if (this.expandedNodeIds.has(nodeId)) this.expandedNodeIds.delete(nodeId);\n else this.expandedNodeIds.add(nodeId);\n // New Set reference so @for trackBy treats it as changed.\n this.expandedNodeIds = new Set(this.expandedNodeIds);\n this.recompute();\n }\n\n // ─── CHROME INTERACTIONS ─────────────────────────────────────────────\n\n public onSearchChange(value: string): void {\n this.searchQuery = value;\n this.recompute();\n }\n\n public onClearSearch(): void {\n this.searchQuery = '';\n this.recompute();\n }\n\n public onSchemaChipToggle(schemaName: string): void {\n const current = this.activeSchemas ?? new Set(this.schemaChips.map(c => c.name));\n const next = new Set(current);\n if (next.has(schemaName)) next.delete(schemaName);\n else next.add(schemaName);\n this.activeSchemas = next.size === this.schemaChips.length ? null : next;\n this.recompute();\n }\n\n public onRequestRefresh(): void {\n this.refreshRequested.emit();\n }\n\n // ─── DERIVED DATA FOR TEMPLATE ───────────────────────────────────────\n\n /** Path string for an edge — uses the orthogonal polyline from layout. */\n public edgePath(edge: LaidOutEdge): string {\n return pointsToPath(edge.points);\n }\n\n /**\n * Whether to render FK field labels along edges. Defaults to ON in\n * both layouts — the zoom-gate (>=0.55x) keeps the labels off when\n * the user is zoomed out far enough to see hundreds of entities, so\n * \"noise on dense views\" isn't a real concern. Consumers can still\n * force off via `config.showRelationshipLabels: false`.\n */\n public get showEdgeLabels(): boolean {\n const enabled = this.config.showRelationshipLabels ?? true;\n if (!enabled) return false;\n return this.transform.k >= 0.55;\n }\n\n /**\n * Pick a point along the edge polyline for a label and approximate\n * its width. Returns null for self-loops (no good place to put text).\n * Uses the longest horizontal segment when one exists; falls back to\n * the segment midpoint otherwise.\n */\n public edgeLabelPosition(edge: LaidOutEdge): { x: number; y: number; w: number } | null {\n if (edge.selfReference) return null;\n const pts = edge.points;\n if (pts.length < 2) return null;\n\n // Find the longest horizontal segment so the label sits on a\n // straight portion, not over a corner.\n let bestIdx = 0;\n let bestLen = 0;\n for (let i = 0; i < pts.length - 1; i++) {\n const [x1, y1] = pts[i];\n const [x2, y2] = pts[i + 1];\n if (Math.abs(y2 - y1) > 0.5) continue; // skip vertical segs\n const len = Math.abs(x2 - x1);\n if (len > bestLen) { bestLen = len; bestIdx = i; }\n }\n\n const [x1, y1] = pts[bestIdx];\n const [x2, y2] = pts[bestIdx + 1];\n const x = (x1 + x2) / 2;\n const y = (y1 + y2) / 2;\n\n // 6.5 px per char is a good approximation for the 11px mono we\n // use for labels — only used to size the background rect.\n const w = Math.max(20, edge.sourceField.name.length * 6.5);\n return { x, y, w };\n }\n\n /** Whether a node should appear dimmed (highlight mode active, node not in set). */\n public isDimmed(nodeId: string): boolean {\n return !!this.highlightSet && !this.highlightSet.has(nodeId);\n }\n\n /** Whether a node is the current focus (strong border). */\n public isFocus(nodeId: string): boolean {\n return this.focusNodeId === nodeId;\n }\n\n /** Whether a node is a 1-hop neighbour of the focus (medium border). */\n public isNeighbour(nodeId: string): boolean {\n return !!this.highlightSet && this.highlightSet.has(nodeId) && !this.isFocus(nodeId);\n }\n\n /** Whether an edge is part of the active highlight subgraph. */\n public isEdgeActive(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && this.highlightSet.has(edge.sourceId) && this.highlightSet.has(edge.targetId);\n }\n\n /** Whether an edge should appear dimmed. */\n public isEdgeDimmed(edge: LaidOutEdge): boolean {\n return !!this.highlightSet && !this.isEdgeActive(edge);\n }\n\n /** Zoom percentage string for the toolbar readout. */\n public get zoomPercent(): string {\n return Math.round(this.transform.k * 100) + '%';\n }\n\n /** Short friendly row-count string (e.g. 1248 → \"1.2k\"). */\n public formatCount(n: number | undefined): string {\n if (n == null) return '';\n if (n >= 1000) return (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k';\n return n.toString();\n }\n\n /** Number of PK fields — handy aggregate (kept for external API parity). */\n public pkCount(entity: ERDNode): number {\n return entity.fields.filter(f => f.isPrimaryKey).length;\n }\n\n /** Number of FK fields — handy aggregate (kept for external API parity). */\n public fkCount(entity: ERDNode): number {\n return entity.fields.filter(f => !!f.relatedNodeId).length;\n }\n\n // ─── LEGACY API SHIMS ────────────────────────────────────────────────\n // Kept so existing consumers (mj-entity-erd wrapper, admin ERD dashboard)\n // continue to compile and work. The new implementation doesn't need\n // most of these, but we preserve the shape.\n\n public zoomIn(): void { this.zoomBy(1.2); }\n public zoomOut(): void { this.zoomBy(0.83); }\n public resetZoom(): void { this.fitToView(); }\n public zoomToFit(_padding?: number): void { this.fitToView(); }\n public zoomToNode(nodeId: string, _scale?: number): void { this.centerOn(nodeId); }\n public triggerResize(): void { this.fitToView(); }\n\n public refresh(): void {\n this.recompute();\n queueMicrotask(() => this.fitToView());\n }\n\n public getState(): ERDState {\n return {\n selectedNodeId: this.selectedNodeId,\n highlightedNodeIds: [...this.highlightedNodeIds],\n zoomLevel: this.transform.k,\n translateX: this.transform.x,\n translateY: this.transform.y,\n focusNodeId: this.focusNodeId,\n focusDepth: this.focusDepth,\n nodePositions: {},\n layoutAlgorithm: this.activeLayout,\n };\n }\n\n public setState(state: Partial<ERDState>, _restorePositions?: boolean): void {\n if (state.selectedNodeId !== undefined) this.selectedNodeId = state.selectedNodeId;\n if (state.highlightedNodeIds !== undefined) this.highlightedNodeIds = [...state.highlightedNodeIds];\n if (state.focusNodeId !== undefined) this.focusNodeId = state.focusNodeId;\n if (state.focusDepth !== undefined) this.focusDepth = state.focusDepth;\n if (state.zoomLevel !== undefined || state.translateX !== undefined || state.translateY !== undefined) {\n this.transform = {\n k: state.zoomLevel ?? this.transform.k,\n x: state.translateX ?? this.transform.x,\n y: state.translateY ?? this.transform.y,\n };\n }\n if (state.layoutAlgorithm && state.layoutAlgorithm !== this.activeLayout) {\n this.activeLayout = state.layoutAlgorithm;\n this.recompute();\n }\n this.updateHighlightSet();\n this.updateSelectedEntity();\n this.cdr.markForCheck();\n }\n\n public exportAsSVG(): string {\n const svg = this.canvasRef?.nativeElement;\n if (!svg) return '';\n return new XMLSerializer().serializeToString(svg);\n }\n\n // ─── TRACK-BYs ───────────────────────────────────────────────────────\n\n public trackByBand = (_: number, b: LaidOutBand) => b.schemaName;\n public trackByEdge = (_: number, e: LaidOutEdge) => e.id;\n public trackByNode = (_: number, n: LaidOutNode) => n.id;\n public trackByField = (_: number, f: ERDField) => f.id || f.name;\n public trackByChip = (_: number, c: SchemaChip) => c.name;\n}\n","<!-- ── CHROME ──────────────────────────────────────────────────────────── -->\n@if (showHeader) {\n <header class=\"erd-chrome\">\n <div class=\"erd-title-group\">\n <div class=\"erd-title\">{{ headerTitle }}</div>\n <div class=\"erd-subtitle\">\n <span class=\"erd-count-pill\">{{ visibleCount }}</span>\n <span class=\"erd-count-label\">of {{ totalCount }} entities</span>\n <span class=\"erd-dot\">·</span>\n <span>{{ layout.edges.length }} relationships</span>\n </div>\n </div>\n\n <label class=\"erd-search\">\n <i class=\"fa-solid fa-magnifying-glass\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n [value]=\"searchQuery\"\n (input)=\"onSearchChange($any($event.target).value)\"\n placeholder=\"Search entities, schemas, fields…\"\n spellcheck=\"false\"\n aria-label=\"Search entities\" />\n @if (searchQuery) {\n <button type=\"button\" class=\"erd-search-clear\" (click)=\"onClearSearch()\" aria-label=\"Clear search\">×</button>\n }\n </label>\n\n <div class=\"erd-chrome-right\">\n @if (schemaChips.length > 1) {\n <div class=\"erd-schema-chips\" role=\"group\" aria-label=\"Filter by schema\">\n @for (chip of schemaChips; track trackByChip($index, chip)) {\n <button\n type=\"button\"\n class=\"erd-chip\"\n [class.active]=\"chip.active\"\n (click)=\"onSchemaChipToggle(chip.name)\"\n [attr.aria-pressed]=\"chip.active\">\n <span class=\"erd-chip-label\">{{ chip.name }}</span>\n <span class=\"erd-chip-count\">{{ chip.count }}</span>\n </button>\n }\n </div>\n }\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Layout mode\">\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'schema-grid'\"\n (click)=\"setLayoutAlgorithm('schema-grid')\"\n title=\"Schema grid — grouped by schema, predictable\"\n aria-label=\"Schema-grid layout\">\n <i class=\"fa-solid fa-table-cells\" aria-hidden=\"true\"></i>\n </button>\n <button\n type=\"button\"\n [class.active]=\"activeLayout === 'dagre'\"\n (click)=\"setLayoutAlgorithm('dagre')\"\n title=\"Hierarchical — classic ERD, relationship-driven\"\n aria-label=\"Hierarchical layout\">\n <i class=\"fa-solid fa-sitemap\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <div class=\"erd-toolbar\" role=\"group\" aria-label=\"Zoom controls\">\n <button type=\"button\" (click)=\"zoomBy(1.2)\" title=\"Zoom in\" aria-label=\"Zoom in\">\n <i class=\"fa-solid fa-magnifying-glass-plus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"zoomBy(0.83)\" title=\"Zoom out\" aria-label=\"Zoom out\">\n <i class=\"fa-solid fa-magnifying-glass-minus\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" (click)=\"fitToView()\" title=\"Fit to view\" aria-label=\"Fit to view\">\n <i class=\"fa-solid fa-expand\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"erd-zoom-val\">{{ zoomPercent }}</span>\n </div>\n </div>\n </header>\n}\n\n<!-- ── CANVAS ──────────────────────────────────────────────────────────── -->\n<!-- Pan handling is window-level once mousedown fires (see component) so\n dragging continues even if the cursor leaves the canvas-wrap. -->\n<div class=\"erd-canvas-wrap\">\n\n <svg\n #canvasRef\n class=\"erd-canvas\"\n [attr.data-panning]=\"panning ? 'true' : null\"\n (mousedown)=\"onBackgroundMouseDown($event)\"\n (wheel)=\"onWheel($event)\">\n\n <defs>\n <marker id=\"erd-arrow\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker\" />\n </marker>\n <marker id=\"erd-arrow-active\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" class=\"erd-marker erd-marker-active\" />\n </marker>\n <marker id=\"erd-many\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke\" />\n </marker>\n <marker id=\"erd-many-active\" viewBox=\"-10 -6 14 12\" refX=\"-8\" refY=\"0\" markerWidth=\"14\" markerHeight=\"14\" orient=\"auto\">\n <path d=\"M 0 -5 L -8 0 L 0 5 M -8 0 L 4 0\" class=\"erd-marker-stroke erd-marker-active\" />\n </marker>\n </defs>\n\n <g [attr.transform]=\"'translate(' + transform.x + ' ' + transform.y + ') scale(' + transform.k + ')'\">\n\n <!-- Schema bands -->\n @if ((config.showSchemaBands ?? true)) {\n @for (band of layout.bands; track trackByBand($index, band)) {\n <g class=\"erd-band\">\n <rect\n [attr.x]=\"band.x\" [attr.y]=\"band.y\"\n [attr.width]=\"band.width\" [attr.height]=\"band.height\"\n rx=\"16\"\n class=\"erd-band-rect\" />\n <text\n [attr.x]=\"band.x + band.width / 2\"\n [attr.y]=\"band.y + 32\"\n text-anchor=\"middle\"\n class=\"erd-band-title\">\n {{ band.schemaName }}\n </text>\n </g>\n }\n }\n\n <!-- Edges -->\n <g class=\"erd-edges\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n <path\n [attr.d]=\"edgePath(edge)\"\n fill=\"none\"\n class=\"erd-edge\"\n [class.erd-edge-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-dimmed]=\"isEdgeDimmed(edge)\"\n [attr.marker-start]=\"(config.crowsFoot ?? true) ? (isEdgeActive(edge) ? 'url(#erd-many-active)' : 'url(#erd-many)') : null\"\n [attr.marker-end]=\"isEdgeActive(edge) ? 'url(#erd-arrow-active)' : 'url(#erd-arrow)'\" />\n }\n </g>\n\n <!-- Edge labels — FK field names rendered along edges. Only shown\n when zoom is high enough for the text to be legible, and only\n when config.showRelationshipLabels resolves true. -->\n @if (showEdgeLabels) {\n <g class=\"erd-edge-labels\">\n @for (edge of layout.edges; track trackByEdge($index, edge)) {\n @let pos = edgeLabelPosition(edge);\n @if (pos) {\n <g\n class=\"erd-edge-label\"\n [class.erd-edge-label-active]=\"isEdgeActive(edge)\"\n [class.erd-edge-label-dimmed]=\"isEdgeDimmed(edge)\">\n <rect\n [attr.x]=\"pos.x - pos.w / 2 - 4\"\n [attr.y]=\"pos.y - 8\"\n [attr.width]=\"pos.w + 8\"\n height=\"16\"\n rx=\"3\"\n class=\"erd-edge-label-bg\" />\n <text\n [attr.x]=\"pos.x\"\n [attr.y]=\"pos.y + 4\"\n text-anchor=\"middle\"\n class=\"erd-edge-label-text\">{{ edge.sourceField.name }}</text>\n </g>\n }\n }\n </g>\n }\n\n <!-- Nodes -->\n <g class=\"erd-nodes\">\n @for (node of layout.nodes; track trackByNode($index, node)) {\n <g\n class=\"erd-node\"\n [attr.transform]=\"'translate(' + node.x + ' ' + node.y + ')'\"\n [class.erd-node-focus]=\"isFocus(node.id)\"\n [class.erd-node-neighbour]=\"isNeighbour(node.id)\"\n [class.erd-node-dimmed]=\"isDimmed(node.id)\"\n (click)=\"onNodeClick(node, $event)\"\n (mouseenter)=\"onNodeMouseEnter(node, $event)\"\n (mouseleave)=\"onNodeMouseLeave(node)\">\n\n <!-- Card shadow -->\n <rect class=\"erd-node-shadow\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"2\" rx=\"8\" />\n\n <!-- Card body -->\n <rect class=\"erd-node-body\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n\n <!-- Header -->\n <rect class=\"erd-node-header\"\n x=\"0\" y=\"0\"\n [attr.width]=\"node.width\" height=\"36\"\n rx=\"6\" />\n <foreignObject x=\"14\" y=\"8\" [attr.width]=\"node.width - 28\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-node-header-content\">\n <span class=\"erd-node-name\" [title]=\"node.name\">{{ node.name }}</span>\n @if (node.customData && $any(node.customData).rows != null) {\n <span class=\"erd-node-rows\">{{ formatCount($any(node.customData).rows) }}</span>\n }\n </div>\n </foreignObject>\n\n <!-- Separator -->\n <line class=\"erd-node-separator\"\n x1=\"0\" [attr.x2]=\"node.width\" y1=\"36\" y2=\"36\" />\n\n <!-- Fields -->\n @for (field of node.visibleFields; track trackByField($index, field); let i = $index) {\n <foreignObject x=\"0\" [attr.y]=\"36 + i * 22\" [attr.width]=\"node.width\" height=\"22\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\"\n class=\"erd-field-row\"\n [class.erd-field-pk]=\"field.isPrimaryKey\"\n [class.erd-field-fk]=\"!field.isPrimaryKey && field.relatedNodeId\">\n @if (field.isPrimaryKey) {\n <span class=\"erd-field-chip erd-field-chip-pk\">PK</span>\n } @else if (field.relatedNodeId) {\n <span class=\"erd-field-chip erd-field-chip-fk\">FK</span>\n }\n <span class=\"erd-field-name\" [title]=\"field.name\">{{ field.name }}</span>\n @if (field.type) {\n <span class=\"erd-field-type\" [title]=\"field.type\">{{ field.type }}</span>\n }\n </div>\n </foreignObject>\n }\n\n <!-- +N more toggle -->\n @if (node.hasMore) {\n <foreignObject\n x=\"4\"\n [attr.y]=\"36 + node.visibleFields.length * 22 + 6\"\n [attr.width]=\"node.width - 8\"\n height=\"14\"\n (click)=\"onToggleExpand(node.id, $event)\">\n <div xmlns=\"http://www.w3.org/1999/xhtml\" class=\"erd-field-more\">\n + {{ node.fields.length - node.visibleFields.length }} more fields\n </div>\n </foreignObject>\n }\n\n <!-- Outline frame — drawn last so the focus/neighbour stroke\n sits above the header instead of being clipped by it. -->\n <rect class=\"erd-node-frame\"\n [attr.width]=\"node.width\" [attr.height]=\"node.height\"\n x=\"0\" y=\"0\" rx=\"8\" />\n </g>\n }\n </g>\n </g>\n </svg>\n\n <!-- Focus details are rendered by the consumer's side panel\n (mj-entity-details inside mj-erd-composite); the in-canvas\n floating focus card was removed as it duplicated that content. -->\n\n <!-- ── Empty state ─────────────────────────────────────────────────── -->\n @if (visibleCount === 0) {\n <mj-empty-state\n class=\"erd-empty\"\n [Variant]=\"totalCount === 0 ? 'empty' : 'no-results'\"\n [Icon]=\"emptyStateIcon\"\n [Title]=\"emptyStateTitle\"\n [Message]=\"totalCount > 0 ? 'Try adjusting schema filters or clearing search' : ''\" />\n }\n\n <!-- ── Loading overlay ─────────────────────────────────────────────── -->\n @if (isRefreshing) {\n <div class=\"erd-loading-overlay\">\n <div class=\"erd-loading-content\">\n <i class=\"fa-solid fa-circle-notch fa-spin\" aria-hidden=\"true\"></i>\n <span>Loading…</span>\n </div>\n </div>\n }\n</div>\n"]}
|
|
@@ -78,7 +78,7 @@ import * as i9 from "@memberjunction/ng-ui-components";
|
|
|
78
78
|
*/
|
|
79
79
|
export declare class EntityRelationshipDiagramModule {
|
|
80
80
|
static ɵfac: i0.ɵɵFactoryDeclaration<EntityRelationshipDiagramModule, never>;
|
|
81
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<EntityRelationshipDiagramModule, [typeof i1.ERDDiagramComponent, typeof i2.MJEntityERDComponent, typeof i3.EntityDetailsComponent, typeof i4.EntityFilterPanelComponent, typeof i5.ERDCompositeComponent], [typeof i6.CommonModule, typeof i7.FormsModule, typeof i8.AngularSplitModule, typeof i9.MJButtonDirective, typeof i9.MJDropdownComponent], [typeof i1.ERDDiagramComponent, typeof i2.MJEntityERDComponent, typeof i3.EntityDetailsComponent, typeof i4.EntityFilterPanelComponent, typeof i5.ERDCompositeComponent]>;
|
|
81
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<EntityRelationshipDiagramModule, [typeof i1.ERDDiagramComponent, typeof i2.MJEntityERDComponent, typeof i3.EntityDetailsComponent, typeof i4.EntityFilterPanelComponent, typeof i5.ERDCompositeComponent], [typeof i6.CommonModule, typeof i7.FormsModule, typeof i8.AngularSplitModule, typeof i9.MJButtonDirective, typeof i9.MJDropdownComponent, typeof i9.MJEmptyStateComponent, typeof i9.MJAccordionModule], [typeof i1.ERDDiagramComponent, typeof i2.MJEntityERDComponent, typeof i3.EntityDetailsComponent, typeof i4.EntityFilterPanelComponent, typeof i5.ERDCompositeComponent]>;
|
|
82
82
|
static ɵinj: i0.ɵɵInjectorDeclaration<EntityRelationshipDiagramModule>;
|
|
83
83
|
}
|
|
84
84
|
//# sourceMappingURL=entity-relationship-diagram.module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-relationship-diagram.module.d.ts","sourceRoot":"","sources":["../../src/lib/entity-relationship-diagram.module.ts"],"names":[],"mappings":";;;;;;;;;;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,
|
|
1
|
+
{"version":3,"file":"entity-relationship-diagram.module.d.ts","sourceRoot":"","sources":["../../src/lib/entity-relationship-diagram.module.ts"],"names":[],"mappings":";;;;;;;;;;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,qBAyBa,+BAA+B;yCAA/B,+BAA+B;0CAA/B,+BAA+B;0CAA/B,+BAA+B;CAAG"}
|
|
@@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
|
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import { FormsModule } from '@angular/forms';
|
|
4
4
|
import { AngularSplitModule } from 'angular-split';
|
|
5
|
-
import { MJButtonDirective, MJDropdownComponent } from '@memberjunction/ng-ui-components';
|
|
5
|
+
import { MJButtonDirective, MJDropdownComponent, MJEmptyStateComponent, MJAccordionModule } from '@memberjunction/ng-ui-components';
|
|
6
6
|
import { ERDDiagramComponent } from './components/erd-diagram.component';
|
|
7
7
|
import { MJEntityERDComponent } from './components/mj-entity-erd.component';
|
|
8
8
|
import { EntityDetailsComponent } from './components/entity-details/entity-details.component';
|
|
@@ -83,7 +83,9 @@ export class EntityRelationshipDiagramModule {
|
|
|
83
83
|
static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
|
|
84
84
|
FormsModule,
|
|
85
85
|
AngularSplitModule,
|
|
86
|
-
MJDropdownComponent
|
|
86
|
+
MJDropdownComponent,
|
|
87
|
+
MJEmptyStateComponent,
|
|
88
|
+
MJAccordionModule] });
|
|
87
89
|
}
|
|
88
90
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityRelationshipDiagramModule, [{
|
|
89
91
|
type: NgModule,
|
|
@@ -101,6 +103,8 @@ export class EntityRelationshipDiagramModule {
|
|
|
101
103
|
AngularSplitModule,
|
|
102
104
|
MJButtonDirective,
|
|
103
105
|
MJDropdownComponent,
|
|
106
|
+
MJEmptyStateComponent,
|
|
107
|
+
MJAccordionModule,
|
|
104
108
|
],
|
|
105
109
|
exports: [
|
|
106
110
|
ERDDiagramComponent,
|
|
@@ -119,7 +123,9 @@ export class EntityRelationshipDiagramModule {
|
|
|
119
123
|
FormsModule,
|
|
120
124
|
AngularSplitModule,
|
|
121
125
|
MJButtonDirective,
|
|
122
|
-
MJDropdownComponent
|
|
126
|
+
MJDropdownComponent,
|
|
127
|
+
MJEmptyStateComponent,
|
|
128
|
+
MJAccordionModule], exports: [ERDDiagramComponent,
|
|
123
129
|
MJEntityERDComponent,
|
|
124
130
|
EntityDetailsComponent,
|
|
125
131
|
EntityFilterPanelComponent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-relationship-diagram.module.js","sourceRoot":"","sources":["../../src/lib/entity-relationship-diagram.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"entity-relationship-diagram.module.js","sourceRoot":"","sources":["../../src/lib/entity-relationship-diagram.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAEpI,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,sDAAsD,CAAC;AAC9F,OAAO,EAAE,0BAA0B,EAAE,MAAM,gEAAgE,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;;AAE3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AA0BH,MAAM,OAAO,+BAA+B;yHAA/B,+BAA+B;4DAA/B,+BAA+B;gEAhBxC,YAAY;YACZ,WAAW;YACX,kBAAkB;YAElB,mBAAmB;YACnB,qBAAqB;YACrB,iBAAiB;;iFAUR,+BAA+B;cAzB3C,QAAQ;eAAC;gBACR,YAAY,EAAE;oBACZ,mBAAmB;oBACnB,oBAAoB;oBACpB,sBAAsB;oBACtB,0BAA0B;oBAC1B,qBAAqB;iBACtB;gBACD,OAAO,EAAE;oBACP,YAAY;oBACZ,WAAW;oBACX,kBAAkB;oBAClB,iBAAiB;oBACjB,mBAAmB;oBACnB,qBAAqB;oBACrB,iBAAiB;iBAClB;gBACD,OAAO,EAAE;oBACP,mBAAmB;oBACnB,oBAAoB;oBACpB,sBAAsB;oBACtB,0BAA0B;oBAC1B,qBAAqB;iBACtB;aACF;;wFACY,+BAA+B,mBAvBxC,mBAAmB;QACnB,oBAAoB;QACpB,sBAAsB;QACtB,0BAA0B;QAC1B,qBAAqB,aAGrB,YAAY;QACZ,WAAW;QACX,kBAAkB;QAClB,iBAAiB;QACjB,mBAAmB;QACnB,qBAAqB;QACrB,iBAAiB,aAGjB,mBAAmB;QACnB,oBAAoB;QACpB,sBAAsB;QACtB,0BAA0B;QAC1B,qBAAqB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { AngularSplitModule } from 'angular-split';\nimport { MJButtonDirective, MJDropdownComponent, MJEmptyStateComponent, MJAccordionModule } from '@memberjunction/ng-ui-components';\n\nimport { ERDDiagramComponent } from './components/erd-diagram.component';\nimport { MJEntityERDComponent } from './components/mj-entity-erd.component';\nimport { EntityDetailsComponent } from './components/entity-details/entity-details.component';\nimport { EntityFilterPanelComponent } from './components/entity-filter-panel/entity-filter-panel.component';\nimport { ERDCompositeComponent } from './components/erd-composite/erd-composite.component';\n\n/**\n * Module for the Entity Relationship Diagram (ERD) visualization components.\n *\n * This module provides a complete suite of components for visualizing and\n * exploring entity relationships:\n *\n * ## Components\n *\n * ### 1. ERDDiagramComponent (`<mj-erd-diagram>`)\n * A generic, reusable ERD component that visualizes entity relationships using\n * D3.js force-directed graphs. It works with any data conforming to the `ERDNode`\n * interface and is completely decoupled from MemberJunction-specific types.\n *\n * ### 2. MJEntityERDComponent (`<mj-entity-erd>`)\n * A higher-level wrapper specifically for MemberJunction. It accepts `EntityInfo[]`\n * directly and handles all the transformation to ERD format automatically.\n *\n * ### 3. EntityDetailsComponent (`<mj-entity-details>`)\n * A detail panel that shows entity information, fields, and relationships when\n * an entity is selected. Designed to work alongside the ERD diagram.\n *\n * ### 4. EntityFilterPanelComponent (`<mj-entity-filter-panel>`)\n * A filter panel for filtering entities by schema, name, status, and base table.\n *\n * ### 5. ERDCompositeComponent (`<mj-erd-composite>`)\n * A complete, ready-to-use ERD exploration interface that combines:\n * - Left panel: Entity filter controls\n * - Center: Interactive ERD diagram\n * - Right panel: Entity details (shown when an entity is selected)\n *\n * ### Choosing Which Component to Use\n *\n * | Use Case | Component |\n * |----------|-----------|\n * | Complete ERD exploration UI | `<mj-erd-composite>` |\n * | ERD diagram with MJ EntityInfo | `<mj-entity-erd>` |\n * | Custom data sources (non-MJ) | `<mj-erd-diagram>` |\n * | Entity detail panel standalone | `<mj-entity-details>` |\n * | Entity filter panel standalone | `<mj-entity-filter-panel>` |\n *\n * @example Using the composite (recommended for dashboards)\n * ```html\n * <mj-erd-composite\n * (userStateChange)=\"saveUserPreferences($event)\"\n * (openRecord)=\"navigateToRecord($event)\">\n * </mj-erd-composite>\n * ```\n *\n * @example Using the MJ wrapper\n * ```html\n * <mj-entity-erd\n * [entities]=\"[currentEntity]\"\n * [selectedEntityId]=\"currentEntity.ID\"\n * [depth]=\"1\"\n * (entitySelected)=\"onEntitySelected($event)\"\n * (openRecord)=\"onOpenRecord($event)\">\n * </mj-entity-erd>\n * ```\n *\n * @example Using the generic component\n * ```html\n * <mj-erd-diagram\n * [nodes]=\"myNodes\"\n * [selectedNodeId]=\"selectedId\"\n * (nodeSelected)=\"onNodeSelected($event)\">\n * </mj-erd-diagram>\n * ```\n */\n@NgModule({\n declarations: [\n ERDDiagramComponent,\n MJEntityERDComponent,\n EntityDetailsComponent,\n EntityFilterPanelComponent,\n ERDCompositeComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n AngularSplitModule,\n MJButtonDirective,\n MJDropdownComponent,\n MJEmptyStateComponent,\n MJAccordionModule,\n ],\n exports: [\n ERDDiagramComponent,\n MJEntityERDComponent,\n EntityDetailsComponent,\n EntityFilterPanelComponent,\n ERDCompositeComponent\n ]\n})\nexport class EntityRelationshipDiagramModule {}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-entity-relationship-diagram",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.45.0",
|
|
4
4
|
"description": "MemberJunction: Entity Relationship Diagram (ERD) component for visualizing entity relationships using D3.js force-directed graphs",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@angular/compiler": "21.1.3",
|
|
27
27
|
"@angular/compiler-cli": "21.1.3",
|
|
28
|
+
"@memberjunction/ng-test-utils": "5.45.0",
|
|
28
29
|
"sass": "^1.97.3",
|
|
29
30
|
"vitest": "^4.0.18"
|
|
30
31
|
},
|
|
@@ -36,10 +37,10 @@
|
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@angular/forms": "21.1.3",
|
|
38
39
|
"@dagrejs/dagre": "^1.1.8",
|
|
39
|
-
"@memberjunction/core": "5.
|
|
40
|
-
"@memberjunction/ng-base-types": "5.
|
|
41
|
-
"@memberjunction/global": "5.
|
|
42
|
-
"@memberjunction/ng-ui-components": "5.
|
|
40
|
+
"@memberjunction/core": "5.45.0",
|
|
41
|
+
"@memberjunction/ng-base-types": "5.45.0",
|
|
42
|
+
"@memberjunction/global": "5.45.0",
|
|
43
|
+
"@memberjunction/ng-ui-components": "5.45.0",
|
|
43
44
|
"@types/d3": "^7.4.3",
|
|
44
45
|
"angular-split": "^20.0.0",
|
|
45
46
|
"d3": "^7.9.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compute-erd-layout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute-erd-layout.test.ts"],"names":[],"mappings":""}
|