Manuale Pratico di Linguaggio DOT (Graphviz) per sviluppatori e analisti
Per sviluppatori, analisti e software architect che vogliono produrre diagrammi professionali, chiari e belli da vedere
Introduzione
Nel lavoro quotidiano di chi sviluppa software — che tu sia analista, sviluppatore backend, frontend, database expert o architect — arriva sempre il momento in cui un diagramma diventa fondamentale.
Serve quando devi:
- spiegare un flusso complesso,
- disegnare la pipeline CI/CD,
- raccontare l’architettura a un nuovo collega,
- analizzare dipendenze tra moduli,
- documentare un database,
- preparare una presentazione tecnica,
- ragionare su un refactoring,
- identificare colli di bottiglia.
Graphviz e il suo linguaggio DOT sono strumenti ideali: testuali (versionabili), veloci da scrivere, belli da renderizzare, flessibili.
Installazione Graphviz
Prima di iniziare, assicurati di avere Graphviz installato:
- Windows: Scarica l’installer da graphviz.org/download o usa
winget install graphviz - macOS:
brew install graphviz - Linux:
sudo apt install graphviz(Debian/Ubuntu) osudo dnf install graphviz(Fedora/RHEL)
Verifica l’installazione con dot -V — dovresti vedere la versione installata.
Questo manuale vuole essere la guida definitiva per chi nel software vuole usare il linguaggio DOT al massimo. Troverai:
- spiegazione approfondita degli attributi con tutte le opzioni rilevanti,
- esempi completi, riutilizzabili e commentati,
- best practices per grafici professionali,
- suggerimenti sull’uso dei layout engine,
- scenari concreti dal mondo dello sviluppo (design, refactoring, analisi, architettura).
Il linguaggio DOT: basi solide
DOT descrive grafi con una sintassi molto semplice:
digraph Nome {
nodoA -> nodoB;
}
Oppure non diretto:
graph Nome {
nodoA -- nodoB;
}
Concetti chiave:
- nodi: entità (funzioni, oggetti, microservizi, tabelle DB)
- archi: relazioni, chiamate, flussi
- attributi: aspetto visuale o metadati
Quick Start: il tuo primo diagramma in 30 secondi
Testa subito online (senza installare nulla)
Tutti gli esempi di questo articolo sono direttamente testabili online usando Edotor.net:
-
Vai su edotor.net
-
Copia il codice DOT di qualsiasi esempio da questo articolo
-
Incollalo nell’area di sinistra (sostituendo il codice esistente)
-
Vedi il rendering immediato nell’area di destra
È il modo più veloce per sperimentare senza installare Graphviz. Quando sei pronto per la produzione, installa Graphviz localmente.
Primo esempio da provare
Copia questo codice e testalo su edotor.net:
digraph MyFirstGraph {
node [shape=box, style=rounded, fillcolor=lightblue, style="rounded,filled"];
edge [color=blue];
Start -> Process -> End;
Process -> Error [style=dashed, label="on failure"];
Error -> Process [label="retry"];
}
Oppure usa la command line locale
Crea un file hello.dot con il codice sopra e genera l’immagine SVG:
dot -Tsvg hello.dot -o hello.svg
Apri hello.svg nel browser e vedrai il tuo primo flowchart! Da qui in poi, tutto si basa su variazioni e combinazioni di questi concetti.
Attributi fondamentali (con opzioni complete)
Gli attributi possono essere applicati globalmente a:
graphnodeedge- a singoli elementi
Esempio:
digraph demo {
graph [rankdir=LR];
node [shape=box];
edge [color=grey];
A -> B;
}
Di seguito l’elenco degli attributi più importanti con le loro opzioni più utili in ambito software.
Attributi dei nodi (node)
shape — forma del nodo
Opzioni utili:
boxellipsecirclediamond(decisioni nei flow)record(class diagrams, strutture dati)plaintext(contenuti completamente personalizzati con HTML-label)notefolder(disponibile in alcune build)
Esempio:
node [shape=box];
Usi tipici:
- box → moduli software
- ellipse → stati
- diamond → decisioni
style — stile grafico
Opzioni comuni:
filleddasheddottedboldrounded- combinazioni:
"filled,rounded"
Esempio:
node [style="filled,rounded"];
fillcolor — colore di riempimento
Formati:
- nomi (e.g.
"lightgrey") - HEX (e.g.
"#AABBCC") - RGB (
"#rrggbb") - HSL (in alcune build)
fontname, fontcolor, fontsize
Es.:
node [fontname="Arial", fontsize=12, fontcolor="#333333"];
margin
Margine interno del nodo.
node [margin="0.2,0.1"];
Attributi degli archi (edge)
arrowsize
Scala della freccia. Default ~1.0
edge [arrowsize=0.8];
arrowhead / arrowtail
Opzioni utili:
normalempty(triangolo vuoto, molto leggibile)diamondonormalcrow(diagrammi ER)teenone
style e color
edge [style=dashed, color="#888888"];
label
Etichetta dell’arco.
A -> B [label="calls"];
Attributi del grafo (graph)
rankdir
Direzione del layout (solo dot):
TB(top → bottom)BT(bottom → top)LR(left → right)RL(right → left)
Es.:
graph [rankdir=LR];
splines
Controlla la forma degli archi:
true(default)false(linee dritte)polylineortho(ortogonali, ottimo per diagrammi “da architetto”)
ranksep, nodesep
Spazi orizzontali/verticali.
graph [ranksep=0.8, nodesep=0.6];
Layout Engines: scegliere quello giusto
Graphviz non ha un solo motore di rendering: ne offre diversi, ognuno ottimizzato per tipologie specifiche di grafo. Scegliere l’engine giusto significa ottenere diagrammi più leggibili e professionali.
Si specifica l’engine usando il flag -K da CLI:
dot -Kdot -Tsvg file.dot -o output.svg
dot -Kneato -Tsvg file.dot -o output.svg
Oppure nel file DOT stesso:
graph G {
layout=neato;
// ...
}
Di seguito i principali engine e quando usarli.
Motori di layout disponibili
dot — layout gerarchico (default)
Cosa fa: Dispone i nodi in modo gerarchico, seguendo la direzione degli archi. È il più usato.
Perfetto per:
- Flowchart e diagrammi di flusso
- Pipeline CI/CD
- Call graph (grafo delle chiamate tra funzioni)
- Architetture a layer (presentation → business → data)
- Processi sequenziali
- Diagrammi di dipendenza con direzione chiara
Esempio di comando:
dot -Tsvg flowchart.dot -o flowchart.svg
Quando evitarlo: Se il grafo non ha una struttura gerarchica chiara o contiene molti cicli.
neato — layout a forza fisica
Cosa fa: Posiziona i nodi simulando forze fisiche (repulsione/attrazione), generando layout organici e simmetrici.
Utile per:
- Grafi non diretti (senza frecce)
- Reti concettuali e mappe mentali
- Relazioni non gerarchiche tra entità
- Grafi piccoli/medi dove vuoi evidenziare cluster naturali
Esempio di comando:
dot -Kneato -Tsvg concepts.dot -o concepts.svg
Quando evitarlo: Con grafi molto grandi (>100 nodi) o fortemente direzionali.
fdp — force-directed placement
Cosa fa: Simile a neato, ma usa un algoritmo diverso (Fruchterman-Reingold). Generalmente più veloce su grafi medi.
Utile per:
- Grafi non diretti di dimensioni medie
- Visualizzazioni di social network (amicizie, collegamenti)
- Analisi di dipendenze senza direzione forte
Esempio di comando:
dot -Kfdp -Tsvg network.dot -o network.svg
sfdp — scalable force-directed placement
Cosa fa: Versione ottimizzata di fdp per grafi molto grandi (migliaia di nodi).
Ottimo per:
- Analisi delle dipendenze su codebase complesse
- Grafo delle classi di un progetto enterprise
- Reti complesse (infrastrutture, microservizi)
- Quando
neatoofdpsono troppo lenti
Esempio di comando:
dot -Ksfdp -Tsvg dependencies.dot -o dependencies.svg
Tip: Usa sfdp quando hai più di 100-200 nodi.
circo — layout circolare
Cosa fa: Dispone i nodi in cerchi concentrici attorno a un nodo centrale.
Ideale per:
- Visualizzare moduli satellite attorno a un core centrale
- Architetture hub-and-spoke
- Rappresentare componenti che dipendono da un servizio centrale
Esempio di comando:
dot -Kcirco -Tsvg modules.dot -o modules.svg
Esempio pratico: Un servizio API centrale con 10 microservizi che lo chiamano.
twopi — layout radiale
Cosa fa: Crea un layout ad albero radiale, con il nodo radice al centro e i livelli che si espandono verso l’esterno.
Perfetto per:
- Alberi gerarchici (org chart, file system)
- Tassonomie
- Mind map strutturate
- Visualizzare espansioni da un punto centrale
Esempio di comando:
dot -Ktwopi -Tsvg tree.dot -o tree.svg
Come scegliere in pratica
| Tipo di grafo | Engine consigliato |
|---|---|
| Flowchart, pipeline, processi | dot |
| Architetture layered | dot |
| Call graph, dependency tree | dot |
| Rete concettuale, brainstorming | neato |
| Social network, grafi medi non diretti | fdp |
| Grafi grandi (>200 nodi) | sfdp |
| Hub centrale con satelliti | circo |
| Alberi gerarchici, org chart | twopi |
Regola pratica: Se hai frecce e una direzione chiara → usa dot. Altrimenti prova neato o fdp.
Tipologie di grafici e quando usarli nella vita reale di un developer
Questa è la sezione più corposa. Per ogni tipo di grafico troverai:
- Quando usarlo nella vita reale
- Attributi consigliati
- Esempio completo
Flowchart: capire il comportamento
Nel lavoro quotidiano capita spesso di dover spiegare un flusso decisionale complesso: una procedura di validazione con molteplici branch, un processo di onboarding utente, o semplicemente il comportamento di una funzione con tanti if/else annidati. Il flowchart è lo strumento ideale per questo.
Quando ti serve un flowchart:
Sei in fase di analisi requisiti e devi capire tutte le casistiche possibili. Stai debuggando una logica che sembra impazzita e vuoi vedere visivamente dove il flusso si biforca. Devi scrivere documentazione per un processo aziendale complesso. Stai facendo onboarding di un nuovo collega e vuoi mostrargli come funziona il sistema di autenticazione.
Il flowchart mostra visivamente le decisioni (rombi), i processi (rettangoli arrotondati), e il flusso logico (frecce). È immediato, chiaro, universale.
Attributi consigliati per flowchart professionali:
Usa rankdir=TB (top-to-bottom) per seguire la convenzione standard dei flowchart. Usa shape=diamond per i nodi decisionali (le condizioni if/else). Usa style=rounded per gli step di processo, così si distinguono dai rombi. Usa colori tenui (fillcolor) per evidenziare start (verde chiaro), errori (rosso chiaro), fine (grigio).
Esempio completo:
digraph Flow {
graph [rankdir=TB, nodesep=0.6];
node [fontname="Arial"];
Start [shape=oval, style=filled, fillcolor="#C1F2C7"];
Check [shape=diamond, label="Valid input?"];
Process [shape=box, style="filled,rounded", fillcolor="#F0F4FF"];
Error [shape=box, fillcolor="#FFEAEA", style=filled];
End [shape=oval, fillcolor="#DDDDDD", style=filled];
Start -> Check;
Check -> Process [label="yes"];
Check -> Error [label="no"];
Process -> End;
}
Cosa fa questo esempio: Parte da uno stato iniziale (Start), passa attraverso una validazione (Check), e si biforca in due percorsi: successo (Process) o errore (Error). Usa colori per rendere immediatamente chiaro cosa è positivo e cosa negativo.
Grafi di dipendenza: capire il software come sistema
Quando lavori su un progetto esistente, una delle prime domande che ti fai è: “Cosa dipende da cosa?” Se devi fare refactoring di un modulo, vuoi sapere chi lo usa. Se devi aggiornare una libreria, vuoi capire l’impatto a cascata. Se stai progettando una nuova feature, vuoi vedere dove si inserisce nell’architettura esistente.
Il grafo delle dipendenze è la mappa del tuo sistema. Mostra moduli, servizi, classi, o microservizi come nodi, e le dipendenze come frecce. È fondamentale per:
Refactoring sicuro: Prima di toccare un modulo, vedi chi lo chiama. Analisi di impatto: Se modifichi un’API, vedi immediatamente tutti i consumatori. Documentazione automatica: Genera il grafo dal codice (con tool come Doxygen, Madge, o script custom) e mantienilo aggiornato. Dependency injection mapping: Visualizza come Spring, Angular o .NET iniettano le dipendenze.
Attributi utili:
Usa rankdir=LR (left-to-right) per avere un flusso orizzontale, tipico delle dependency chain. Usa shape=box per i moduli/servizi. Usa color e penwidth per evidenziare dipendenze critiche o problematiche (es. dipendenze circolari in rosso). Usa style=dashed per dipendenze opzionali o deboli.
Esempio:
digraph Deps {
graph [rankdir=LR];
node [shape=box, style=filled, fillcolor="#F7FAFF", fontname="Inter"];
edge [color="#555555"];
UI -> API;
API -> Auth;
API -> UserService;
UserService -> Database [color="#FF5555", penwidth=2, label="critical"];
}
Cosa fa questo esempio: Mostra una classica architettura web: UI chiama API, API dipende da Auth e UserService, UserService parla col Database. La dipendenza critica (UserService → Database) è evidenziata in rosso con linea spessa: se il DB va giù, tutto crolla.
Architettura software: cluster e layer
Quando progetti un’architettura o documenti quella esistente, hai bisogno di mostrare raggruppamenti logici e separazione dei livelli. Un sistema web tipico ha Presentation, Business, Data. Un progetto a microservizi ha boundary logici (edge, services, datastores). Un sistema legacy potrebbe avere moduli separati per dominio.
Il diagramma di architettura con cluster ti permette di:
Visualizzare layer separati: Presentation Layer, Business Layer, Data Layer. Ogni layer è un box colorato che contiene i suoi componenti. Mostrare boundary dei microservizi: Edge Gateway, Services, Datastores. Ogni boundary è un cluster. Documentare moduli legacy: Isola i moduli per responsabilità (Auth, Orders, Reporting) così è chiaro chi fa cosa. Presentare l’architettura a stakeholder: Un diagramma layered è universale e comprensibile anche dai non-tecnici.
Attributi utili:
Usa subgraph cluster_* per creare raggruppamenti visivi. Usa compound=true per permettere archi che attraversano i cluster. Usa splines=ortho per linee ortogonali, tipiche dei diagrammi “da architetto”. Usa shape=cylinder per i database, così sono immediatamente riconoscibili.
Esempio architettura layered:
digraph Architecture {
graph [
rankdir=TB,
ranksep=0.8,
nodesep=0.6,
overlap=false,
splines=true,
sep="+0.2"
];
node [shape=box, style="rounded,filled", fillcolor="#F0F4FF", fontname="Arial"];
subgraph cluster_presentation {
label="Presentation Layer";
style=filled;
color=lightgrey;
fillcolor="#E8F4F8";
UI;
}
subgraph cluster_business {
label="Business Layer";
style=filled;
color=lightgrey;
fillcolor="#FFF4E6";
ServiceA; ServiceB;
}
subgraph cluster_data {
label="Data Layer";
style=filled;
color=lightgrey;
fillcolor="#F0F0F0";
DB [shape=cylinder, fillcolor="#D0E8FF"];
}
UI -> ServiceA;
UI -> ServiceB;
ServiceA -> DB;
ServiceB -> DB;
}
Cosa fa questo esempio: Definisce tre layer con subgraph cluster_*. Presentation contiene UI, Business contiene due servizi, Data contiene il DB (con shape=cylinder). Le frecce mostrano il flusso: UI → Services → DB. L’architettura è immediatamente comprensibile.
Microservices Map: capire un ecosistema distribuito
Se lavori con microservizi, hai decine di servizi che comunicano tra loro: API Gateway, servizi di dominio (Orders, Users, Notifications), database, code, cache. Quando arriva un incident in produzione, la prima domanda è: “Chi parla con chi? Dov’è il collo di bottiglia?”
La mappa dei microservizi è il tuo GPS nel caos distribuito. Ti serve per:
Design architetturale: Prima di scrivere codice, disegna la mappa. Identifica i boundary logici (edge, core services, datastores). Documentazione API: Mostra chi chiama quale servizio e attraverso quale protocollo (REST, gRPC, eventi). Analisi di performance: Durante un incident, guardi la mappa e capisci subito se il problema è nell’API Gateway, in un servizio specifico, o nel DB condiviso. Post-mortem: Dopo un down, la mappa aiuta a ricostruire la catena di fallimento.
Attributi utili:
Usa cluster per separare i boundary logici (Edge, Services, Data). Usa shape=cylinder per database, shape=box per servizi. Usa label sugli archi per specificare il protocollo (HTTP, gRPC, Kafka). Usa shape=plaintext con HTML table per servizi complessi con porte multiple.
Esempio:
digraph Micro {
graph [rankdir=LR, splines=true];
node [shape=plaintext];
subgraph cluster_gateway {
label="Edge";
Gateway [label="API Gateway"];
}
subgraph cluster_services {
label="Services";
Order; User; Notification;
}
subgraph cluster_data {
label="Datastores";
DB [shape=cylinder, label="Postgres"];
Cache [shape=box, label="Redis"];
}
Gateway -> User;
Gateway -> Order;
Order -> DB;
User -> Cache;
Notification -> User;
}
Cosa fa questo esempio: Organizza l’ecosistema in tre cluster: Edge (Gateway), Services (Order, User, Notification), Datastores (DB, Cache). Le frecce mostrano le chiamate: Gateway → User/Order, Order → DB, User → Cache. È la mappa completa del sistema.
Diagrammi di stato: modellare comportamenti
Molti sistemi hanno un comportamento a stati: una richiesta HTTP può essere Idle, Loading, Success, Error. Un ordine e-commerce passa da Draft → Pending → Confirmed → Shipped. Un sistema embedded ha stati di accensione, standby, operativo, errore. Un’interfaccia UI ha stati di caricamento, pronta, errore.
Il diagramma di stato modella questi comportamenti come un grafo: ogni nodo è uno stato, ogni arco è una transizione etichettata con l’evento che la causa. È fondamentale per:
Progettare macchine a stati: Prima di implementare lo state pattern nel codice, disegna il diagramma. Documentare protocolli: I protocolli di rete (TCP, WebSocket, custom) hanno state machine precise. Il diagramma le rende esplicite. Modellare UI/UX flow: Quando progetti un’app, disegna gli stati dell’interfaccia: caricamento, pronta, errore, vuota. Debug di sistemi embedded: Se un device si blocca in uno stato, il diagramma ti aiuta a capire quali transizioni mancano.
Attributi utili:
Usa shape=circle per gli stati (convention standard delle FSM). Usa rankdir=LR per layout orizzontale, tipico degli state diagram. Usa label sugli archi per mostrare l’evento che causa la transizione. Usa shape=doublecircle per stati finali/terminali.
Esempio:
digraph States {
graph [rankdir=LR];
node [shape=circle, fontsize=12];
Idle -> Loading [label="start"];
Loading -> Ready [label="success"];
Loading -> Error [label="fail"];
Error -> Idle [label="reset"];
Ready -> Idle [label="finish"];
}
Cosa fa questo esempio: Modella il ciclo di vita di una richiesta asincrona: parte da Idle, va in Loading quando parte la chiamata, poi Success o Error a seconda del risultato. Da Error può tornare Idle con un reset. Da Ready può tornare Idle al completamento. Ogni transizione è etichettata con l’evento che la causa.
Diagrammi delle classi con record
Quando progetti un sistema object-oriented, o vuoi documentare il dominio di un’applicazione, il diagramma delle classi è lo standard. Mostra classi con attributi e metodi, e le relazioni tra loro (ereditarietà, composizione, dipendenza).
DOT non è UML, ma con shape=record ottieni qualcosa di molto simile e perfettamente leggibile. È utile per:
Progettazione iniziale: Prima di scrivere il codice, disegna le classi principali del dominio. Identifica attributi, metodi, relazioni. Refactoring: Quando devi ristrutturare un modulo, disegna lo stato attuale e quello desiderato. Confronta i due diagrammi. Domain-Driven Design (DDD): Modella le entità, value object, aggregati. Il diagramma aiuta a visualizzare i boundary del dominio. Documentazione: Genera il diagramma automaticamente dal codice (con tool come Doxygen) e mantienilo aggiornato.
Attributi utili:
Usa shape=record per creare box con sezioni separate (nome classe | attributi | metodi). Usa fontname="Courier New" o monospace per renderlo simile a codice. Usa arrowhead=onormal per ereditarietà (freccia vuota, standard UML). Usa \l (backslash-l) per allineare il testo a sinistra dentro i record.
Esempio:
digraph Classes {
node [shape=record, fontname="Courier New"];
Person [label="{Person|name: string\l age: int\l|greet()}"];
Employee [label="{Employee|id: int\l role: string\l|work()}"];
Person -> Employee [arrowhead="onormal"];
}
Cosa fa questo esempio: Definisce due classi: Person (con attributi nome, età, metodo greet) e Employee (con id, ruolo, metodo work). Person è la superclasse di Employee (freccia con arrowhead=onormal, standard UML per l’ereditarietà). Il \l allinea il testo a sinistra dentro i record.
Diagrammi ER professionali con HTML-label
Se lavori con database, prima o poi devi disegnare lo schema delle tabelle: chiavi primarie, foreign key, relazioni 1:N o N:N. Il diagramma Entity-Relationship (ER) è lo standard per questo.
DOT supporta tabelle HTML dentro i nodi con shape=plaintext, permettendoti di creare diagrammi ER puliti e professionali. È fondamentale per:
Progettazione database: Prima di scrivere le migration, disegna lo schema. Identifica le entità, gli attributi, le relazioni. Valida il design con il team. Data modeling: Quando progetti un nuovo modulo, parti dal modello dati. Il diagramma ER ti aiuta a ragionare su normalizzazione e performance. Reverse engineering: Quando erediti un DB legacy senza documentazione, genera il diagramma ER dal DB stesso (con tool come SchemaSpy o pg_dump + script) per capire la struttura. Documentazione: Il diagramma ER è comprensibile anche dai non-developer (product manager, analisti business).
Attributi utili:
Usa shape=plaintext per abilitare HTML label. Usa <TABLE> HTML per creare box strutturati con header (nome tabella) e righe (campi). Usa arrowhead=crow per relazioni 1:N (standard dei diagrammi ER). Usa label="1:N" sugli archi per rendere esplicita la cardinalità.
Esempio:
digraph ER {
node [shape=plaintext];
User [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD><B>User</B></TD></TR>
<TR><TD>id PK</TD></TR>
<TR><TD>email</TD></TR>
</TABLE>
>];
Order [label=<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD><B>Order</B></TD></TR>
<TR><TD>id PK</TD></TR>
<TR><TD>user_id FK</TD></TR>
</TABLE>
>];
User -> Order [label="1:N", arrowhead="crow"];
}
Cosa fa questo esempio: Definisce due tabelle (User e Order) usando HTML. Ogni tabella ha un header in grassetto e righe per i campi. La freccia con arrowhead=crow e label="1:N" mostra la relazione: un User ha molti Order (chiave esterna user_id in Order).
Diagrammi CI/CD Pipeline
Se lavori in un team che fa continuous integration e deployment, hai una pipeline che esegue step automatici: build, test, analisi statica, packaging, deploy, monitoraggio. Quando qualcosa si rompe, o quando fai onboarding di un nuovo developer, serve un diagramma che mostri l’intera pipeline.
Il diagramma CI/CD visualizza il flusso automatico dal commit al deploy. È utile per:
DevOps e SRE: Documentare la pipeline esistente. Identificare colli di bottiglia (quale step richiede più tempo?). Onboarding team: Un nuovo developer guarda il diagramma e capisce subito cosa succede dopo un git push. Ottimizzazione: Vuoi parallelizzare alcuni step? Il diagramma ti mostra quali dipendono da quali. Debugging: La pipeline fallisce? Il diagramma ti aiuta a capire a che step e perché (freccia tratteggiata per i retry).
Attributi utili:
Usa rankdir=LR per flusso orizzontale (tipico delle pipeline). Usa shape=box con style=filled per gli step, colorandoli per tipo (build=blu, test=verde, deploy=rosso). Usa style=dotted con label="retry" per mostrare meccanismi di retry automatico. Usa label sugli archi per indicare condizioni (es. “only on master branch”).
Esempio:
digraph CICD {
graph [rankdir=LR];
node [shape=box, style=filled, fillcolor="#F8FBFF"];
Code -> Build -> Test -> Package -> Deploy -> Monitor;
Test -> Build [style=dotted, label="retry"];
}
Cosa fa questo esempio: Mostra una pipeline classica: Code → Build → Test → Package → Deploy → Monitor. La freccia tratteggiata da Test a Build mostra un retry automatico in caso di fallimento dei test. È un flusso lineare, immediatamente comprensibile.
Sottrarre complessità: mappe concettuali e analisi
Non tutti i diagrammi devono essere gerarchici o direzionali. A volte hai bisogno di visualizzare relazioni concettuali senza una struttura fissa: durante un brainstorming, quando fai design collettivo con il team, o quando vuoi mappare le dipendenze concettuali tra aree tecnologiche.
La mappa concettuale non ha un “inizio” o una “fine”: è una rete di nodi collegati organicamente. È utile per:
Brainstorming: Parti da un’idea centrale e aggiungi nodi collegati mentre discuti con il team. La mappa cresce naturalmente. Design collettivo: Durante una sessione di design, mappa i componenti e le loro relazioni. Non sai ancora la gerarchia, ma sai che “Backend parla con Database e API”. Analisi delle dipendenze concettuali: Vuoi capire quali aree tecnologiche sono collegate (es. Security → Logging → Observability). Documentazione di alto livello: Per stakeholder non-tecnici, una mappa concettuale è più accessibile di un grafo gerarchico.
Attributi utili:
Usa engine neato o fdp invece di dot, per ottenere un layout organico basato su forze fisiche. Usa shape=ellipse per nodi concettuali (non processi). Usa style=filled con colori tenui per raggruppamenti visivi. Usa grafi non diretti (graph invece di digraph) se le relazioni sono bidirezionali.
Esempio con engine neato:
graph Concepts {
layout=neato;
node [shape=ellipse, style=filled, fillcolor="#EFEFFF"];
Backend -- Database;
Backend -- API;
API -- Security;
Security -- Logging;
Logging -- Observability;
}
Evitare sovrapposizioni: overlap e splines
Uno dei problemi più comuni quando si disegnano grafi complessi è la sovrapposizione di frecce, testi e nodi. Graphviz offre attributi specifici per controllare questo comportamento e rendere i diagrammi più leggibili.
Il problema: sovrapposizioni indesiderate
Quando hai molti nodi e frecce, specialmente con layout gerarchici o con splines=ortho, le frecce possono sovrapporsi ai label dei cluster o ai nodi. Ecco un esempio tipico del problema:
digraph OverlapProblem {
graph [rankdir=TB, splines=ortho];
node [shape=box, style=rounded];
subgraph cluster_a {
label="Component A";
A1; A2;
}
subgraph cluster_b {
label="Component B";
B1; B2;
}
subgraph cluster_c {
label="Component C";
C1; C2;
}
A1 -> B1;
A2 -> B2;
B1 -> C1;
B2 -> C2;
A1 -> C1;
}
Problema: Con splines=ortho le frecce possono attraversare i label dei cluster rendendo il diagramma confuso.
La soluzione: overlap e splines
Graphviz offre diversi attributi per risolvere questo problema:
overlap — evita sovrapposizioni tra nodi
graph [overlap=false];
Opzioni principali:
falseovoronoi— evita sovrapposizioni (migliore qualità, più lento)scale— scala il grafo per evitare sovrapposizioniscalexy— scala con proporzioni diverse su X e Ytrue(default) — permette sovrapposizioni
splines — controlla la forma degli archi
graph [splines=true];
Opzioni:
trueospline— curve smooth che evitano nodi (raccomandato)curved— archi leggermente curvipolyline— linee spezzateortho— linee ortogonali (può causare sovrapposizioni!)lineofalse— linee dritte
sep — margine extra tra elementi
graph [sep="+0.2"];
Aggiunge margine tra nodi e archi (in pollici). Il + significa “aggiungi al valore di default”.
ranksep e nodesep — spaziatura tra livelli e nodi
graph [ranksep=0.8, nodesep=0.6];
Aumenta lo spazio verticale (ranksep) e orizzontale (nodesep) tra gli elementi.
Esempio migliorato
Ecco lo stesso grafo con attributi ottimizzati per evitare sovrapposizioni:
digraph OverlapSolved {
graph [
rankdir=TB,
ranksep=0.8,
nodesep=0.6,
overlap=false,
splines=true,
sep="+0.2"
];
node [shape=box, style=rounded];
subgraph cluster_a {
label="Component A";
style=filled;
fillcolor="#E8F4F8";
A1; A2;
}
subgraph cluster_b {
label="Component B";
style=filled;
fillcolor="#FFF4E6";
B1; B2;
}
subgraph cluster_c {
label="Component C";
style=filled;
fillcolor="#F0F0F0";
C1; C2;
}
A1 -> B1;
A2 -> B2;
B1 -> C1;
B2 -> C2;
A1 -> C1;
}
Risultato: Le frecce ora evitano i nodi e i label, il grafo è più spazioso e leggibile. I colori di sfondo aiutano a distinguere i cluster.
Quando usare cosa
| Scenario | Attributi consigliati |
|---|---|
| Diagrammi complessi con molti nodi | overlap=false, splines=true |
| Grafi gerarchici (flowchart, architetture) | ranksep=0.8, nodesep=0.6, splines=true |
| Grafi con cluster | overlap=false, sep="+0.2" |
| Diagrammi “da architetto” con linee dritte | splines=polyline (evita ortho) |
| Grafi piccoli e semplici | default (non serve modificare) |
Regola pratica: Inizia sempre con overlap=false e splines=true se hai più di 10 nodi o usi cluster.
Esempio completo con tutte le best practices
Ecco un esempio reale che combina tutti gli attributi consigliati: architettura a microservizi con 4 layer, molti nodi e archi, cluster colorati, spazi ottimizzati:
digraph CompleteExample {
graph [
rankdir=TB,
ranksep=1.0,
nodesep=0.7,
overlap=false,
splines=true,
sep="+0.25"
];
node [shape=box, style="rounded,filled", fillcolor="#F0F4FF", fontname="Arial", fontsize=11];
edge [color="#555555", arrowsize=0.8];
subgraph cluster_frontend {
label="Frontend Layer";
style=filled;
fillcolor="#E8F4F8";
color="#5A9FD4";
WebUI [label="Web UI"];
MobileApp [label="Mobile App"];
}
subgraph cluster_api {
label="API Gateway Layer";
style=filled;
fillcolor="#FFF4E6";
color="#E8A87C";
Gateway [label="API Gateway"];
LoadBalancer [label="Load Balancer"];
}
subgraph cluster_services {
label="Microservices Layer";
style=filled;
fillcolor="#F0F8E8";
color="#90C290";
AuthService [label="Auth Service"];
UserService [label="User Service"];
OrderService [label="Order Service"];
PaymentService [label="Payment Service"];
}
subgraph cluster_data {
label="Data Layer";
style=filled;
fillcolor="#F5F5F5";
color="#999999";
UsersDB [shape=cylinder, fillcolor="#D0E8FF", label="Users DB"];
OrdersDB [shape=cylinder, fillcolor="#D0E8FF", label="Orders DB"];
Cache [shape=box, fillcolor="#FFE8D0", label="Redis Cache"];
}
// Frontend to Gateway
WebUI -> LoadBalancer [label="HTTPS"];
MobileApp -> LoadBalancer [label="HTTPS"];
// Gateway to Services
LoadBalancer -> Gateway;
Gateway -> AuthService [label="gRPC"];
Gateway -> UserService [label="REST"];
Gateway -> OrderService [label="REST"];
// Service dependencies
OrderService -> PaymentService [label="API call"];
UserService -> AuthService [label="validate"];
PaymentService -> AuthService [label="validate"];
// Data access
AuthService -> UsersDB;
UserService -> UsersDB;
UserService -> Cache [style=dashed, label="cache"];
OrderService -> OrdersDB;
OrderService -> Cache [style=dashed, label="cache"];
}
Command line:
dot -Tsvg overlap_complete.dot -o overlap_complete.svg
Cosa dimostra questo esempio:
- overlap=false: Nessuna sovrapposizione tra nodi, anche con 13 nodi e 4 cluster
- splines=true: Frecce curve che evitano elegantemente nodi e label
- sep="+0.25": Margine extra che mantiene tutto leggibile
- ranksep=1.0, nodesep=0.7: Spaziatura generosa tra layer e nodi
- Cluster colorati: Ogni layer ha un colore distintivo per identificazione immediata
- Label sugli archi: Protocolli (HTTPS, gRPC, REST) e tipo di connessione espliciti
- Style dashed per cache: Dipendenze opzionali visualizzate diversamente
- Cylinder shape per DB: Database immediatamente riconoscibili
Questo è il template perfetto per documentare architetture complesse in modo professionale e leggibile.
Color Schemes: palette professionali pronte all’uso
Graphviz include color schemes predefiniti basati su palette professionali di ColorBrewer. Invece di scegliere colori manualmente, puoi usare palette testate per leggibilità, accessibilità e professionalità.
Come funzionano i color schemes
Usa l’attributo colorscheme per selezionare una palette, poi usa i numeri 1-9 (o più, dipende dallo schema) invece dei codici hex:
node [colorscheme=set39, fillcolor=1, color=2];
I color schemes sono organizzati in categorie:
- Qualitative (set1, set2, set3, pastel1, pastel2, dark2, paired, accent) — Per categorie distinte
- Sequential (blues3-9, greens3-9, reds3-9, purples3-9, oranges3-9) — Per valori progressivi
- Diverging (rdylgn3-11, spectral3-11, rdbu3-11) — Per dati con punto centrale
Riferimento completo: graphviz.org/docs/attrs/colorscheme/
Esempi pratici con color schemes professionali
Ogni esempio usa lo stesso diagramma (processo a 5 step) ma con palette diverse. Confronta e scegli quello più adatto al tuo caso d’uso.
Esempio 1: Set39 (qualitativo, vivace)
Ottimo per distinguere categorie diverse, presentazioni colorate, dashboard.
digraph ProcessSet39 {
graph [rankdir=LR, bgcolor=white];
node [shape=box, style="rounded,filled", colorscheme=set39, fontname=Arial];
edge [colorscheme=set39, penwidth=2];
Start [fillcolor=1, label="Start"];
Validate [fillcolor=2, label="Validate"];
Process [fillcolor=3, label="Process"];
Store [fillcolor=4, label="Store"];
Notify [fillcolor=5, label="Notify"];
Start -> Validate [color=1];
Validate -> Process [color=2];
Process -> Store [color=3];
Store -> Notify [color=4];
}
Command line:
dot -Tsvg colorscheme_set39.dot -o colorscheme_set39.svg
Esempio 2: Pastel19 (qualitativo, soft)
Colori pastello per documentazione tecnica, wiki, blog post. Meno impattante ma più leggibile a lungo.
digraph ProcessPastel {
graph [rankdir=LR, bgcolor=white];
node [shape=box, style="rounded,filled", colorscheme=pastel19, fontname=Arial, fontcolor="#333333"];
edge [colorscheme=dark28, penwidth=2];
Start [fillcolor=1, label="Start"];
Validate [fillcolor=3, label="Validate"];
Process [fillcolor=5, label="Process"];
Store [fillcolor=7, label="Store"];
Notify [fillcolor=9, label="Notify"];
Start -> Validate [color=1];
Validate -> Process [color=3];
Process -> Store [color=5];
Store -> Notify [color=7];
}
Command line:
dot -Tsvg colorscheme_pastel.dot -o colorscheme_pastel.svg
Esempio 3: Blues9 (sequential, progressione)
Ideale per mostrare intensità crescente, priorità, fasi di maturazione.
digraph ProcessBlues {
graph [rankdir=LR, bgcolor=white];
node [shape=box, style="rounded,filled", colorscheme=blues9, fontname=Arial];
edge [color="#2171B5", penwidth=2];
Start [fillcolor=2, fontcolor=black, label="Start"];
Validate [fillcolor=4, fontcolor=white, label="Validate"];
Process [fillcolor=6, fontcolor=white, label="Process"];
Store [fillcolor=8, fontcolor=white, label="Store"];
Notify [fillcolor=9, fontcolor=white, label="Notify"];
Start -> Validate -> Process -> Store -> Notify;
}
Command line:
dot -Tsvg colorscheme_blues.dot -o colorscheme_blues.svg
Esempio 4: RdYlGn9 (diverging, semaforo)
Perfetto per stati di successo/warning/errore, health checks, monitoring.
digraph ProcessStatus {
graph [rankdir=LR, bgcolor=white];
node [shape=box, style="rounded,filled", colorscheme=rdylgn9, fontname=Arial, fontcolor=black];
edge [penwidth=2, color="#666666"];
Idle [fillcolor=5, label="Idle\n(neutral)"];
Starting [fillcolor=7, label="Starting\n(ok)"];
Running [fillcolor=9, label="Running\n(good)"];
Warning [fillcolor=4, label="Warning"];
Error [fillcolor=1, label="Error"];
Idle -> Starting -> Running;
Running -> Warning [style=dashed];
Warning -> Error [style=dashed];
Running -> Idle [label="stop"];
}
Command line:
dot -Tsvg colorscheme_rdylgn.dot -o colorscheme_rdylgn.svg
Esempio 5: Paired12 (qualitativo, coppie)
Usa coppie di colori coordinati. Ottimo per confronti, versioni A/B, relazioni.
digraph ProcessPaired {
graph [rankdir=TB, bgcolor=white];
node [shape=box, style="rounded,filled", colorscheme=paired12, fontname=Arial];
edge [colorscheme=paired12, penwidth=2];
subgraph cluster_v1 {
label="Version 1.x";
style=filled;
fillcolor="#F0F0F0";
V1_Start [fillcolor=1, label="Start v1"];
V1_Process [fillcolor=1, label="Process v1"];
V1_End [fillcolor=1, label="End v1"];
V1_Start -> V1_Process -> V1_End;
}
subgraph cluster_v2 {
label="Version 2.x";
style=filled;
fillcolor="#F8F8F8";
V2_Start [fillcolor=2, label="Start v2"];
V2_Process [fillcolor=2, label="Process v2"];
V2_End [fillcolor=2, label="End v2"];
V2_Start -> V2_Process -> V2_End;
}
V1_Start -> V2_Start [label="upgrade", color=4, style=dashed];
}
Command line:
dot -Tsvg colorscheme_paired.dot -o colorscheme_paired.svg
Esempio 6: Accent8 (qualitativo, contrasti forti)
Massimo contrasto tra elementi. Per evidenziare differenze importanti.
digraph ProcessAccent {
graph [rankdir=LR, bgcolor="#F5F5F5"];
node [shape=box, style="rounded,filled", colorscheme=accent8, fontname=Arial, fontcolor=black];
edge [colorscheme=accent8, penwidth=2];
Input [fillcolor=1, label="Input"];
Parse [fillcolor=2, label="Parse"];
Transform [fillcolor=3, label="Transform"];
Validate [fillcolor=4, label="Validate"];
Output [fillcolor=5, label="Output"];
Input -> Parse [color=1];
Parse -> Transform [color=2];
Transform -> Validate [color=3];
Validate -> Output [color=4];
Validate -> Parse [color=6, label="retry", style=dashed];
}
Command line:
dot -Tsvg colorscheme_accent.dot -o colorscheme_accent.svg
Quando usare quale color scheme
| Scenario | Color Scheme Consigliato |
|---|---|
| Categorie diverse, presentazioni | set39, set28, dark28 |
| Documentazione tecnica, wiki | pastel19, pastel28 |
| Progressione, priorità, livelli | blues9, greens9, purples9, oranges9 |
| Stati (ok/warning/error) | rdylgn9, rdylbu9, spectral9 |
| Confronti, versioni A/B | paired12, paired11 |
| Massimo contrasto | accent8, set39 |
| Accessibilità (daltonismo) | set2, dark2 (ColorBrewer safe) |
Combinare color schemes
Puoi usare schemi diversi per nodi e archi:
node [colorscheme=pastel19, fillcolor=3];
edge [colorscheme=dark28, color=2];
Tip: Testa sempre i colori con ColorBrewer per verificare accessibilità e stampabilità.
Tecniche avanzate: ports, ranks, compound edges
Ports nei record — Collega archi a campi specifici di un record usando la sintassi nodo:porta:
ClassA:field1 -> ClassB:field2;
Forzare nodi allo stesso livello — Usa rank=same per posizionare più nodi sulla stessa riga orizzontale:
{ rank=same; A; B; C; }
Compound edges tra cluster — Collega cluster interi invece di singoli nodi con lhead e ltail:
edge [lhead=cluster_B, ltail=cluster_A];
Archi ortogonali — Crea archi con angoli retti per uno stile “da architetto”:
graph [splines=ortho];
Stile professionale: consigli pratici
- Usa palette coerenti.
- Evita gradienti troppo brillanti.
- Usa
Inter,ArialoRobotoper leggibilità. - Usa
orthoper archi “da architetto”. - Mantieni margini adeguati (
nodesep,ranksep). - Preferisci SVG per qualità nei blog.
- Mantieni i file DOT versionati.
Stili grafici pronti all’uso
Qui trovi 5 varianti stilistiche per lo stesso state diagram, pronte da copiare e adattare ai tuoi diagrammi. Ogni stile definisce colori, font, dimensioni e forme per creare un look coerente.
Stile 1: Corporate Blue (professionale, formale)
Palette blu/grigio, font Arial, stile pulito per presentazioni aziendali.
digraph CorporateBlue {
graph [
rankdir=LR,
bgcolor="#F8F9FA",
fontname="Arial",
fontsize=12
];
node [
shape=box,
style="rounded,filled",
fillcolor="#E3F2FD",
color="#1976D2",
fontname="Arial",
fontsize=11,
fontcolor="#1565C0",
penwidth=2
];
edge [
color="#1976D2",
fontname="Arial",
fontsize=10,
fontcolor="#424242"
];
Idle [label="Idle"];
Processing [label="Processing"];
Complete [label="Complete"];
Idle -> Processing [label="start"];
Processing -> Complete [label="finish"];
Complete -> Idle [label="reset"];
Processing -> Idle [label="cancel"];
}
Command line:
dot -Tsvg style_corporate.dot -o style_corporate.svg
Stile 2: Dark Mode (moderno, tech)
Sfondo scuro, testo chiaro, palette verde/ciano per UI moderne e developer tools.
digraph DarkMode {
graph [
rankdir=LR,
bgcolor="#1E1E1E",
fontname="Consolas",
fontsize=12
];
node [
shape=box,
style="rounded,filled",
fillcolor="#2D2D30",
color="#00D9FF",
fontname="Consolas",
fontsize=11,
fontcolor="#E0E0E0",
penwidth=2
];
edge [
color="#00D9FF",
fontname="Consolas",
fontsize=10,
fontcolor="#B0B0B0"
];
Idle [label="Idle"];
Processing [label="Processing"];
Complete [label="Complete"];
Idle -> Processing [label="start"];
Processing -> Complete [label="finish"];
Complete -> Idle [label="reset"];
Processing -> Idle [label="cancel"];
}
Command line:
dot -Tsvg style_dark.dot -o style_dark.svg
Stile 3: Warm Minimal (soft, leggibile)
Palette calda arancio/beige, sans-serif, ottimo per documentazione tecnica.
digraph WarmMinimal {
graph [
rankdir=LR,
bgcolor="#FFFBF5",
fontname="Helvetica",
fontsize=12
];
node [
shape=box,
style="rounded,filled",
fillcolor="#FFE8CC",
color="#FF8C42",
fontname="Helvetica",
fontsize=11,
fontcolor="#6B4423",
penwidth=1.5
];
edge [
color="#FF8C42",
fontname="Helvetica",
fontsize=10,
fontcolor="#8B5A3C",
penwidth=1.5
];
Idle [label="Idle"];
Processing [label="Processing"];
Complete [label="Complete"];
Idle -> Processing [label="start"];
Processing -> Complete [label="finish"];
Complete -> Idle [label="reset"];
Processing -> Idle [label="cancel"];
}
Command line:
dot -Tsvg style_warm.dot -o style_warm.svg
Stile 4: Monochrome (elegante, stampabile)
Bianco e nero, gradazioni di grigio, perfetto per stampa e documentazione formale.
digraph Monochrome {
graph [
rankdir=LR,
bgcolor="white",
fontname="Times-Roman",
fontsize=12
];
node [
shape=box,
style="rounded,filled",
fillcolor="#F5F5F5",
color="#333333",
fontname="Times-Roman",
fontsize=11,
fontcolor="#000000",
penwidth=2
];
edge [
color="#333333",
fontname="Times-Roman",
fontsize=10,
fontcolor="#666666",
penwidth=1.5
];
Idle [label="Idle"];
Processing [label="Processing"];
Complete [label="Complete"];
Idle -> Processing [label="start"];
Processing -> Complete [label="finish"];
Complete -> Idle [label="reset"];
Processing -> Idle [label="cancel"];
}
Command line:
dot -Tsvg style_mono.dot -o style_mono.svg
Stile 5: Vibrant Gradient (creativo, impattante)
Colori vivaci con sfumature, ottimo per presentazioni e slide visivamente accattivanti.
digraph VibrantGradient {
graph [
rankdir=LR,
bgcolor="#FAFAFA",
fontname="Verdana",
fontsize=12
];
node [
shape=box,
style="rounded,filled",
fillcolor="#A8E6CF:#56CCF2",
gradientangle=90,
color="#2D6A9F",
fontname="Verdana",
fontsize=11,
fontcolor="#1A3A52",
penwidth=2.5
];
edge [
color="#9B59B6",
fontname="Verdana",
fontsize=10,
fontcolor="#5B3A72",
penwidth=2
];
Idle [label="Idle"];
Processing [label="Processing", fillcolor="#FFD93D:#FF6B9D", gradientangle=90];
Complete [label="Complete", fillcolor="#6BCF7F:#4ECDC4", gradientangle=90];
Idle -> Processing [label="start"];
Processing -> Complete [label="finish"];
Complete -> Idle [label="reset"];
Processing -> Idle [label="cancel"];
}
Command line:
dot -Tsvg style_vibrant.dot -o style_vibrant.svg
Come usare questi stili
Copia il blocco graph, node, edge dello stile che preferisci e applicalo ai tuoi diagrammi. Puoi poi personalizzare:
- Colori: sostituisci i codici hex con la tua palette
- Font: usa
fontname="NomeFont"(Arial, Helvetica, Courier, Times, Verdana, Consolas) - Dimensioni:
fontsizeper testo,penwidthper spessore bordi e frecce - Shape:
box,ellipse,circle,diamond,cylinder,record - Gradienti: usa
fillcolor="color1:color2"congradientangle(solo alcuni output format)
Note sulla compatibilità dei font
I font devono essere installati sul sistema dove generi le immagini:
- Font universali (funzionano ovunque):
Arial,Helvetica,Times,Times-Roman,Courier - Font moderni (verificare disponibilità):
Verdana,Consolas,Roboto,Inter - Windows: la maggior parte dei font sono già installati
- macOS: ottimo supporto per font standard
- Linux: installa
fonts-liberationofonts-dejavuper avere Arial/Helvetica equivalenti - CI/CD: usa font base o includi i font nel container Docker
Se un font non è disponibile, Graphviz usa un fallback (solitamente Times). Per essere sicuro, usa sempre font base o testa la generazione sull’ambiente di produzione.
Workflow: come integrare Graphviz nel lavoro reale
-
Metti i file
.gvnella repo. -
Genera gli SVG automaticamente nella CI:
dot -Tsvg diagram.gv -o diagram.svg -
Inietta gli SVG nella documentazione (README, wiki, blog).
-
Aggiorna i diagrammi ad ogni refactoring.
-
Usa differ e versioning dei file DOT come faresti col codice.
Troubleshooting: errori comuni e soluzioni
Errore: “syntax error in line X near…”
- Causa: Sintassi DOT non valida
- Soluzione: Controlla punto e virgola mancanti, parentesi graffe non chiuse, virgolette non matchate
- Esempio:
A -> Bdeve terminare con;→A -> B;
Errore: “Warning: Unable to find font…”
- Causa: Il font specificato non è installato sul sistema
- Soluzione: Usa font universali (Arial, Helvetica, Times) o installa il font richiesto
- Verifica font disponibili:
dot -vmostra i font disponibili
Il diagramma è troppo grande/piccolo
- Soluzione 1: Aggiungi
graph [size="8,6"]per limitare dimensioni (in pollici) - Soluzione 2: Usa
graph [ratio=compress]per comprimere automaticamente - Soluzione 3: Genera PNG con DPI custom:
dot -Tpng -Gdpi=150 file.dot -o file.png
Le frecce si sovrappongono ai nodi
- Soluzione: Aggiungi
graph [overlap=false, splines=true](vedi sezione “Evitare sovrapposizioni”)
I nodi sono tutti allineati orizzontalmente invece che verticalmente
- Soluzione: Usa
graph [rankdir=TB]per top-to-bottom (default è LR = left-to-right)
Il cluster non appare
- Causa: Nome cluster non inizia con
cluster_ - Soluzione: Rinomina
subgraph mygroupinsubgraph cluster_mygroup
Output SVG troppo grande (file size)
- Causa: SVG con molti elementi
- Soluzione 1: Usa PNG invece di SVG per grafi molto complessi
- Soluzione 2: Ottimizza con
svgo:svgo input.svg -o output.svg
Grafo non si genera (nessun output, nessun errore)
- Causa: Comando errato o redirect sbagliato
- Verifica: Usa
-vper verbose:dot -v -Tsvg input.dot -o output.svg - Test rapido:
echo "digraph{A->B}" | dot -Tsvg > test.svg
Le label degli archi non si vedono
- Causa: Label troppo lunghe o font troppo piccolo
- Soluzione: Aumenta
fontsizesugli edge o usa\nper spezzare label su più righe
Template DOT + Comandi Graphviz (CLI)
Ogni template include:
-
snippet DOT
-
comando CLI per generare l’immagine
Per coerenza uso il formato SVG, ma puoi sostituire -Tsvg con:
-Tpng-Tpdf-Tjpg-Tgif
E puoi salvare l’input DOT in template.dot oppure usare pipe.
Flowchart
Template 1 – Processo base
digraph FlowBasic {
graph [rankdir=TB];
node [shape=rectangle, style=rounded, fontsize=12];
Start [label="Start", shape=circle];
Step1 [label="Input validation"];
Step2 [label="Process request"];
Step3 [label="Persist data"];
End [label="End", shape=doublecircle];
Start -> Step1 -> Step2 -> Step3 -> End;
}
Command line:
dot -Tsvg FlowBasic.dot -o FlowBasic.svg
Template 2 – Branching (if/else)
digraph FlowIfElse {
graph [rankdir=TB];
node [fontsize=12, style=rounded];
Start [shape=circle];
Check [shape=diamond, label="Is valid?"];
A [label="Handle valid case"];
B [label="Handle error"];
End [shape=doublecircle];
Start -> Check;
Check -> A [label="Yes"];
Check -> B [label="No"];
A -> End;
B -> End;
}
Command line:
dot -Tsvg FlowIfElse.dot -o FlowIfElse.svg
Template 3 – Processo con sezioni
digraph FlowSections {
graph [rankdir=TB];
node [fontsize=11, style=rounded];
subgraph cluster_input {
label="Input Stage";
color=lightgrey;
style=filled;
A1 [label="Receive request"];
A2 [label="Validate payload"];
A1 -> A2;
}
subgraph cluster_processing {
label="Processing Stage";
color=lightblue;
style=filled;
P1 [label="Transform data"];
P2 [label="Apply business rules"];
P1 -> P2;
}
subgraph cluster_output {
label="Output Stage";
color=lightyellow;
style=filled;
O1 [label="Persist"];
O2 [label="Return response"];
O1 -> O2;
}
A2 -> P1 -> O1;
}
Command line:
dot -Tsvg FlowSections.dot -o FlowSections.svg
State Machine
Template 4 – State machine base
digraph StateMachine {
graph [rankdir=LR];
node [shape=circle, fontsize=12];
Idle;
Loading;
Error;
Success;
Idle -> Loading [label="start"];
Loading -> Success [label="ok"];
Loading -> Error [label="fail"];
Error -> Idle [label="retry"];
}
Command line:
dot -Tsvg StateMachine.dot -o StateMachine.svg
Template 5 – Stati annidati
digraph NestedStates {
graph [rankdir=LR];
node [fontsize=11];
subgraph cluster_ready {
label="Ready state";
style=dashed;
R1 [shape=circle, label="Idle"];
R2 [shape=circle, label="Primed"];
R1 -> R2 [label="prepare"];
}
subgraph cluster_active {
label="Active state";
style=dashed;
A1 [shape=circle, label="Running"];
A2 [shape=circle, label="Paused"];
A1 -> A2 [label="pause"];
A2 -> A1 [label="resume"];
}
R2 -> A1 [label="activate"];
}
Command line:
dot -Tsvg NestedStates.dot -o NestedStates.svg
Sequence Diagram (DOT)
Template 6 – Sequence orizzontale
digraph Sequence {
graph [rankdir=LR];
node [shape=box, fontsize=11];
Client -> API [label="POST /login"];
API -> AuthService [label="Check credentials"];
AuthService -> DB [label="Query user"];
DB -> AuthService [label="Result"];
AuthService -> API [label="Token"];
API -> Client [label="200 OK"];
}
Command line:
dot -Tsvg Sequence.dot -o Sequence.svg
Template 7 – Sequence con attivazioni
digraph SequenceActivation {
graph [rankdir=LR];
node [shape=box, style=rounded, fontsize=11];
User -> Frontend [label="Login"];
Frontend -> Backend [label="POST /login"];
Backend -> Backend [label="validate()"];
Backend -> DB [label="SELECT user"];
DB -> Backend [label="row found"];
Backend -> Frontend [label="JWT"];
Frontend -> User [label="Welcome"];
}
Command line:
dot -Tsvg SequenceActivation.dot -o SequenceActivation.svg
Dependency Graph
Template 8 – Moduli
digraph DependencyTree {
graph [rankdir=TB];
node [shape=box, style=rounded, fontsize=12];
App -> ModuleA;
App -> ModuleB;
ModuleA -> LibA;
ModuleA -> LibB;
ModuleB -> LibB;
}
Command line:
dot -Tsvg DependencyTree.dot -o DependencyTree.svg
Template 9 – Microservizi
digraph MicroservicesDep {
graph [rankdir=LR];
node [shape=box, style=rounded, fontsize=11];
Gateway -> Auth;
Gateway -> Orders;
Auth -> UsersDB;
Orders -> ProductsService;
Orders -> Payments;
Payments -> BankAPI;
}
Command line:
dot -Tsvg MicroservicesDep.dot -o MicroservicesDep.svg
Architecture Diagram
Template 10 – Layered
digraph Layered {
graph [rankdir=TB];
node [shape=box, style=rounded, fontsize=12];
subgraph cluster_presentation {
label="Presentation Layer";
style=filled;
color=lightyellow;
UI;
API;
}
subgraph cluster_business {
label="Business Layer";
style=filled;
color=lightblue;
Services;
}
subgraph cluster_data {
label="Data Layer";
style=filled;
color=lightgrey;
DB;
Cache;
}
UI -> API -> Services -> DB;
Services -> Cache;
}
Command line:
dot -Tsvg Layered.dot -o Layered.svg
Template 11 – Esagonale
digraph Hexagonal {
graph [rankdir=LR];
node [shape=box, style=rounded, fontsize=11];
AppCore [label="Core Domain"];
PortIn [label="Inbound Ports"];
PortOut [label="Outbound Ports"];
AdapterIn [label="Inbound Adapters"];
AdapterOut [label="Outbound Adapters"];
DB [label="Database"];
UI [label="Frontend/UI"];
UI -> AdapterIn -> PortIn -> AppCore;
AppCore -> PortOut -> AdapterOut -> DB;
}
Command line:
dot -Tsvg Hexagonal.dot -o Hexagonal.svg
ER Diagrams
Template 12 – 1:N
digraph ER_OneToMany {
graph [rankdir=LR];
node [shape=record, fontsize=11];
User [label="{User|id PK|name|email}"];
Order [label="{Order|id PK|user_id FK|total}"];
User -> Order [label="1:N"];
}
Command line:
dot -Tsvg ER_OneToMany.dot -o ER_OneToMany.svg
Template 13 – N:N
digraph ER_ManyToMany {
graph [rankdir=LR];
node [shape=record, fontsize=11];
Student [label="{Student|id PK|name}"];
Course [label="{Course|id PK|title}"];
Enroll [label="{Enroll|student_id FK|course_id FK}"];
Student -> Enroll;
Course -> Enroll;
}
Command line:
dot -Tsvg ER_ManyToMany.dot -o ER_ManyToMany.svg
Call Graph
Template 14 – Base
digraph CallGraph {
graph [rankdir=TB];
node [shape=box, style=rounded, fontsize=11];
main -> init;
main -> loadConfig;
loadConfig -> readFile;
readFile -> parseJson;
}
Command line:
dot -Tsvg CallGraph.dot -o CallGraph.svg
Template 15 – Con categorie
digraph CategorizedCalls {
graph [rankdir=TB];
node [shape=box, style=rounded, fontsize=11];
subgraph cluster_io {
label="I/O Functions";
color=lightgrey;
readFile;
writeFile;
}
subgraph cluster_logic {
label="Business Logic";
color=lightblue;
compute;
validate;
}
main -> compute -> validate;
compute -> readFile;
validate -> writeFile;
}
Command line:
dot -Tsvg CategorizedCalls.dot -o CategorizedCalls.svg
Network Diagram
Template 16 – Base
digraph Network {
graph [rankdir=LR];
node [shape=box, style=rounded, fontsize=11];
Client -> LoadBalancer;
LoadBalancer -> AppServer1;
LoadBalancer -> AppServer2;
AppServer1 -> DB;
AppServer2 -> DB;
}
Command line:
dot -Tsvg Network.dot -o Network.svg
Template 17 – Con protocolli
digraph NetworkProto {
graph [rankdir=LR];
node [shape=box, fontsize=11];
Client -> API [label="HTTPS"];
API -> Auth [label="gRPC"];
API -> Orders [label="REST"];
Orders -> DB [label="TCP"];
}
Command line:
dot -Tsvg NetworkProto.dot -o NetworkProto.svg
Timeline / Roadmap
Template 18 – Timeline
digraph Timeline {
graph [rankdir=LR];
node [shape=box, style=rounded, fontsize=11];
Start -> Milestone1 -> Milestone2 -> Milestone3 -> Release;
}
Command line:
dot -Tsvg Timeline.dot -o Timeline.svg
Template 19 – Roadmap
digraph Roadmap {
graph [rankdir=LR];
node [shape=box, fontsize=11];
subgraph cluster_backend {
label="Backend";
B1 [label="Auth module"];
B2 [label="Payments"];
}
subgraph cluster_frontend {
label="Frontend";
F1 [label="Login UI"];
F2 [label="Dashboard"];
}
B1 -> B2;
F1 -> F2;
}
Command line:
dot -Tsvg Roadmap.dot -o Roadmap.svg
Mind Map
Template 20 – Mind map
graph MindMap {
layout=twopi;
rankdir=LR;
node [shape=box, style=rounded, fontsize=11];
Central -- Idea1;
Central -- Idea2;
Central -- Idea3;
Idea2 -- Sub1;
Idea2 -- Sub2;
}
Command line:
dot -Ktwopi -Tsvg MindMap.dot -o MindMap.svg
Component Diagram
Template 21 – Components
digraph Components {
graph [rankdir=LR];
node [shape=component, fontsize=11];
UI -> API;
API -> Service;
Service -> DB;
}
Command line:
dot -Tsvg Components.dot -o Components.svg
Class Diagram
Template 22 – UML class-like
digraph Classes {
graph [rankdir=TB];
node [shape=record, fontsize=11];
Person [label="{Person|name:string|age:int}"];
Student [label="{Student|grade:int}"];
Person -> Student;
}
Command line:
dot -Tsvg Classes.dot -o Classes.svg
Layouts
Template 23 – Orizzontale
digraph Horizontal {
graph [rankdir=LR];
node [shape=box, style=rounded];
}
Command line:
dot -Tsvg Horizontal.dot -o Horizontal.svg
Template 24 – Verticale
digraph Vertical {
graph [rankdir=TB];
node [shape=box, style=rounded];
}
Command line:
dot -Tsvg Vertical.dot -o Vertical.svg
Template 25 – Circolare
graph Circular {
layout=circo;
node [shape=box, style=rounded];
}
Command line:
dot -Kcirco -Tsvg Circular.dot -o Circular.svg
Stili professionali
Template 26 – Modern theme
digraph Modern {
graph [rankdir=LR];
node [
shape=box,
style="rounded,filled",
fillcolor="#eef3f8",
color="#6a8bbf",
fontsize=11
];
edge [color="#6a8bbf"];
A -> B -> C;
}
Command line:
dot -Tsvg Modern.dot -o Modern.svg
Template 27 – Tema Scuro
digraph Dark {
bgcolor="#1e1e1e";
node [
shape=box,
style="rounded,filled",
fillcolor="#333333",
fontcolor="white",
color="#777777",
fontsize=11
];
edge [color="#999999"];
A -> B -> C;
}
Command line:
dot -Tsvg Dark.dot -o Dark.svg
Risorse utili
Documentazione ufficiale
- Graphviz Homepage: graphviz.org — Sito ufficiale con download, documentazione e news
- DOT Language Specification: graphviz.org/doc/info/lang.html — Riferimento completo della sintassi DOT
- Node Shapes Gallery: graphviz.org/doc/info/shapes.html — Catalogo completo di tutte le forme disponibili
- Attributes Reference: graphviz.org/doc/info/attrs.html — Lista completa di tutti gli attributi con descrizioni
- Color Names: graphviz.org/doc/info/colors.html — Palette di colori predefiniti e codici supportati
Strumenti online
- GraphvizOnline: dreampuf.github.io/GraphvizOnline — Editor online con preview in tempo reale
- Edotor: edotor.net — Editor Graphviz online con esempi e syntax highlighting
- WebGraphviz: webgraphviz.com — Generatore SVG/PNG da browser senza installazione
Integrazioni e librerie
- Graphviz Visual Editor (VSCode): Estensione per preview live in Visual Studio Code
- PlantUML: plantuml.com — Usa Graphviz per rendering di UML
- Mermaid: mermaid.js.org — Alternativa JavaScript-based a Graphviz per grafici in Markdown
- Python graphviz: graphviz.readthedocs.io — Libreria Python per generare grafi programmaticamente
- Go graphviz: github.com/goccy/go-graphviz — Binding Go per Graphviz
Gallery ed esempi
- Graphviz Gallery: graphviz.org/gallery — Esempi ufficiali di grafi complessi
- GitHub Awesome Graphviz: github.com/topics/graphviz — Repository e progetti che usano Graphviz
Community e supporto
- Stack Overflow: Tag graphviz — Domande e risposte della community
- Reddit r/graphviz: reddit.com/r/graphviz — Discussioni, esempi e aiuto
Tool complementari
- dot2tex: dot2tex.readthedocs.io — Converte DOT in LaTeX/TikZ
- SVGO: github.com/svg/svgo — Ottimizzatore SVG per ridurre dimensioni file
- Inkscape: inkscape.org — Editor vettoriale per post-processing manuale di SVG
Articolo scritto da Daniele Teti — danieleteti.it
Comments
comments powered by Disqus