Add catalog-owned logical relationships and runtime snapshots, extend the database-management UI and validation coverage, and document the updated operational workflow. Keep active sensitive-generation status in a tooltip and indicator, and update the layout E2E to follow the history action in its new database-scoped location.
300 lines
17 KiB
Markdown
300 lines
17 KiB
Markdown
# Visualizzatore ERD nel browser: proposta solo open source
|
|
|
|
Data dell'audit: 31 agosto 2026.
|
|
|
|
## Decisione
|
|
|
|
Per ThothII sceglierei **AntV X6 + ELK.js** come fondazione del visualizzatore ERD.
|
|
|
|
- **AntV X6** è MIT, non ha una distinta edizione Professional e include nel progetto OSS
|
|
le funzioni che servono davvero a un diagramma complesso: nodi e porte personalizzabili,
|
|
pan/zoom, selezione, minimappa, history, clipboard, tastiera, routing, virtual rendering ed
|
|
export SVG/PNG/JPEG.
|
|
- **ELK.js** è il motore di layout automatico, EPL-2.0 e senza tier commerciale. Il layout
|
|
layered gestisce porte, vincoli sull'ordine delle porte, archi multipli, self-loop e routing
|
|
ortogonale: proprietà importanti per foreign key composite e schemi affollati.
|
|
- La combinazione non dipende da esempi o componenti a pagamento. Il lavoro applicativo che
|
|
resta da fare — semantica ER, livelli di dettaglio, filtri e adattatore X6/ELK — appartiene
|
|
davvero al dominio di ThothII e non è una funzione nascosta dietro un piano Pro.
|
|
|
|
La seconda scelta è **React Flow + ELK.js**. È probabilmente l'integrazione più naturale con
|
|
l'attuale frontend React e ha una migliore storia documentata per accessibilità. Il runtime è
|
|
MIT e non viene tecnicamente depotenziato, ma diversi pattern avanzati già implementati
|
|
(auto-layout, edge routing, undo/redo, copy/paste, expand/collapse) sono pubblicati come esempi
|
|
con licenza React Flow Pro. Non è quindi la scelta più lineare se il criterio prioritario è
|
|
evitare anche una dipendenza progettuale da materiale Professional.
|
|
|
|
## Cosa significa «open source senza limitazioni Professional»
|
|
|
|
L'audit distingue tre casi:
|
|
|
|
1. **OSS completo**: licenza OSI e nessun tier commerciale che trattenga funzioni essenziali.
|
|
2. **OSS con caveat**: il motore è aperto, ma esistono esempi premium, API instabili o limiti
|
|
architetturali rilevanti. Può essere usato, purché il limite sia accettato esplicitamente.
|
|
3. **Escluso**: licenza proprietaria oppure core aperto con funzioni necessarie al viewer
|
|
complesso riservate alla versione commerciale.
|
|
|
|
La valutazione riguarda sia la licenza sia ciò che si può effettivamente costruire senza
|
|
acquistare un prodotto complementare. Le note sulle licenze sono tecniche, non consulenza legale.
|
|
|
|
## Matrice di selezione
|
|
|
|
| Soluzione | Licenza OSS | Tier Pro rilevante | Adeguatezza a ERD complessi | Verdetto |
|
|
|---|---|---|---|---|
|
|
| **AntV X6 + ELK.js** | MIT + EPL-2.0 | Nessuno individuato | Porte per colonna, minimappa, routing, export, virtual rendering e layout avanzato | **Consigliata** |
|
|
| **React Flow + ELK.js** | MIT + EPL-2.0 | Esempi/pattern avanzati Pro, non runtime separato | Ottima UX React, nodi HTML, minimappa e accessibilità; export SVG non nativo | **Valida con caveat** |
|
|
| **maxGraph** | Apache-2.0 | Nessuno | Molto completo, SVG, porte, folding e layout; API imperativa e integrazione React costosa | **Valida con caveat** |
|
|
| **Cytoscape.js + ELK** | MIT | Nessuno | Molto scalabile come grafo, ma meno adatto a tabelle ricche e porte per campo | **Alternativa di nicchia** |
|
|
| **Liam ERD/CLI** | Apache-2.0 | Nessuno | Viewer ERD già rifinito e self-hostable; il package embeddable è interno e instabile | **Reference o app separata** |
|
|
| **Graphviz + Viz.js** | EPL-2.0 + MIT | Nessuno | Layout ed SVG eccellenti; non offre da solo un explorer applicativo | **Renderer di export** |
|
|
| **Mermaid.js + Panzoom** | MIT + MIT/ISC | Mermaid Chart è separato | Facile, ma insufficiente per interazioni e modelli ER ricchi | **Solo preview semplice** |
|
|
| **Sprotty/GLSP** | EPL-2.0 | Nessuno | Potente e completo, ma è un framework di modeling più pesante del necessario | **Non prioritario** |
|
|
| **JointJS** | Core MPL-2.0 | Molte funzioni utili sono in JointJS+ | Lo split commerciale intercetta proprio le necessità del viewer | **Esclusa** |
|
|
| **GoJS** | Proprietaria | Licenza di deployment | Completa tecnicamente, ma non open source | **Esclusa** |
|
|
| **yFiles** | Proprietaria | Licenza commerciale | Completa tecnicamente, ma non open source | **Esclusa** |
|
|
|
|
## 1. Scelta principale: AntV X6 + ELK.js
|
|
|
|
### Funzioni disponibili nell'open source
|
|
|
|
X6 offre un canvas diagrammatico basato su SVG con supporto anche a nodi HTML/React. Il core
|
|
espone porte, archi personalizzabili, self-loop e multiedge. I plugin distribuiti dal progetto
|
|
comprendono Scroller, MiniMap, Selection, History, Clipboard, Keyboard, DnD, Stencil, Snapline,
|
|
Transform ed Export. La documentazione copre inoltre router `orth`, `manhattan` ed `er`, zoom e
|
|
panning. Non è emersa un'edizione X6 Pro che renda a pagamento queste capacità.
|
|
|
|
Fonti primarie: [repository e licenza X6](https://github.com/antvis/X6),
|
|
[porte](https://x6.antv.antgroup.com/en/tutorial/basic/port),
|
|
[router](https://x6.antv.antgroup.com/en/api/registry/router),
|
|
[minimappa](https://x6.antv.antgroup.com/en/tutorial/plugins/minimap),
|
|
[scroller](https://x6.antv.antgroup.com/en/tutorial/plugins/scroller) ed
|
|
[export](https://x6.antv.antgroup.com/en/tutorial/plugins/export).
|
|
|
|
ELK non è un renderer: calcola la geometria del grafo. L'algoritmo layered supporta porte e
|
|
relativi vincoli, archi ortogonali, self-loop e archi multipli. Va eseguito in un Web Worker per
|
|
non bloccare l'interfaccia sui modelli grandi. L'adattatore dovrà passare a ELK le porte delle
|
|
colonne e usare anche le `edge sections` e i bend point restituiti, non soltanto le coordinate
|
|
dei nodi.
|
|
|
|
Fonti primarie: [ELK.js e licenza](https://github.com/kieler/elkjs) e
|
|
[ELK layered](https://eclipse.dev/elk/reference/algorithms/org-eclipse-elk-layered.html).
|
|
|
|
### Limiti reali
|
|
|
|
- X6 è più imperativo di React Flow: conviene incapsularlo in un singolo componente React con
|
|
un adapter stabile, evitando di spargere istanze e listener nel resto dell'applicazione.
|
|
- L'accessibilità per screen reader non è documentata al livello di React Flow; tab order,
|
|
focus, descrizioni ARIA e navigazione da tastiera richiedono test e lavoro applicativo.
|
|
- Un nodo React/HTML può introdurre `foreignObject` nell'SVG. Per un export portabile e
|
|
stampabile è meglio produrre un SVG separato dallo stesso modello e dalla geometria ELK.
|
|
|
|
Questi sono costi tecnici, non limitazioni commerciali.
|
|
|
|
## 2. Seconda scelta: React Flow + ELK.js
|
|
|
|
`@xyflow/react` è MIT. Custom nodes React, handle multipli, pan/zoom, fit view, Controls,
|
|
MiniMap, selezione e funzioni di accessibilità sono nel runtime OSS. React Flow Pro vende
|
|
supporto, template ed esempi con relativo codice sorgente; non esiste una libreria runtime Pro
|
|
che sblocchi il canvas.
|
|
|
|
Il caveat è comunque concreto: auto-layout, edge routing, undo/redo, copy/paste ed
|
|
expand/collapse compaiono nel catalogo degli esempi Pro e quel codice usa la **xyflow Pro
|
|
License**, non la MIT del core. Le stesse funzioni possono essere sviluppate sopra le API OSS,
|
|
ma non si può considerare tutto il materiale ufficiale liberamente riutilizzabile.
|
|
|
|
Fonti primarie: [package React Flow](https://github.com/xyflow/xyflow/blob/main/packages/react/package.json),
|
|
[funzioni del core](https://reactflow.dev/index),
|
|
[catalogo degli esempi Pro](https://reactflow.dev/examples/pro-examples),
|
|
[auto-layout](https://reactflow.dev/examples/layout/auto-layout) e
|
|
[termini Pro](https://reactflow.dev/pro).
|
|
|
|
È una buona scelta se si privilegiano velocità d'integrazione React, componenti HTML e
|
|
accessibilità. Non è la prima scelta di questo audit perché l'utente ha chiesto espressamente
|
|
di minimizzare la distanza fra ciò che è open source e l'offerta Professional.
|
|
|
|
Altro limite: React Flow combina nodi DOM e archi SVG. L'esempio ufficiale di download usa
|
|
`html-to-image`, quindi il diagramma interattivo non si traduce automaticamente in un SVG puro.
|
|
|
|
## 3. Altre soluzioni interamente open source
|
|
|
|
### maxGraph
|
|
|
|
maxGraph, successore TypeScript di mxGraph, è Apache-2.0 e non ha un piano Pro. Offre rendering
|
|
SVG, connection constraints/porte, loop e multigraph, layout, routing, outline, grouping e
|
|
folding. Può quindi sostenere un editor ERD ricco.
|
|
|
|
Lo terrei come terza scelta: l'API è imperativa, non esiste un wrapper React ufficiale, la
|
|
virtualizzazione non è documentata e gran parte dell'accessibilità va costruita. Il progetto è
|
|
ancora pre-1.0. Il costo di integrazione e manutenzione sarebbe maggiore di X6.
|
|
|
|
Fonti: [licenza e repository](https://github.com/maxGraph/maxGraph),
|
|
[guida Vite/TypeScript](https://maxgraph.github.io/maxGraph/docs/getting-started/) e
|
|
[gestione della complessità](https://maxgraph.github.io/maxGraph/docs/usage/group-and-complexity-management/).
|
|
|
|
### Cytoscape.js
|
|
|
|
Cytoscape.js e molte estensioni sono MIT, senza tier professionale. È ottimo per grandi grafi,
|
|
filtri, selezioni e algoritmi di rete. Il rendering Canvas è però meno naturale per schede-tabella
|
|
ricche, testo selezionabile e handle collegati alle singole colonne. Inoltre l'adapter
|
|
`cytoscape.js-elk` non passa le porte a ELK né usa le route degli archi: non risolve da solo il
|
|
problema delle foreign key per colonna.
|
|
|
|
È appropriato per una vista di dipendenze ad alto livello, non come renderer ERD principale.
|
|
L'estensione `cytoscape-svg` è GPL-3.0; in un prodotto che non vuole assorbire quel vincolo è
|
|
preferibile una pipeline Graphviz/Viz.js o un generatore SVG proprio.
|
|
|
|
Fonti: [Cytoscape.js](https://github.com/cytoscape/cytoscape.js),
|
|
[adapter ELK](https://github.com/cytoscape/cytoscape.js-elk) e
|
|
[cytoscape-svg](https://github.com/kinimesi/cytoscape-svg).
|
|
|
|
### Liam ERD
|
|
|
|
Liam ERD è Apache-2.0, self-hostable e già orientato al problema: pan/zoom, ricerca, filtro,
|
|
command palette e modalità `TABLE_NAME`, `KEY_ONLY`, `ALL_FIELDS`. La documentazione dichiara
|
|
supporto a schemi con oltre cento tabelle. La CLI può generare un'app Vite statica.
|
|
|
|
Non userei però direttamente `@liam-hq/erd-core` dentro ThothII: il maintainer lo definisce una
|
|
dipendenza interna, ne sconsiglia l'uso diretto e avverte che l'API può cambiare; il package è
|
|
ancora 0.x. Inoltre occorre verificare la compatibilità con la versione React di ThothII e la
|
|
fedeltà delle foreign key composite. Liam è quindi un ottimo benchmark UX, una CLI per una vista
|
|
separata o una base da forkare consapevolmente, non l'interfaccia stabile su cui fondare il
|
|
prodotto.
|
|
|
|
Fonti: [repository Liam](https://github.com/liam-hq/liam),
|
|
[README di erd-core](https://github.com/liam-hq/liam/blob/main/frontend/packages/erd-core/README.md),
|
|
[funzioni UI](https://liambx.com/docs/ui-features) e [CLI](https://liambx.com/docs/cli).
|
|
|
|
### Sprotty/GLSP
|
|
|
|
Sprotty e Eclipse GLSP sono EPL-2.0 e offrono un'infrastruttura seria per diagrammi SVG,
|
|
layout e protocolli client/server. Sono pensati per strumenti di modeling estensibili, con
|
|
dependency injection e un'architettura più ampia di un viewer. Restano una soluzione OSS valida,
|
|
ma sproporzionata per questa esigenza salvo che ThothII evolva in un vero editor di modelli.
|
|
|
|
Fonti: [Sprotty](https://github.com/eclipse-sprotty/sprotty) ed
|
|
[Eclipse GLSP](https://eclipse.dev/glsp/documentation/overview/).
|
|
|
|
## 4. Renderer complementari, non fondazioni del viewer
|
|
|
|
### Graphviz e Viz.js
|
|
|
|
Graphviz è EPL-2.0; `@viz-js/viz`, il port WebAssembly utilizzabile nel browser, è MIT. Graphviz
|
|
produce SVG di alta qualità, supporta label HTML-like e porte e rimane molto utile per export,
|
|
stampa o una vista read-only. Non fornisce però da solo ricerca, filtri, livelli di dettaglio,
|
|
editing o gestione dello stato applicativo.
|
|
|
|
Lo userei come renderer di export alternativo, non come UI primaria. Se il layout a schermo
|
|
deve corrispondere esattamente all'export, è preferibile generare l'SVG direttamente dalla
|
|
geometria ELK invece di mantenere due motori di layout indipendenti.
|
|
|
|
Fonti: [licenza Graphviz](https://graphviz.org/license/),
|
|
[formati SVG](https://graphviz.org/docs/outputs/svg/) e
|
|
[Viz.js](https://github.com/mdaines/viz-js).
|
|
|
|
### Mermaid.js e librerie di pan/zoom
|
|
|
|
Mermaid.js è MIT e non ha feature del renderer open source bloccate. **Mermaid Chart** è invece
|
|
un servizio commerciale distinto e il suo piano gratuito ha limiti: non va confuso con la
|
|
libreria self-hosted.
|
|
|
|
Si può aggiungere navigazione a un SVG Mermaid con `@panzoom/panzoom` (MIT) o `d3-zoom` (ISC),
|
|
entrambi senza tier Pro. Questo migliora l'esperienza corrente, ma non supera i limiti strutturali
|
|
del diagramma ER Mermaid: interazioni a livello di tabella, controllo ridotto delle porte e del
|
|
routing, assenza di semantic zoom e difficoltà crescente su schemi molto grandi.
|
|
|
|
Mermaid resta adatto a preview e documentazione, non al viewer finale.
|
|
|
|
Fonti: [Mermaid.js](https://github.com/mermaid-js/mermaid),
|
|
[distinzione da Mermaid Chart](https://mermaid.ai/open-source/ecosystem/mermaid-chart.html),
|
|
[Panzoom](https://github.com/timmywil/panzoom) e [d3-zoom](https://github.com/d3/d3-zoom).
|
|
|
|
### Python
|
|
|
|
SchemaSpy ed ERAlchemy sono open source e possono generare documentazione o grafi attraverso
|
|
Graphviz, ma non sostituiscono il componente interattivo React. Python è utile lato backend per
|
|
normalizzare metadati o produrre artefatti batch; pan/zoom, selezione, ricerca e dettagli restano
|
|
responsabilità del browser. Aggiungere un servizio Python solo per disegnare l'ERD non porta un
|
|
vantaggio architetturale a ThothII.
|
|
|
|
## 5. Soluzioni escluse
|
|
|
|
### JointJS / JointJS+
|
|
|
|
Il core JointJS è MPL-2.0, ma JointJS+ è commerciale e comprende proprio molte funzioni che
|
|
servirebbero qui: PaperScroller, Navigator/minimappa, selection, clipboard, keyboard, undo/redo,
|
|
toolbar, export e layout aggiuntivi. Sarebbe tecnicamente possibile ricostruirle sul core, ma la
|
|
distanza fra OSS e Professional è troppo grande rispetto al criterio richiesto.
|
|
|
|
Fonti: [licenza](https://www.jointjs.com/license),
|
|
[confronto delle funzioni](https://www.jointjs.com/features) e
|
|
[prezzi](https://www.jointjs.com/pricing).
|
|
|
|
### GoJS e yFiles
|
|
|
|
Sono prodotti completi e maturi, ma non open source. GoJS richiede una licenza per il deployment
|
|
e mostra una filigrana senza chiave; yFiles usa licenze proprietarie, con evaluation temporanea e
|
|
licenza necessaria per la distribuzione. Non soddisfano il requisito, quindi non entrano nella
|
|
shortlist.
|
|
|
|
Fonti: [licensing GoJS](https://gojs.net/latest/intro/deployment.html) e
|
|
[licensing yFiles](https://docs.yworks.com/yfiles-html/dguide/deployment/licensing.html).
|
|
|
|
## 6. Architettura proposta per ThothII
|
|
|
|
Il frontend usa React 18 e oggi `SchemaLinkingViewer.tsx` genera Mermaid con un limite di 45
|
|
elementi. La resa corrente perde informazione: accorpa più foreign key fra la stessa coppia di
|
|
tabelle, omette i self-reference e usa cardinalità generiche. Il catalogo espone già tabelle,
|
|
colonne, chiavi primarie e relazioni con coppie ordinate di colonne, quindi può alimentare un
|
|
modello più fedele.
|
|
|
|
Propongo questa separazione:
|
|
|
|
1. **Modello renderer-neutral**: `TableNode`, `ColumnPort` e `RelationEdge` con nome del
|
|
constraint e lista ordinata delle coppie sorgente/destinazione. Non appiattire le FK composite.
|
|
2. **Snapshot API**: un endpoint coerente, per esempio
|
|
`GET /catalog/databases/:databaseId/schema-diagram`, che restituisca tabelle, colonne,
|
|
relazioni e versione del catalogo in una sola lettura, evitando la richiesta colonne N+1.
|
|
3. **Layout worker**: ELK.js in Web Worker, con porte per colonna, port constraints, route degli
|
|
archi e cache per versione del database e filtri correnti.
|
|
4. **Renderer interattivo**: X6 incapsulato in `DatabaseRelationshipDiagram.tsx`, affiancato
|
|
alla vista tabellare con un toggle List/Diagram e con riuso del drawer dei dettagli.
|
|
5. **Export**: generatore SVG separato basato sullo stesso modello e sulla geometria ELK;
|
|
Graphviz/Viz.js può essere un fallback per layout alternativi o documentazione batch.
|
|
|
|
Il catalogo non registra oggi tutti i vincoli UNIQUE né il tipo MATCH delle FK. Senza questi
|
|
dati non sempre è possibile distinguere correttamente 1:1 da 1:N. Il renderer non deve inventare
|
|
la cardinalità: deve mostrare una notazione neutra finché il metadato necessario non viene
|
|
raccolto.
|
|
|
|
### Funzioni necessarie per schemi complessi
|
|
|
|
- semantic zoom: solo nomi tabella, poi PK/FK, infine tutti i campi;
|
|
- ricerca e filtri per schema, tabella, colonna e tipo di relazione;
|
|
- modalità focus con vicinato a uno o due hop;
|
|
- evidenziazione della relazione e delle due colonne al passaggio/selezione;
|
|
- minimappa, fit selection, navigazione da tastiera e pannello dettagli;
|
|
- distinzione visiva di PK, FK, nullable, composite key, self-loop e relazioni parallele;
|
|
- layout automatico ricalcolabile, ma posizioni manuali persistibili;
|
|
- rendering progressivo o virtuale e fallback tabellare sempre disponibile;
|
|
- export dell'intero schema e dell'area filtrata in SVG/PNG.
|
|
|
|
## 7. Proof of concept consigliato
|
|
|
|
Un POC breve dovrebbe usare **X6 + ELK.js** su tre dataset sintetici: circa 30, 150 e 500
|
|
tabelle, includendo FK composite, più FK tra la stessa coppia, self-loop, tabelle isolate e hub
|
|
ad alto grado.
|
|
|
|
I criteri di accettazione dovrebbero misurare:
|
|
|
|
- tempo di layout nel worker e tempo al primo frame interattivo;
|
|
- fluidità di pan/zoom e uso memoria sul caso da 500 tabelle;
|
|
- correttezza di porte, archi paralleli, self-loop e FK composite;
|
|
- leggibilità nelle tre soglie di semantic zoom;
|
|
- navigazione completa da tastiera e comportamento con screen reader;
|
|
- qualità e portabilità dell'SVG esportato;
|
|
- assenza di codice, esempi o componenti soggetti a licenza commerciale.
|
|
|
|
Se X6 non raggiunge il livello di accessibilità richiesto senza un costo eccessivo, il confronto
|
|
finale va fatto con React Flow + lo stesso adapter ELK e lo stesso modello dati. In questo modo
|
|
si cambia renderer senza rifare API, semantica delle relazioni o pipeline di export.
|