How I structure D2 files
I use D2 for diagrams in my documentation.
RunOnSave
Section titled “RunOnSave”D2 vscode extension does not support automatic rendering on file save, so I use RunOnSave extension to run D2 CLI on file save. Files with leading underscore in filename are ignored as I use them as imports.
"emeraldwalk.runonsave": { "commands": [ { "match": "\\.d2$", "notMatch": "\\\\_.*\\.d2$", "isAsync": true, "cmd": "cd ${fileDirname} && d2 ${file} ${fileBasenameNoExt}.svg" } ]}
File structure
Section titled “File structure”To keep things organized, I structure my D2 files like this:
- vars and classes
- diagram elements or shapes
- relationships between elements or connections
- tala layout positioning directives
This is how I create new D2 diagram:
- Copy my D2 template that I keep in separate file.
- Define elements.
- Add relationships and see how tala layout positions them automatically.
- Adjust positions with
top
andleft
directives.
Example D2 file:
# Colors to choose from: https://github.com/terrastruct/d2/blob/master/lib/color/color.go#L190
vars: { d2-config: { pad: 2 center: true theme-id: 5 dark-theme-id: 5 layout-engine: tala sketch: false }}
direction: down
***.label.near: top-center***.style: { stroke-width: 1 shadow: true border-radius: 5 font-size: 8 font-color: black}
classes: { arrow: { style: { stroke: black stroke-width: 1 font-size: 8 font-color: black } } box: { width: 150 height: 50 }}
cloud: { label: Azure Cloud
apim: { label: API Management class: box } vpn: { label: VPN Gateway class: box }}
onprem: { label: On-Premises service: { label: Service\n\[WinService\] class: box }}
cloud.apim -> cloud.vpn: {class: arrow; label: Private Endpoint}cloud.vpn -> onprem.service: {class: arrow; label: S2S VPN}
cloud: {top: 0; left: 0; label.near: top-left}cloud.apim: {top: 0; left: 0}cloud.vpn: {top: 100; left: 0}
onprem: {top: 300; left: 0; label.near: top-left}