Files
ThothII/docs/research/2026-08-31-browser-erd-library-options.md
T
Codex 076c9742c5 feat: consolidate database management work
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.
2026-09-01 14:46:55 +02:00

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.