gogv

Graphviz dot,
in pure Go.

gogv is a Go implementation of the Graphviz dot program, following Graphviz 16.1.0. It lays out graphs written in the DOT language and writes them as SVG and in the other output formats of dot. It needs no cgo, no embedded WebAssembly and no installed Graphviz.

Install v0.3.1 Try it in the browser Source on GitHub

example.gv
digraph gogv {
	rankdir=LR
	node [shape=box, style=rounded, fontname=Helvetica, fontsize=12]
	edge [fontname=Helvetica, fontsize=10, color="#555555"]

	input [label="DOT text", shape=plaintext]

	subgraph cluster_language {
		label="dotlang"
		fontname=Helvetica
		color="#4a7ebb"
		lexer -> parser [label="tokens"]
	}

	subgraph cluster_layout {
		label="layout"
		fontname=Helvetica
		color="#5a9e4b"
		rank -> order -> position -> route
	}

	subgraph cluster_output {
		label="output"
		fontname=Helvetica
		color="#b36b2e"
		node [shape=ellipse]
		svg; xdot; json; canon
	}

	input -> lexer
	parser -> rank [label="graph"]
	parser -> canon [label="no layout"]
	route -> svg
	route -> xdot
	route -> json
}

$ dot -Tsvg example.gv -o example.svg

The stages of gogv, laid out by gogv from left to right: DOT text goes through the lexer and the parser of dotlang, then through rank, order, position and route of the layout, to the svg, xdot and json outputs; canon is written without a layout.

Three ways to run it

Go library

gogv.Render writes the bytes that dot -T<format> writes, and returns the warnings and a *gogv.SyntaxError with its line. It is safe for concurrent use.

out, warnings, err :=
	gogv.Render(ctx, src, "svg")

Command line

A dot that accepts -T<format>, -o<file>, -V and -Kdot, and rejects the other flags of Graphviz's dot with exit status 1 instead of ignoring them.

dot -Tsvg graph.gv -o graph.svg

WebAssembly module

The library starts no process and reads no file, environment variable or network, so it builds and runs in WebAssembly. The playground on this page runs it.

GOOS=js GOARCH=wasm go build ./...

Playground

Edit the DOT source, and gogv v0.3.1 lays it out in this page with WebAssembly. No server is involved.

If this message stays, the playground could not start: browsers do not run its scripts from a page opened as a file. Serve the page over HTTP, for example with make site and python3 -m http.server -d .cache/site.

With go tool pprof

go tool pprof draws its call graphs with dot: -svg, -web and the Graph view of -http. With gogv installed as dot, they work without Graphviz: nodes are filled with their colors, hot edges are thicker and kept straight, residual edges are dotted, tag nodes are boxes with depth, and the Graph view selects nodes by their id.

go install github.com/ekalinin/gogv/cmd/dot@v0.3.1
export PATH="$(go env GOPATH)/bin:$PATH"
go tool pprof -http=:8080 cpu.prof

Output formats

The layout is the layered layout of dot: ranking, crossing minimization, positioning, and spline or polyline routing, with clusters, edge labels, table labels and node ports. The Status and "Not supported yet" lists of the README name the attributes and values that gogv supports. A feature that is not supported yet gives a warning that names the default used instead.

Install

With Go 1.26 or later, install the dot command line of v0.3.1:

go install github.com/ekalinin/gogv/cmd/dot@v0.3.1
dot -V   # dot - graphviz version 16.1.0 (gogv 0.3.1)

The command is named dot, as Graphviz's is: when Graphviz is installed too, the dot found first in PATH runs, and dot -V tells them apart. Add the library to a module with:

go get github.com/ekalinin/gogv@v0.3.1

Releases have no prebuilt binaries.

Conformance

make conformance compares v0.3.1 with Graphviz 16.1.0 built without Pango on 587 cases: canon byte for byte, plain by nodes, edges and size, svg by size and the structural similarity of the rasterized documents, and dot, xdot and JSON by their objects, attributes and drawing operations.

The conformance report lists the cases by capability and by format.

Clean-room implementation

gogv is written from published papers, the Graphviz documentation and the observed behavior of Graphviz 16.1.0, used as a black box. It contains no code from Graphviz or from its ports and bindings. Every Go file names its sources in Provenance: lines:

Text is measured with tables generated from the Liberation 2.1.5 fonts, and elementary functions come from a port of fdlibm, so that the output is the same, byte for byte, on every platform.