Module nimgraphviz

The nimgraphviz module is a library for making graphs using GraphViz based on PyGraphviz.

To export images, you must have GraphViz installed. Download it here: https://graphviz.gitlab.io/download

Here is an example of creating a simple graph:

# create a directed graph
var graph = initGraph(directed=true)

# set some attributes of the graph:
graph.graphAttr.add("fontsize", "32")
graph.graphAttr.add("label", "Test Graph")

# add edges:
# (if a node does not exist already it will be created automatically)
graph.addEdge("a", "b", "a-to-b", [("label", "A to B")])
graph.addEdge("c", "b", "c-to-b", [("style", "dotted")])
graph.addEdge("b", "a", "b-to-a")
graph.addNode("c", [("color", "blue"), ("shape", "box"),
                    ("style", "filled"), ("fontcolor", "white")])
graph.addNode("d", [("lable", "node")])

# if you want to export the graph in the DOT language,
# you can do it like this:
# echo graph.exportDot()

# Export graph as PNG:
graph.exportImage("test_graph.png")

Types

Edge = tuple[a, b, key: string]
Graph = object
  name*: string
  isDirected*: bool            ## Whether or not the graph is directed
  graphAttr*: Table[string, string] ## A table of key-value pairs
                                 ## describing the layout and
                                 ## appearence of the graph
  edgesTable: Table[string, HashSet[Edge]]
  edgeAttrs: Table[Edge, Table[string, string]]
  nodeAttrs: Table[string, Table[string, string]]
The name of the graph

Procs

proc setGraphVizPath(path: string) {.
raises: [], tags: []
.}
sets the directory to search for the GraphViz executable (dot) if it is not in your PATH. should end in a delimiter ("/" or "\")
proc initGraph(name: string = nil; directed = false): Graph {.
raises: [], tags: []
.}
proc addEdge(self: var Graph; a, b: string; key: string = nil) {.
raises: [KeyError], tags: []
.}
the same as addEdge*(self: var Graph, a, b: string, key: string, attrs: openArray[(string, string)]) but without attributes and key is optional
proc addEdge(self: var Graph; a, b: string; key: string;
            attrs: openArray[(string, string)]) {.
raises: [KeyError], tags: []
.}

Adds an edge to the graph connecting nodes a and b. If the nodes don't already exist in the graph, they will be created

key is an identifier for the edge. It can be useful when you want to have multiple edges between the same two nodes

attrs is a set of key-value pairs specifying styling attributes for the edge. You can call addEdge again multiple times with the same nodes and key and different attrs to add new attributes

For example: .. code-block:: nim

var graph = initGraph() graph.addEdge("a", "b", nil, [("color", "blue")]) graph.addEdge("a", "b", nil, [("style", "dotted")])

will create a graph with a single dotted, blue edge

proc edges(self: Graph): seq[Edge] {.
raises: [KeyError], tags: []
.}
A list of all the edges in the graph (An edge is a three-tuple of two nodes and the edge key)
proc edges(self: Graph; nbunch: string): seq[Edge] {.
raises: [KeyError], tags: []
.}
A list of all the edges in the graph that are adjacent to the given node (coming in or out) (An edge is a three-tuple of two nodes and the edge key)
proc addNode(self: var Graph; key: string; attrs: openArray[(string, string)]) {.
raises: [KeyError], tags: []
.}

Adds a node to the graph. key is the name of the node, used to refer to it when creating edges, etc. It will be used as the label unless another label is given

attrs is a set of key-value pairs describing layout attributes for the node. You can call addNode() for an existing node to update its attributes

proc nodes(self: Graph): seq[string] {.
raises: [], tags: []
.}
Returns a seq of the nodes in the graph
proc degree(self: Graph; node: string): int {.
raises: [KeyError], tags: []
.}
The number of edges adjacent to the given node (in or out)
proc inDegree(self: Graph; node: string): int {.
raises: [KeyError], tags: []
.}
The number of edges into the given node If the graph is directed, it is the same as degree()
proc outDegree(self: Graph; node: string): int {.
raises: [KeyError], tags: []
.}
The number of edges out of the given node If the graph is directed, it is the same as degree()
proc exportDot(self: Graph): string {.
raises: [KeyError], tags: []
.}
Returns a string describing the graph GraphViz's dot language.
proc exportImage(self: Graph; fileName: string = nil; layout = "dot"; format = "png") {.
raises: [ SystemError, KeyError, OSError, Exception, ValueError, GraphVizException], tags: [ ExecIOEffect, ReadIOEffect, RootEffect, ReadEnvEffect, WriteIOEffect]
.}

Exports the graph as an image file.

filename - the name of the file to export to. Should include ".png" or the appropriate file extension. If none is given, it will default to the name of the graph. If that is nil, it will default to graph.png

layout - which of the GraphViz layout engines to use. Default is dot. Can be one of: dot, neato, fdp, sfdp, twopi, circo (or others if you have them installed).

format - the output format to export to. The default is png. You can specify more details with "{format}:{rendering engine}:{library}". (See GV command-line docs for more details)

Iterators

iterator iterEdges(self: Graph): Edge {.
raises: [KeyError], tags: []
.}
iterator over all the edges in the graph. An edge is a three-tuple of two nodes and the edge key
iterator iterEdges(self: Graph; nbunch: string): Edge {.
raises: [KeyError], tags: []
.}
iterator over all the edges in the graph that are adjacent to the given node (coming in or out). Yields three-tuples of two nodes and the edge key
iterator iterNodes(self: Graph): string {.
raises: [], tags: []
.}
Iterates over all of the nodes in the graph