API Reference¶
d2vision can be used as a Go library in your own programs.
Installation¶
Packages¶
| Package | Description |
|---|---|
d2vision |
Core types and SVG parsing |
d2vision/format |
TOON/JSON/YAML serialization |
d2vision/generate |
D2 code generation |
d2vision/render |
D2 rendering (SVG output) |
d2vision/convert |
Mermaid/PlantUML conversion |
Parsing SVGs¶
package main
import (
"fmt"
"log"
"github.com/grokify/d2vision"
)
func main() {
// Parse from file
diagram, err := d2vision.ParseFile("diagram.svg")
if err != nil {
log.Fatal(err)
}
// Access diagram data
fmt.Printf("Version: %s\n", diagram.Version)
fmt.Printf("Nodes: %d\n", len(diagram.Nodes))
fmt.Printf("Edges: %d\n", len(diagram.Edges))
// Iterate nodes
for _, node := range diagram.Nodes {
fmt.Printf("Node: %s (%s)\n", node.ID, node.Shape)
}
}
Diagram Type¶
type Diagram struct {
Version string `json:"version,omitempty"`
Title string `json:"title,omitempty"`
ViewBox Bounds `json:"viewBox"`
Nodes []Node `json:"nodes"`
Edges []Edge `json:"edges"`
}
Node Type¶
type Node struct {
ID string `json:"id"`
Label string `json:"label,omitempty"`
Shape ShapeType `json:"shape"`
Bounds Bounds `json:"bounds"`
Parent string `json:"parent,omitempty"`
Children []string `json:"children,omitempty"`
Style NodeStyle `json:"style,omitempty"`
}
Edge Type¶
type Edge struct {
ID string `json:"id"`
Source string `json:"source"`
Target string `json:"target"`
Label string `json:"label,omitempty"`
SourceArrow ArrowType `json:"sourceArrow,omitempty"`
TargetArrow ArrowType `json:"targetArrow"`
Path []Point `json:"path,omitempty"`
}
Serialization¶
package main
import (
"fmt"
"github.com/grokify/d2vision"
"github.com/grokify/d2vision/format"
)
func main() {
diagram, _ := d2vision.ParseFile("diagram.svg")
// TOON format (default, token-efficient)
toon, _ := format.Marshal(diagram, format.TOON)
fmt.Println(string(toon))
// JSON format
json, _ := format.Marshal(diagram, format.JSON)
fmt.Println(string(json))
// YAML format
yaml, _ := format.Marshal(diagram, format.YAML)
fmt.Println(string(yaml))
}
Format Constants¶
const (
TOON Format = "toon"
JSON Format = "json"
JSONCompact Format = "json-compact"
YAML Format = "yaml"
)
Generating D2 Code¶
package main
import (
"fmt"
"github.com/grokify/d2vision/generate"
)
func main() {
spec := &generate.DiagramSpec{
GridColumns: 2,
Containers: []generate.ContainerSpec{
{
ID: "cluster1",
Label: "Cluster 1",
Direction: "down",
Nodes: []generate.NodeSpec{
{ID: "service1", Label: "Service 1"},
{ID: "db1", Label: "Database", Shape: "cylinder"},
},
Edges: []generate.EdgeSpec{
{From: "service1", To: "db1"},
},
},
{
ID: "cluster2",
Label: "Cluster 2",
Direction: "down",
Nodes: []generate.NodeSpec{
{ID: "service2", Label: "Service 2"},
{ID: "db2", Label: "Database", Shape: "cylinder"},
},
Edges: []generate.EdgeSpec{
{From: "service2", To: "db2"},
},
},
},
Edges: []generate.EdgeSpec{
{From: "cluster1.db1", To: "cluster2.db2", Label: "sync"},
},
}
gen := generate.NewGenerator()
d2Code := gen.Generate(spec)
fmt.Println(d2Code)
}
DiagramSpec Type¶
type DiagramSpec struct {
Direction string `json:"direction,omitempty"`
GridColumns int `json:"gridColumns,omitempty"`
GridRows int `json:"gridRows,omitempty"`
Nodes []NodeSpec `json:"nodes,omitempty"`
Containers []ContainerSpec `json:"containers,omitempty"`
Edges []EdgeSpec `json:"edges,omitempty"`
Sequences []SequenceSpec `json:"sequences,omitempty"`
Tables []TableSpec `json:"tables,omitempty"`
}
ContainerSpec¶
type ContainerSpec struct {
ID string `json:"id"`
Label string `json:"label,omitempty"`
Direction string `json:"direction,omitempty"`
GridColumns int `json:"gridColumns,omitempty"`
GridRows int `json:"gridRows,omitempty"`
Style StyleSpec `json:"style,omitempty"`
Nodes []NodeSpec `json:"nodes,omitempty"`
Containers []ContainerSpec `json:"containers,omitempty"`
Edges []EdgeSpec `json:"edges,omitempty"`
}
NodeSpec¶
type NodeSpec struct {
ID string `json:"id"`
Label string `json:"label,omitempty"`
Shape string `json:"shape,omitempty"`
Icon string `json:"icon,omitempty"`
Style StyleSpec `json:"style,omitempty"`
}
EdgeSpec¶
type EdgeSpec struct {
From string `json:"from"`
To string `json:"to"`
Label string `json:"label,omitempty"`
SourceArrow string `json:"sourceArrow,omitempty"`
TargetArrow string `json:"targetArrow,omitempty"`
Style StyleSpec `json:"style,omitempty"`
}
StyleSpec¶
type StyleSpec struct {
Fill string `json:"fill,omitempty"`
Stroke string `json:"stroke,omitempty"`
StrokeWidth *int `json:"strokeWidth,omitempty"`
BorderRadius *int `json:"borderRadius,omitempty"`
FontSize *int `json:"fontSize,omitempty"`
Opacity *float64 `json:"opacity,omitempty"`
}
// Helper functions
func IntPtr(i int) *int
func Float64Ptr(f float64) *float64
Rendering D2 Code¶
The render package provides built-in D2 rendering without requiring the D2 CLI:
package main
import (
"context"
"log"
"os"
"github.com/grokify/d2vision/render"
)
func main() {
d2Code := `
direction: right
client: Client { shape: person }
server: Server {
api: API
db: Database { shape: cylinder }
api -> db
}
client -> server.api
`
// Create renderer
r, err := render.New()
if err != nil {
log.Fatal(err)
}
// Render to SVG
svg, err := r.RenderSVG(context.Background(), d2Code, nil)
if err != nil {
log.Fatal(err)
}
// Write to file
if err := os.WriteFile("diagram.svg", svg, 0644); err != nil {
log.Fatal(err)
}
}
Quick Rendering¶
For simple use cases:
// One-liner to render D2 to SVG
svg, err := render.Quick("a -> b -> c")
// Validate D2 code without rendering
err := render.Validate(ctx, d2Code)
Render Options¶
opts := &render.Options{
ThemeID: 1, // D2 theme (0 = default)
Pad: 100, // Padding in pixels
Sketch: true, // Hand-drawn style
Scale: 2.0, // Output scale
}
svg, err := r.RenderSVG(ctx, d2Code, opts)
Full Example¶
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/grokify/d2vision/generate"
"github.com/grokify/d2vision/render"
)
func main() {
// Create a diagram spec
spec := &generate.DiagramSpec{
Direction: "right",
Nodes: []generate.NodeSpec{
{ID: "client", Label: "Client", Shape: "person"},
},
Containers: []generate.ContainerSpec{
{
ID: "server",
Label: "Server",
Direction: "down",
Nodes: []generate.NodeSpec{
{ID: "api", Label: "API"},
{ID: "db", Label: "Database", Shape: "cylinder"},
},
Edges: []generate.EdgeSpec{
{From: "api", To: "db"},
},
},
},
Edges: []generate.EdgeSpec{
{From: "client", To: "server.api"},
},
}
// Generate D2 code
gen := generate.NewGenerator()
d2Code := gen.Generate(spec)
// Render to SVG using built-in renderer
r, err := render.New()
if err != nil {
log.Fatal(err)
}
svg, err := r.RenderSVG(context.Background(), d2Code, nil)
if err != nil {
log.Fatal(err)
}
// Write to file
if err := os.WriteFile("diagram.svg", svg, 0644); err != nil {
log.Fatal(err)
}
fmt.Println("Generated diagram.svg")
}