A popular way to draw graphs is to describe the graph in the DOT language and pass this description to a rendering tool such as Graphviz. graph is a generic Go graph library for creating graph structures, performing operations on them, and generating a DOT description of them.
Preparation
If you want to try this demo yourself, you can do so by setting up an example project:
- Install Go 1.18 and Graphviz.
- Initialize a Go module in a new directory, for example
go mod init mygraph
. - Get the library using
go get github.com/dominikbraun/graph
. - Create a file called
main.go
.
Creating a Graph
In this example, we're going to create a simple graph g
: It consists of four nodes (or vertices) connected by three directed edges. The vertices
are integer values, so this is a graph of integers.
package main import "github.com/dominikbraun/graph" func main() { g := graph.New(graph.IntHash, graph.Directed()) _ = g.AddVertex(1) _ = g.AddVertex(2) _ = g.AddVertex(3) _ = g.AddVertex(4) _ = g.AddEdge(1, 2) _ = g.AddEdge(1, 3) _ = g.AddEdge(3, 4) }
Each vertex is identified by a unique hash. To obtain the hash value for a vertex, the graph needs a hashing function which is passed to New
. In our case, this is the predefined IntHash
function that accepts an integer and returns that integer as a hash value at the same time.
Custom data types as vertices and custom hashing functions are supported as well, see Hashes.
A variety of functional options may be called when creating the graph, for example Directed
to make the graph directed or Acyclic
to permit cycles. Vertex
adds a vertex with the given value, and Edge
creates an edge between two vertices.
Generating a DOT File
The next step is to generate a DOT description for the graph, which can be accomplished using the included draw
package. Any io.Writer
can be used as an output target. In this demo, we're going to write the DOT description into a file called my-graph.gv
:
file, _ := os.Create("my-graph.gv") _ = draw.DOT(g, file)
With these additions, the Go program should ultimately look as follows:
package main import ( "os" "github.com/dominikbraun/graph" "github.com/dominikbraun/graph/draw" ) func main() { g := graph.New(graph.IntHash, graph.Directed()) _ = g.AddVertex(1) _ = g.AddVertex(2) _ = g.AddVertex(3) _ = g.AddVertex(4) _ = g.AddEdge(1, 2) _ = g.AddEdge(1, 3) _ = g.AddEdge(3, 4) file, _ := os.Create("my-graph.gv") _ = draw.DOT(g, file) }
Running go run main.go
will create the graph and yield the corresponding DOT file.
Rendering the Graph
This DOT file can be interpreted by a variety of renderers, the most popular one being Graphviz. After installing Graphviz, you can render the graph as an SVG using the following command:
dot -Tsvg -O my-graph.gv
Adding Edge Attributes
The DOT language supports a number of attributes, for example for coloring edges. Using graph
, arbitrary edge attributes can be added and included in the DOT description when visualizing a graph. An edge like this will be colored red:
_ = g.AddEdge(1, 2, graph.EdgeAttribute("color", "red"))
You can find further examples and documentation on GitHub.