Diagramas D2
D2 es un lenguaje declarativo: describes formas y las conexiones entre ellas, y un motor de diseño decide dónde va todo. Nunca colocas coordenadas a mano. Por eso un diagrama D2 es corto, difierenciable y fácil de editar más tarde, y también por qué la mayoría de los errores provienen de peculiaridades de sintaxis y del motor de diseño, no del diseño.
Esta habilidad es un conocimiento completo y funcional de D2 v0.9.x, verificado contra el compilador real. Cada ejemplo en references/ y assets/templates/ compila.
Flujo de trabajo
- Verifica la herramienta. Ejecuta
d2 --version(oscripts/d2check.sh --version). Si faltad2, informa al usuario y ofrecebrew install d2ocurl -fsSL https://d2lang.com/install.sh | sh -s --; no lo instales silenciosamente. - Elige el tipo de diagrama y lee la referencia correspondiente (tabla a continuación). Comienza desde una plantilla en
assets/templates/cuando sea adecuada. - Escribe el archivo
.d2junto a donde el usuario lo desee (por defecto:diagrams/<nombre>.d2). - Compila y renderiza con
scripts/d2check.sh <archivo.d2> [directorio_salida] [pdf|pptx|gif](formatea, compila, renderiza SVG, coloca una vista previa PNG endirectorio_salida/preview/, y cualquier formato adicional). Nunca confíes solo end2 validate: solo analiza la sintaxis. Nombres de formas incorrectos, estilos fuera de rango, características de diseño no compatibles e importaciones faltantes pasanvalidatey fallan al compilar. - Mira la imagen. Abre el PNG en
preview/(herramienta Leer en el.png) y evalúa: etiquetas superpuestas, bordes enredados, dirección de flujo incorrecta, diseño desequilibrado. Corrige y vuelve a renderizar. Un diagrama que compila pero es ilegible no está terminado. - Entrega el código fuente
.d2más el archivo renderizado, e indica qué motor de diseño, tema y dirección usaste para que el usuario pueda cambiarlos.
Para una salida rápida sin archivos: echo 'a -> b' | d2 - out.svg.
Sintaxis en una pantalla
direction: right # arriba | abajo | derecha | izquierda (a nivel raíz; solo TALA permite por contenedor)
# formas: clave, etiqueta opcional, atributos opcionales
web: Web App {shape: rectangle} # clave `web`, etiqueta "Web App"
db: Postgres {shape: cylinder}
user: Customer {shape: person}
# conexiones: -> <- <-> -- (siempre referencia CLAVES, nunca etiquetas)
user -> web: usa
web -> db: SQL {style.stroke-dash: 3}
web -> cache: lee # las claves no declaradas se crean sobre la marcha
# contenedores: puntos o mapas anidados
backend: {
api -> worker: encola
worker -> _.db: escribe # _ = ámbito padre
}
web -> backend.api: HTTPS
# el estilo vive en los atributos
db.style.fill: "#e6f2ff" # cita cualquier cosa que comience con #
(web -> db)[0].style.stroke: red # estiliza una conexión por índice
# reutilización: clases, variables, globs
classes: {
store: {shape: cylinder; style.fill: "#e6f2ff"}
}
cache.class: store
vars: {env: prod}
note: Ejecutando en ${env}
*.style.border-radius: 8
Los puntos y coma separan elementos en una línea. # inicia un comentario, """ ... """ es un comentario de bloque. Las claves no distinguen mayúsculas/minúsculas y las declaraciones repetidas se fusionan (API, api y Api: Gateway son una forma etiquetada "Gateway").
Citas: la fuente número uno de errores
Las cadenas sin comillas son convenientes, pero varios caracteres tienen significado. Pon entre comillas la etiqueta completa ("..." o '...') siempre que contenga alguno de estos, o el compilador produce un error o, peor, trunca silenciosamente la etiqueta:
| Carácter | Qué sucede sin comillas | Ejemplo de corrección |
|---|---|---|
# en cualquier lugar | el resto de la línea se convierte en comentario: a: C# language renderiza "C" | a: "C# language" |
[ al inicio | se analiza como una matriz: a: [JSON/HTTPS] renderiza solo "a" | a: "[JSON/HTTPS]" |
. en una clave | crea un contenedor: svc v1.2 se convierte en svc v1 > 2 | "svc v1.2" |
& o [ ] en una clave | error de análisis (& es el marcador de filtro glob) | "R&D", "svc[0]" |
$ seguido de cualquier cosa excepto { | "las sustituciones deben comenzar con {" | comillas simples: 'cuesta $5' |
{ } ` | ` al inicio de la etiqueta | abre un mapa o una cadena de bloque |
palabras reservadas como claves de forma (label, link, class, top, style, shape, icon, near, direction, vars ...) | "las palabras clave reservadas están prohibidas en los bordes" | "link" -> b, o elige una clave diferente |
-> o : dentro de una etiqueta de borde | bien en la práctica (a -> b: Hora: 10s funciona) | no necesita comillas |
puntuación no ASCII como : (dos puntos de ancho completo) | no se reconoce como dos puntos | usa ASCII : ; . |
Los colores hexadecimales deben ir entre comillas ("#fff") porque # inicia un comentario. Las comillas simples también deshabilitan la sustitución ${...}.
Saltos de línea en etiquetas: \n en una etiqueta entre comillas o sin comillas, o una cadena de bloque |md ... | para texto enriquecido.
Cosas que muerden (lee antes de depurar)
- Dagre, el motor de diseño predeterminado, no puede dibujar una conexión entre un contenedor y su propio descendiente (
a -> a.b), no puede dimensionar contenedores (width/height), y no puede usarnear: <objeto>. Da error en tiempo de compilación. Cambia a--layout=elk(ovars.d2-config.layout-engine: elk) en lugar de reescribir el diagrama. - Las palabras reservadas se comparan sin distinguir mayúsculas/minúsculas. Una forma o clase UML llamada
Shape,Label,Class,Style,Link,Icon... choca con la palabra clave (reserved field shape does not accept composite). Cámbiale el nombre. - Conecta claves, no etiquetas. Después de
be: Backend,Backend -> xcrea una nueva forma llamada Backend. Usabe -> x. - Las conexiones repetidas no se fusionan;
a -> bdos veces dibuja dos flechas. Dirígete a ellas como(a -> b)[0],(a -> b)[1]. d2-legendes una variable, no una forma: ponla dentro devars: { d2-legend: { ... } }. Und2-legend: ""de nivel superior es solo una forma ordinaria llamada "d2-legend".- Diagramas de secuencia: el orden de declaración es el orden en pantalla, los actores deben declararse primero, y dentro de los grupos solo puedes hacer referencia a actores que existan en el nivel superior.
- Tablas SQL y clases UML: conecta filas (
orders.user_id -> users.id), y usa ELK o TALA para que los bordes lleguen a la fila exacta. - Las formas de punta de flecha solo se renderizan en un extremo que tenga flecha:
A -> Bconsource-arrowhead.shape: diamondno dibuja nada en A (y--no dibuja ninguna forma). Invierte el borde para que la forma esté en el destino, o usa<->. d2 fmtreescribe etiquetas de palabras reservadas (lnk: Linkse convierte enlnk: link), yscripts/d2check.shejecuta fmt en tu archivo en su lugar. Pon entre comillas dichas etiquetas (lnk: "Link").- Las cadenas de bloque
|md ... |terminan en el siguiente|. Una barra vertical literal dentro necesita un delimitador más largo:|md ...|o||md ... ||. - Los rangos de estilo numérico están aplicados:
stroke-width0-15,opacity0-1,font-size8-100.text-transformaceptanone|uppercase|lowercase|capitalize(el sitio web dicetitle; el compilador lo rechaza).3dsolo funciona en rectángulo, cuadrado y hexágono. - No añadas
animated: trueodark-theme-ida menos que te lo pidan. La animación implica flujo de datos en tiempo de ejecución; un tema oscuro cambia silenciosamente los colores para los espectadores cuyo SO está en modo oscuro. - Los colores de relleno en las formas anulan el tema. Prefiere el tema y algunas
classes; usa colores explícitos solo cuando el color tenga significado (y entonces añade una leyenda). - PNG/PDF/PPTX/GIF se renderizan sin navegador en v0.9+. Las versiones anteriores (<0.8) necesitan Playwright/Chromium, que se descarga en el primer uso. Verifica
d2 --version. - TALA está incluido en v0.9 (
--layout=tala) pero no es determinista: un pequeño cambio de etiqueta puede reordenar el diseño. Fíjalo condata.tala-seedssi la reproducibilidad es importante. - Los archivos multi-lámina (
layers/scenarios/steps) exportan SVG y PNG como directorios (x/index.svg,x/layers/a.svg), y renderizar PNG con el mismo nombre reemplaza el directorio SVG. Mantén los formatos en carpetas separadas (el script lo hace). Para un entregable de exploración en profundidad, usa PDF (una página por lámina, conlink: layers.xenlaces clicables) y no dibujes formas "Atrás" a mano: el exportador añade una barra de navegación automáticamente. Consultareferences/composition.md. - Que el archivo de salida exista no significa éxito. D2 puede escribir un renderizado parcial en caso de error. Verifica el código de salida (el script lo hace).
Elegir diseño, dirección, tema
- Motor de diseño:
dagre(predeterminado, rápido, bordes curvos) ->elk(enrutamiento ortogonal, mejor para arquitectura, tablas SQL, bordes contenedor a contenedor) ->tala(simetría,directionpor contenedor,near: objeto,top/leftbloqueados). Por defecto, usa ELK para cualquier cosa con contenedores o tablas. - Dirección:
rightpara tuberías, flujos de solicitudes y pantallas anchas;downpara jerarquías y organigramas. Elige una para todo el cuadro. - Tema:
theme-id: 0predeterminado;4Cool classics y3Flagship Terrastruct se ven modernos;1gris neutro para documentos sobrios;8es seguro para daltonismo;300/301terminal;303C4;200/201oscuro. Tabla completa enreferences/cli-and-rendering.md. - Pon la configuración de renderizado en el archivo para que viaje con él:
vars: {
d2-config: {
layout-engine: elk
theme-id: 4
pad: 40
}
}
(Las banderas CLI y las variables de entorno D2_* anulan este bloque.)
Guía de diseño
- De 3 a 12 formas por lámina. Más allá, divide con
layers(acercar),scenarios(variantes) osteps(acumulación), o usa contenedores para agrupar. - Nombra por clave, etiqueta para humanos: claves estables cortas (
pg,auth), etiquetas legibles (pg: PostgreSQL). - Las etiquetas de borde son verbos o protocolos (
lee,publica,HTTPS), no oraciones ni el nombre del destino. - Asocia la forma al significado:
cylinderalmacén,queuecola,personpersona,cloudexterno,diamonddecisión,hexagonservicio,document/pagedocumento,packagepaquete,steppaso. No dejes todo como un rectángulo. - El color codifica significado o nada. Como máximo ~5 categorías, aplicadas a través de
classes, con und2-legendsolo cuando los colores transmitan información que las etiquetas no. - Un nivel de abstracción por lámina.
- D2 es para documentar software y sistemas a escala de pizarra (hasta unos pocos cientos de formas). Deliberadamente no tiene diagramas de Gantt, mapas mentales, diagramas de Venn, Sankey, gráficos circulares/de barras o mapas geográficos, y un objeto no puede vivir en dos contenedores. Dilo y sugiere otra herramienta en lugar de forzar D2.
Mapa de referencias
Lee solo lo que la tarea necesite.
| Tarea | Leer |
|---|---|
| Cualquier duda de sintaxis: claves, etiquetas, conexiones, contenedores, cadenas, escape, comentarios, palabras clave reservadas | references/language.md |
Formas, cada clave de estilo y su rango, puntas de flecha, texto/markdown/LaTeX/código, iconos, posicionamiento near, tamaños, temas | references/shapes-and-styling.md |
| Diagramas de secuencia, tablas SQL (ERD), clases UML, cuadrículas, leyendas, tooltips/enlaces, C4 | references/diagram-types.md |
Clases, variables, globs y filtros, anulaciones y null, importaciones, modelos suspend | references/reuse-and-globs.md |
| Capas, escenarios, pasos, enlace de láminas, importaciones para diagramas grandes, exportación multi-lámina | references/composition.md |
Banderas CLI, motores de diseño, tabla de temas, formatos de exportación, d2-config, incrustación en docs/CI, D2.js | references/cli-and-rendering.md |
| Patrones listos por familia de diagrama (arquitectura, flujo, estado, ERD, C4, organigrama...) | references/recipes.md + assets/templates/*.d2 |
| Conversión desde Mermaid / PlantUML / Graphviz | references/recipes.md (sección de conversión) |
| Un mensaje de error o un diagrama que se renderiza mal | references/troubleshooting.md |
Cuando la compilación falla
Ejecuta scripts/d2check.sh archivo.d2. Los errores aparecen como archivo:LÍNEA:COL: mensaje. Busca el mensaje en references/troubleshooting.md; los culpables habituales son las citas (arriba), un límite del motor de diseño (cambia a ELK), una forma desconocida o un estilo fuera de rango, y la sangría de cadenas de bloque. Corrige un error a la vez y vuelve a ejecutar: los errores posteriores suelen ser consecuencias del primero.