Skip to content

About

Go bindings for Graphviz: layout and render DOT graphs with the real Graphviz compiled to WebAssembly and run on wazero, no C toolchain and no system Graphviz

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

376 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-graphviz ci

Go bindings for Graphviz

About this fork

A fork of github.com/goccy/go-graphviz, maintained by forkcloser. The library is the same: Graphviz compiled to WebAssembly, run on wazero, no C toolchain and no system Graphviz. The upstream dot command is not part of this module; forkcloser ships its own, github.com/forkcloser/dot, as a static binary with every layout and format of the library.

Features

The embedded Graphviz is the version of the graphviz entry in pins.yaml.

  • Pure Go Library
  • No need to install Graphviz library ( brew install graphviz or apt-get install graphviz )
    • The Graphviz library has been converted to WebAssembly (WASM) and embedded it, so it works consistently across all environments
  • Supports encoding/decoding for DOT language
  • Supports custom renderer for custom format
  • Supports setting graph properties in a type-safe manner

Supported Layout

circo dot fdp neato nop nop1 nop2 osage patchwork sfdp twopi

Supported Format

dot svg png jpg

The above are the formats supported by default. You can also add custom formats.

Fonts

Labels are measured for the layout and drawn with the fonts installed on the machine, as Graphviz's own tools do, so text fits its node in every format, and the same graph can lay out slightly differently on two machines with different fonts. A font name resolves the way Graphviz resolves it: a PostScript name such as Times-Roman or Helvetica-Bold, a family with style words (DejaVu Sans Bold, Arial:italic), or a list of them, looked up among the installed fonts by name, with the metric-compatible substitutes Graphviz knows (Arial for Helvetica, the Liberation and TeX Gyre faces). Where nothing installed answers, the embedded Go fonts stand in, in regular, bold, italic and monospace cuts. Those cover Latin, Greek and Cyrillic: a label in another script, CJK among them, draws as boxes on a machine with no font for it, unless a FontLoader (SetFontLoader) supplies one.

Fonts are read from the platform's directories: on macOS ~/Library/Fonts, /Library/Fonts and /System/Library/Fonts; on Windows the system and the user's Fonts folders; on Linux and the BSDs ~/.fonts, then fonts under XDG_DATA_HOME (~/.local/share/fonts when it is unset) and under each XDG_DATA_DIRS entry (/usr/local/share/fonts and /usr/share/fonts when it is unset); on Android /system/fonts.

Installation

$ go get github.com/forkcloser/go-graphviz

Synopsis

1. Write DOT Graph in Go

package main

import (
  "bytes"
  "context"
  "fmt"
  "log"

  "github.com/forkcloser/go-graphviz"
)

func main() {
  ctx := context.Background()
  g, err := graphviz.New(ctx)
  if err != nil { panic(err )}

  graph, err := g.Graph()
  if err != nil { panic(err) }
  defer func() {
    if err := graph.Close(); err != nil { panic(err) }
    g.Close()
  }()
  n, err := graph.CreateNodeByName("n")
  if err != nil { panic(err) }

  m, err := graph.CreateNodeByName("m")
  if err != nil { panic(err) }

  e, err := graph.CreateEdgeByName("e", n, m)
  if err != nil { panic(err) }
  e.SetLabel("e")

  var buf bytes.Buffer
  if err := g.Render(ctx, graph, "dot", &buf); err != nil {
    log.Fatal(err)
  }
  fmt.Println(buf.String())
}

2. Parse DOT Graph

path := "/path/to/dot.gv"
b, err := os.ReadFile(path)
if err != nil { panic(err) }
graph, err := graphviz.ParseBytes(b)

3. Render Graph

ctx := context.Background()
g, err := graphviz.New(ctx)
if err != nil { panic(err) }

graph, err := g.Graph()
if err != nil { panic(err) }

// create your graph

// 1. write encoded PNG data to buffer
var buf bytes.Buffer
if err := g.Render(ctx, graph, graphviz.PNG, &buf); err != nil { panic(err) }

// 2. get as image.Image instance
image, err := g.RenderImage(ctx, graph)
if err != nil { panic(err) }

// 3. write to file directly
if err := g.RenderFilename(ctx, graph, graphviz.PNG, "/path/to/graph.png"); err != nil { panic(err) }

Development

Every task runs through just: just lint, just test, just fix, just wasm, just bindings; just --list shows the rest. Tools are pinned by aqua and the shared conventions come from limen (see AGENTS.md).

How it works

  1. Generates bindings between Go and C from Protocol Buffers file with just bindings.
  2. Builds graphviz.wasm with just wasm (internal/wasm/build/build.sh): Graphviz, expat and the C bridge compiled to wasm32-wasip1 by a pinned wasi-sdk and shrunk by a pinned binaryen, every input fetched by version and checked against the digests in pins.yaml. No container and no configure run: the build is reproducible, and CI rebuilds the committed blob on Linux and macOS and compares the bytes.
  3. Uses Graphviz functionality from the sub-packages cgraph and gvc via the internal/wasm package.
  4. graphviz package provides facade interface for all sub packages.

License

MIT

This library embeds and uses graphviz.wasm, which is generated based on the original source code of Graphviz. Therefore, the graphviz.wasm follows the license adopted by Graphviz ( Eclipse Public License ).

About

Go bindings for Graphviz: layout and render DOT graphs with the real Graphviz compiled to WebAssembly and run on wazero, no C toolchain and no system Graphviz

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages