dot

package module
v0.0.0-...-fa0cb27 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2025 License: MIT Imports: 6 Imported by: 0

README

dot - little helper package in Go for the graphviz dot language

Go Go Report Card GoDoc codecov

DOT language

package main

import ( "fmt" "github.com/eristocrates/dot" )

// go run main.go | dot -Tpng > test.png && open test.png

func main() { g := dot.NewGraph(dot.Directed) n1 := g.Node("coding") n2 := g.Node("testing a little").Box()

g.Edge(n1, n2) g.Edge(n2, n1, "back").Attr("color", "red")

fmt.Println(g.String()) }

Output

digraph { node [label="coding"]; n1; node [label="testing a little",shape="box"]; n2; n1 -> n2; n2 -> n1 [color="red", label="back"]; }

Chaining edges

g.Node("A").Edge(g.Node("B")).Edge(g.Node("C"))

A -> B -> C

g.Node("D").BidirectionalEdge(g.Node("E"))

D <-> E

Subgraphs

s := g.Subgraph("cluster") s.Attr("style", "filled")

Initializers

g := dot.NewGraph(dot.Directed) g.NodeInitializer(func(n dot.Node) { n.Attr("shape", "rectangle") n.Attr("fontname", "arial") n.Attr("style", "rounded,filled") })

g.EdgeInitializer(func(e dot.Edge) { e.Attr("fontname", "arial") e.Attr("fontsize", "9") e.Attr("arrowsize", "0.8") e.Attr("arrowhead", "open") })

HTML and Literal values

node.Attr("label", Literal("left-justified text\l")) graph.Attr("label", HTML("Hi"))

cluster example

di := dot.NewGraph(dot.Directed) outside := di.Node("Outside")

// A clusterA := di.Subgraph("Cluster A", dot.ClusterOption{}) insideOne := clusterA.Node("one") insideTwo := clusterA.Node("two")

// B clusterB := di.Subgraph("Cluster B", dot.ClusterOption{}) insideThree := clusterB.Node("three") insideFour := clusterB.Node("four")

// edges outside.Edge(insideFour).Edge(insideOne).Edge(insideTwo).Edge(insideThree).Edge(outside)

See also ext/Subsystem type for creating composition hierarchies.

record example

See record_test.go#ExampleNode_NewRecordBuilder.

About dot attributes

https://graphviz.gitlab.io/doc/info/attrs.html

display your graph

go run main.go | dot -Tpng > test.png && open test.png

mermaid

Output a dot Graph using the mermaid syntax. Only Graph and Flowchart are supported. See MermaidGraph and MermaidFlowchart.

g := dot.NewGraph(dot.Directed)
...
fmt.Println(dot.MermaidGraph(g, dot.MermaidTopToBottom))

subgraphs in mermaid

flowchart LR;n8-->n3;subgraph one;n2("a1");n3("a2");n2-->n3;end;subgraph three;n8("c1");n9("c2");n8-->n9;end;subgraph two;n5("b1");n6("b2");n5-->n6;end;

mermaid specific attributes

attr type description
link Edge examples are {-->,-.->,--x,o--o}
shape Node examples are {MermaidShapeRound,MermaidShapeCircle,MermaidShapeTrapezoid}
style Node example is fill:#90EE90

extensions

See also package dot/dotx for types that can help in constructing complex graphs.

testing

go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out

(c) 2015-2023, http://ernestmicklei.com. MIT License.

Documentation

Overview

Package dot is a helper for producing graphs in DOT format (graphviz). It offers Graph,Node and Edge objects to construct simple and complex (e.g. nested) graphs.

Copyright (c) Ernest Micklei. MIT License

Index

Examples

Constants

View Source
const (
	MermaidTopToBottom = iota
	MermaidTopDown
	MermaidBottomToTop
	MermaidRightToLeft
	MermaidLeftToRight
)

Variables

View Source
var (
	Strict     = GraphTypeOption{"strict"} // only for graph and digraph, not for subgraph
	Undirected = GraphTypeOption{"graph"}
	Directed   = GraphTypeOption{"digraph"}
	Sub        = GraphTypeOption{"subgraph"}
)
View Source
var (
	MermaidShapeRound            = shape{"(", ")"}
	MermaidShapeStadium          = shape{"([", "])"}
	MermaidShapeSubroutine       = shape{"[[", "]]"}
	MermaidShapeCylinder         = shape{"[(", ")]"}
	MermaidShapeCirle            = shape{"((", "))"} // Deprecated: use MermaidShapeCircle instead
	MermaidShapeCircle           = shape{"((", "))"}
	MermaidShapeAsymmetric       = shape{">", "]"}
	MermaidShapeRhombus          = shape{"{", "}"}
	MermaidShapeTrapezoid        = shape{"[/", "\\]"}
	MermaidShapeTrapezoidAlt     = shape{"[\\", "/]"}
	MermaidShapeHexagon          = shape{"{{", "}}"}
	MermaidShapeParallelogram    = shape{"[/", "/]"}
	MermaidShapeParallelogramAlt = shape{"[\\", "\\]"}
)

Functions

func MermaidFlowchart

func MermaidFlowchart(g *Graph, orientation int) string

func MermaidGraph

func MermaidGraph(g *Graph, orientation int) string

Types

type AttributesMap

type AttributesMap struct {
	// contains filtered or unexported fields
}

AttributesMap holds attribute=value pairs.

func (*AttributesMap) Attributes

func (am *AttributesMap) Attributes() map[string]interface{}

Attributes returns a copy of the attributes.

func (AttributesMap) Delete

func (a AttributesMap) Delete(key string)

Delete removes the attribute value at key, if any

func (AttributesMap) SetAttribute

func (a AttributesMap) SetAttribute(label string, value interface{})

SetAttribute sets the value for an attribute (unless empty).

func (AttributesMap) SetAttributes

func (a AttributesMap) SetAttributes(labelvalues ...interface{})

SetAttributes sets multiple values for attributes (unless empty) taking a label,value list E.g SetAttributes("style","filled","fillcolor","red")

func (AttributesMap) Value

func (a AttributesMap) Value(label string) interface{}

Value return the value added for this label.

type ClusterOption

type ClusterOption struct{}

func (ClusterOption) Apply

func (o ClusterOption) Apply(g *Graph)

type Edge

type Edge struct {
	AttributesMap
	// contains filtered or unexported fields
}

Edge represents a graph edge between two Nodes.

func (Edge) Attribute

func (e Edge) Attribute(name string) interface{}

Attribute returns the value stored by a name. Returns nil if missing.

func (Edge) Attributes

func (e Edge) Attributes() map[string]interface{}

Returns a copy of the attributes for this edge.

func (Edge) Bold

func (e Edge) Bold() Edge

Bold sets the edge attribute "style" to "bold"

func (Edge) Dashed

func (e Edge) Dashed() Edge

Dashed sets the edge attribute "style" to "dashed"

func (Edge) Dotted

func (e Edge) Dotted() Edge

Dotted sets the edge attribute "style" to "dotted"

func (Edge) Edge

func (e Edge) Edge(to Node, labels ...string) Edge

Edge returns a new Edge between the "to" node of this Edge and the argument Node.

func (Edge) EdgesTo

func (e Edge) EdgesTo(to Node) []Edge

EdgesTo returns all existing edges between the "to" Node of the Edge and the argument Node.

func (Edge) From

func (e Edge) From() Node

From returns the Node that this edge is pointing from.

func (Edge) Label

func (e Edge) Label(value interface{}) Edge

Label sets "label"=value and returns the Edge. Same as Attr("label",value)

func (Edge) ReverseEdge

func (e Edge) ReverseEdge(from Node, labels ...string) Edge

ReverseEdge returns a new Edge between the "from" node of this Edge and the argument Node.

func (Edge) SetAttribute

func (e Edge) SetAttribute(key string, value interface{}) Edge

SetAttribute sets key=value and returns the Edge.

func (Edge) Solid

func (e Edge) Solid() Edge

Solid sets the edge attribute "style" to "solid" Default style

func (Edge) To

func (e Edge) To() Node

To returns the Node that this edge is pointing to.

type Graph

type Graph struct {
	AttributesMap
	// contains filtered or unexported fields
}

Graph represents a dot graph with nodes and edges.

func NewGraph

func NewGraph(options ...GraphOption) *Graph

NewGraph return a new initialized Graph.

func (*Graph) AddToMaxRank

func (g *Graph) AddToMaxRank(nodes ...Node)

func (*Graph) AddToMinRank

func (g *Graph) AddToMinRank(nodes ...Node)

func (*Graph) AddToSameRank

func (g *Graph) AddToSameRank(nodes ...Node)

AddToSameRank adds the given nodes to the specified rank group, forcing them to be rendered in the same row

func (*Graph) AddToSinkRank

func (g *Graph) AddToSinkRank(nodes ...Node)

func (*Graph) AddToSourceRank

func (g *Graph) AddToSourceRank(nodes ...Node)

func (*Graph) DeepCopy

func (g *Graph) DeepCopy() *Graph

DeepCopy creates a deep copy of a Graph, including all nodes, edges, subgraphs & attributes

func (*Graph) DeleteNode

func (g *Graph) DeleteNode(id string) bool

DeleteNode deletes a node and all the edges associated to the node Returns false if the node wasn't found, true otherwise

func (*Graph) Edge

func (g *Graph) Edge(fromNode, toNode Node, labels ...string) Edge

Edge creates a new edge between two nodes. Nodes can have multiple edges to the same other node (or itself). If one or more labels are given then the "label" attribute is set to the edge.

func (*Graph) EdgeInitializer

func (g *Graph) EdgeInitializer(callback func(e Edge))

EdgeInitializer sets a function that is called (if not nil) when an Edge is implicitly created.

func (*Graph) EdgeWithPorts

func (g *Graph) EdgeWithPorts(fromNode, toNode Node, fromNodePort, toNodePort string, labels ...string) Edge

EdgeWithPorts creates a new edge between two nodes with ports. Other functionality are the same

func (*Graph) EdgesMap

func (g *Graph) EdgesMap() map[string][]Edge

EdgesMap returns a map with Node.id -> []Edge

func (*Graph) FindEdges

func (g *Graph) FindEdges(fromNode, toNode Node) (found []Edge)

FindEdges finds all edges in the graph that go from the fromNode to the toNode. Otherwise, returns an empty slice.

func (*Graph) FindNodeById

func (g *Graph) FindNodeById(id string) (foundNode Node, found bool)

FindNodeById return node by id

func (*Graph) FindNodeWithLabel

func (g *Graph) FindNodeWithLabel(label string) (Node, bool)

func (*Graph) FindNodes

func (g *Graph) FindNodes() (nodes []Node)

FindNodes returns all nodes recursively

func (*Graph) FindSubgraph

func (g *Graph) FindSubgraph(id string) (*Graph, bool)

FindSubgraph returns the subgraph of the graph or one from its parents.

func (*Graph) HasNode

func (g *Graph) HasNode(n Node) bool

HasNode returns whether the node was created in this graph (does not look for it in subgraphs).

func (*Graph) ID

func (g *Graph) ID() string

ID returns the identifier of the graph.

func (*Graph) IndentedWrite

func (g *Graph) IndentedWrite(w *IndentWriter)

IndentedWrite write the graph to a writer using simple TAB indentation.

func (*Graph) IsDirected

func (g *Graph) IsDirected() bool

IsDirected returns info about the graph type

func (*Graph) Label

func (g *Graph) Label(label string) *Graph

Label sets the "label" attribute value.

func (*Graph) Node

func (g *Graph) Node(id string) Node

Node returns the node created with this id or creates a new node if absent. The node will have a label attribute with the id as its value. Use Label() to overwrite this. This method can be used as both a constructor and accessor. not thread safe!

func (*Graph) NodeInitializer

func (g *Graph) NodeInitializer(callback func(n Node))

NodeInitializer sets a function that is called (if not nil) when a Node is implicitly created.

func (*Graph) Root

func (g *Graph) Root() *Graph

Root returns the top-level graph if this was a subgraph.

func (*Graph) SetID

func (g *Graph) SetID(newID string) *Graph

SetID sets the identifier of the graph.

func (*Graph) String

func (g *Graph) String() string

String returns the source in dot notation.

func (*Graph) Subgraph

func (g *Graph) Subgraph(id string, options ...GraphOption) *Graph

Subgraph returns the Graph with the given id ; creates one if absent. The label attribute is also set to the id ; use Label() to overwrite it.

func (*Graph) VisitNodes

func (g *Graph) VisitNodes(callback func(node Node) (done bool))

VisitNodes visits all nodes recursively

func (*Graph) Write

func (g *Graph) Write(w io.Writer)

type GraphOption

type GraphOption interface {
	Apply(*Graph)
}

type GraphTypeOption

type GraphTypeOption struct {
	Name string
}

func (GraphTypeOption) Apply

func (o GraphTypeOption) Apply(g *Graph)

type HTML

type HTML string

HTML renders the provided content as graphviz HTML. Use of this type is only valid for some attributes, like the 'label' attribute.

type IndentWriter

type IndentWriter struct {
	// contains filtered or unexported fields
}

IndentWriter decorates an io.Writer to insert leading TAB \t character per line

func NewIndentWriter

func NewIndentWriter(w io.Writer) *IndentWriter

NewIndentWriter returns a new IndentWriter with indent level 0.

func (*IndentWriter) BackIndent

func (i *IndentWriter) BackIndent()

BackIndent drops the level with one.

func (*IndentWriter) Indent

func (i *IndentWriter) Indent()

Indent raises the level and writes the extra \t (TAB) character.

func (*IndentWriter) IndentWhile

func (i *IndentWriter) IndentWhile(block func())

IndentWhile call the blocks after an indent and will restore that indent afterward.

func (*IndentWriter) NewLine

func (i *IndentWriter) NewLine()

NewLine writes the new line and a number of tab \t characters that matches the level count.

func (*IndentWriter) NewLineIndentWhile

func (i *IndentWriter) NewLineIndentWhile(block func())

NewLineIndentWhile is a variation of IndentWhile that produces extra newlines.

func (*IndentWriter) Write

func (i *IndentWriter) Write(data []byte) (n int, err error)

Write makes it an io.Writer

func (*IndentWriter) WriteString

func (i *IndentWriter) WriteString(s string) (n int, err error)

WriteString is a convenient Write.

type Literal

type Literal string

Literal renders the provided value as is, without adding enclosing quotes, escaping newlines, quotations marks or any other characters. For example:

node.Attr("label", Literal(`"left-justified text\l"`))

allows you to left-justify the label (due to the \l at the end). The caller is responsible for enclosing the value in quotes and for proper escaping of special characters.

type Node

type Node struct {
	AttributesMap
	// contains filtered or unexported fields
}

Node represents a dot Node.

func (Node) Attribute

func (n Node) Attribute(name string) interface{}

Attribute returns the value stored by a name. Returns nil if missing.

func (Node) BidirectionalEdge

func (n Node) BidirectionalEdge(toAndFromNode Node) []Edge

BidirectionalEdge adds two edges, marks the first as invisible and the second with direction "both". Returns both edges.

func (Node) Box

func (n Node) Box() Node

Box sets the attribute "shape" to "box"

func (Node) Edge

func (n Node) Edge(toNode Node, labels ...string) Edge

Edge sets label=value and returns the Edge for chaining.

func (Node) EdgesTo

func (n Node) EdgesTo(toNode Node) []Edge

EdgesTo returns all existing edges between this Node and the argument Node.

func (Node) Graph

func (n Node) Graph() *Graph

func (Node) ID

func (n Node) ID() string

ID returns the assigned id to this node.

func (Node) Label

func (n Node) Label(label string) Node

Label sets the attribute "label" to the given label

func (Node) NewRecordBuilder

func (n Node) NewRecordBuilder() *recordBuilder

NewRecordBuilder returns a new recordBuilder for setting the attributes for a record-shaped node. Call Build() on the builder to set the label and shape.

Example

https://graphviz.org/doc/info/shapes.html#record

digraph structs {
    node [shape=record];
    struct1 [label="<f0> left|<f1> mid&#92; dle|<f2> right"];
    struct2 [label="<f0> one|<f1> two"];
    struct3 [label="hello&#92;nworld |{ b |{c|<here> d|e}| f}| g | h"];
    struct1:f1 -> struct2:f0;
    struct1:f2 -> struct3:here;
}
g := NewGraph(Directed)

r1 := g.Node("struct1").NewRecordBuilder()
r1.FieldWithId("left", "f0")
r1.FieldWithId("mid&#92;dle", "f1")
r1.FieldWithId("right", "f2")
r1.Build()

r2 := g.Node("struct2").NewRecordBuilder()
r2.FieldWithId("one", "f0")
r2.Build()

r3 := g.Node("struct3").NewRecordBuilder()
r3.Field("hello&#92;world")
r3.Nesting(func() {
	r3.Field("b")
	r3.Nesting(func() {
		r3.Field("c")
		r3.FieldWithId("d", "here")
		r3.Field("e")
	})
	r3.Field("f")
})
r3.Field("g")
r3.Field("h")
r3.Build()

g.EdgeWithPorts(g.Node("struct1"), g.Node("struct2"), "f1", "f0")
g.EdgeWithPorts(g.Node("struct1"), g.Node("struct3"), "f2", "here")

fmt.Println(flatten(g.String()))
Output:

digraph  {n1[label="<f0> left|<f1> mid&#92;dle|<f2> right",shape="record"];n2[label="<f0> one",shape="record"];n3[label="hello&#92;world|{b|{c|<here> d|e}|f}|g|h",shape="record"];n1:f1->n2:f0;n1:f2->n3:here;}

func (Node) ReverseEdge

func (n Node) ReverseEdge(fromNode Node, labels ...string) Edge

ReverseEdge sets label=value and returns the Edge for chaining.

func (Node) SetAttribute

func (n Node) SetAttribute(label string, value interface{}) Node

SetAttribute sets label=value and return the Node

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL