Parses the Graphviz DOT language in golang

Overview

Parses the Graphviz DOT language and creates an interface, in golang, with which to easily create new and manipulate existing graphs which can be written back to the DOT format.

This parser has been created using gocc.

Example (Parse and Edit)

graphAst, _ := gographviz.ParseString(`digraph G {}`)
graph := gographviz.NewGraph()
if err := gographviz.Analyse(graphAst, graph); err != nil {
    panic(err)
}
graph.AddNode("G", "a", nil)
graph.AddNode("G", "b", nil)
graph.AddEdge("a", "b", true, nil)
output := graph.String()

Documentation

Installation

go get github.com/awalterschulze/gographviz

Build and Tests

Build Status

Users

  • aptly - Debian repository management tool
  • gorgonia - A Library that helps facilitate machine learning in Go
  • imagemonkey - Let's create our own image dataset
  • depviz - GitHub dependency visualizer (auto-roadmap)
  • kustomize-graph - A tool to visualize Kustomize dependencies
  • inframap - Read your tfstate or HCL to generate a graph specific for each Terraform provider
  • Antrea Traceflow supports using Traceflow for network diagnosis for Antrea, a Kubernetes networking solution intended to be Kubernetes native

Mentions

Using Golang and GraphViz to Visualize Complex Grails Applications

Issues
  • Typesafe (kinda) Attributes now available

    Typesafe (kinda) Attributes now available

    So, the attributes is now a static set (found in common/attributes.go). The API still takes a map[string]string but all public methods (AddNode, AddAttr etc) will call FromStringMap(), which will create a Attrs from the string map, and then pass them into private methods (addNode, addAttr, etc)

    This way, the API stays the same, per #4 .

    Caveat: I have also silenced the panic(err) in almost all of them because the test cases themselves are wrong/have wrong attributes. I'll probably leave that to someone else to fix. (grep for the below:)

    if err != nil {
        // panic(err)  // TODO: Fix...
    }```
    
    opened by chewxy 19
  • Fix Go module name

    Fix Go module name

    From https://blog.golang.org/using-go-modules:

    Each different major version (v1, v2, and so on) of a Go module uses a different module path: starting at v2, the path must end in the major version. In the example, v3 of rsc.io/quote is no longer rsc.io/quote: instead, it is identified by the module path rsc.io/quote/v3. This convention is called semantic import versioning

    Currently running go mod download in a module using github.com/awalterschulze/gographviz in version v2.0.2 results in the following error:

    github.com/awalterschulze/[email protected]+incompatible: invalid version: +incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required

    opened by piepmatz 16
  • Attributes and Errors

    Attributes and Errors

    This pull request contains backwards incompatible changes:

    1. Some methods now return errors, instead of panicing.
    2. Attributes are checked to be valid attributes.
    opened by awalterschulze 10
  • [Question] Is there any way to get the Node in a Graph?

    [Question] Is there any way to get the Node in a Graph?

    I want to edit a node attributes inside a graph. Is there any way to get the node by name of node and edit it? Like in nodejs package JNXnetwork we can do that by

    G.node.get(0).foo = 'bar';
    

    Is there anyway in this package to do that?

    Thanks

    opened by knrt10 9
  • Default attributes are not inherited by nodes or edges in subgraphs

    Default attributes are not inherited by nodes or edges in subgraphs

    Given an input graph with default node/edge attributes and a subgraph, like this one:

    digraph g {
        node [shape=record];
        edge [style=dashed];
        subgraph cluster_key {
            graph [label=KEY];
            key_user [fontcolor=red];
            key_dep  [fontcolor=blue];
            key_user -> key_dep;
        }
        A [fontcolor=red];
        B [fontcolor=blue];
        A -> B;
    }
    

    In the rendering from dot, the default attributes are inherited by the objects in the subgraph:

    image

    but gographviz only applies the attributes to the top-level objects, not the ones in the subgraph:

    image

    opened by nkitchen 9
  • how to set `node[shape=box style=rounded labelloc=b]` global attribute?

    how to set `node[shape=box style=rounded labelloc=b]` global attribute?

    image

    it's not allowed use like this:

    graph.AddAttr(workflowName, "node", "shape=rect style=rounded, labelloc=b")
    

    but if set attribute one by one, it will not take affect.

    graph.AddAttr(workflowName, "shape", "rect")
    graph.AddAttr(workflowName, "style", "rounded")
    graph.AddAttr(workflowName, "labelloc", "b")
    

    image

    opened by tsjsdbd 8
  • Nesting cluster subgraphs doesn't work

    Nesting cluster subgraphs doesn't work

    What I am trying to achive:

    pic

    Code I used:

    g := gographviz.NewGraph()
    g.SetName("G")
    g.SetDir(true)
    
    g.AddNode("G", "Ga", nil)
    g.AddNode("G", "Gb", nil)
    g.AddEdge("Ga", "Gb", true, nil)
    
    g.AddSubGraph("G", "clusterone", map[string]string{
        "style": "filled", 
        "fillcolor": "red",
    })
    g.AddNode("clusterone", "sA", nil)
    g.AddNode("clusterone", "sB", nil)
    g.AddEdge("sA", "sB", true, nil)
    
    g.AddSubGraph("clusterone", "clustertwo", map[string]string{
        "style": "filled", 
        "fillcolor": "blue",
    })
    g.AddNode("clustertwo", "ssA", nil)
    g.AddNode("clustertwo", "ssB", nil)
    g.AddEdge("ssA", "ssB", true, nil)
    
    fmt.Println(g.String())
    

    However this is what the result looked like:

    pic2

    Am I doing something wrong?

    opened by ofabry 8
  • Quote node IDs and attributes

    Quote node IDs and attributes

    Hi there, thanks for this package.

    My node IDs and attribute values disagree strongly with the DOT schema, and I've found that I have to quote them in order for tools like Gephi to parse them as they all are of type "ID".

    Could gographviz detect the need to quote/escape anything that it needs to write out as type ID and do so automatically so I don't have to add the quotes myself? Here's an example that produces an unreadable file:

    graph := gographviz.NewGraph()
    graph.SetName("G")
    graph.AddNode("G", "331fb1985e8884cfaaae65be7f8cfe5b", gographviz.Attrs{"label": "1:6:1w/w/PYqH7d1+6Fg"})
    graph.AddEdge("331fb1985e8884cfaaae65be7f8cfe5b", "ec2f3d34a4f4c4f82dd1d0b2f1a581e", gographviz.Attrs{"label": "FOO_BAR"})
    os.Stdout.Write(gographviz.WriteAst().String())
    

    Thanks!

    opened by joshk0 8
  • How to get subtree based on parent node?

    How to get subtree based on parent node?

    Hi,

    first of all, many thanks for the great library - it's really a pleasure to use!

    I am currently evaluating gographviz for another project (https://github.com/bbernhard/imagemonkey-core) and would be glad if I could use it there.

    One thing I am currently struggling with is, the possibility to extract a subtree based on a given label. If I understood the documentation correctly, then that's what SortedChildren is meant to be for. However, for some obscure reason it doesn't seem to work - it looks like I have messed something up here.

    Here is a small code snippet which illustrates my problem. truck, bike, motorbike and car are all children of vehicle. When asking gographviz for the label vehicle I would like to get a list of all its children. I tried to accomplish that with graph.Relations.SortedChildren("vehicle") but that returns an empty list.

    I am pretty sure that I have missed something here and would be glad, if you could point me in the right direction.

    Thanks a lot, Bernhard

    package main
    
    import (
    	"bytes"
    	"os"
    	"fmt"
    	"github.com/awalterschulze/gographviz"
    )
    
    func main() {
    	graphAst, _ := gographviz.ParseString(`
    		digraph G { 
    			{ 
    				car [label="car" id="94bbd2ff-8a8e-4d1c-9ac5-f9506aa20e43"] 
    				vehicle [color=green style=filled label="vehicle"] 
    				truck [label="truck"] 
    			} 
    			
    		   vehicle -> truck
    		    vehicle -> car
    		    vehicle -> motorbike
    		    vehicle -> bike
    		}
    	`)
    	graph := gographviz.NewGraph()
    	graph.SetDir(true)
    	if err := gographviz.Analyse(graphAst, graph); err != nil {
        	panic(err)
    	}
    
    	childrens := graph.Relations.SortedChildren("vehicle")
    	for _, child := range childrens {
    		fmt.Printf("%s\n", child)
    	}
    }
    
    opened by bbernhard 7
  • Make cluster subgraphs as nodes for edges

    Make cluster subgraphs as nodes for edges

    There's an issue where making edges between cluster subgraphs (which are useful with fdp) would double subgraphs in output string.

    Consider this code:

    g := gographviz.NewEscape()
    g.SetName("G")
    g.SetDir(false)
    g.AddSubGraph("G", "cluster0", map[string]string{"label": "root"})
    g.AddSubGraph("cluster0", "cluster_1", map[string]string{"label": "child 1"})
    g.AddSubGraph("cluster0", "cluster_2", map[string]string{"label": "child 2"})
    nodeStyle := map[string]string{"style": "rounded"}
    g.AddNode("cluster_1", "1", nodeStyle)
    g.AddNode("cluster_1", "2", nodeStyle)
    g.AddNode("cluster_2", "3", nodeStyle)
    g.AddNode("cluster_2", "4", nodeStyle)
    g.AddNode("G", "Code deployment", map[string]string{"style": "dotted"})
    g.AddPortEdge("cluster_2", "", "cluster_1", "", false, nil)
    s := g.String()
    fmt.Println(s)
    

    It currently renders such code, which is incorrect and would not render:

    graph G { subgraph cluster_2 { label="child 2"; 3 [ style=rounded ]; 4 [ style=rounded ];

    } --subgraph cluster_1 { label="child 1"; 1 [ style=rounded ]; 2 [ style=rounded ];

    }; subgraph cluster0 { label=root; subgraph cluster_1 { label="child 1"; 1 [ style=rounded ]; 2 [ style=rounded ];

    } ; subgraph cluster_2 { label="child 2"; 3 [ style=rounded ]; 4 [ style=rounded ];

    } ;

    } ; "Code deployment" [ style=dotted ];

    }

    After the patch applied it would make such code (subgraphs starting with cluster would be rendered as nodes for edges): graph G { cluster_2--cluster_1; subgraph cluster0 { label=root; subgraph cluster_1 { label="child 1"; 1 [ style=rounded ]; 2 [ style=rounded ];

    } ; subgraph cluster_2 { label="child 2"; 3 [ style=rounded ]; 4 [ style=rounded ];

    } ;

    } ; "Code deployment" [ style=dotted ];

    }

    opened by Didainius 7
  • Replace travis job with github action.

    Replace travis job with github action.

    Created github action that performs the same tasks as travis job.

    Note that the badge in Readme.md is already pointing to https://github.com/awalterschulze/gographviz to work correctly when merged.

    opened by jmrtt 6
  • Extend does not escape attributes

    Extend does not escape attributes

    I am using the following to update node labels in an Escape

    graph.Nodes.Lookup[id].Attrs.Extend(attrs)
    

    but the new label is not automatically escaped. Maybe there is a better way to update node attributes that I'm missing.

    On the other hand, if this is a bug, I'd happy to try to fix it. At a first glance at the implementation, it does not look like the escaping logic is executed for any Attrs method.

    Thanks!

    opened by rupanshusoi 3
  • How to define default attributes for node, edge, or graph

    How to define default attributes for node, edge, or graph

    Hi, all.

    I am trying to use the node, edge, and graph statement from the Lexical and Semantic Notes. However, since this library always sorts and prints nodes, the order is changed. How can I always define it first?

    Output:

    digraph G {
    	rank=LR;
    	Hello->World[ headlabel="head", taillabel="tail" ];
    	Hello->World:f0;
    	Hello->World:f1;
    	Hello->World:f2;
    	Hello [ label="Hi\nStart", shape=Mrecord ];
    	World [ label="<f0>one|<f1>two|<f2>three", shape=Mrecord ];
    	node [ shape=Mrecord ];
    }
    

    You can see that the node line is defined last.

    Expected:

    digraph G {
    	node [ shape=Mrecord ];  <-------------- This line
    	rank=LR;
    	Hello->World[ headlabel="head", taillabel="tail" ];
    	Hello->World:f0;
    	Hello->World:f1;
    	Hello->World:f2;
    	Hello [ label="Hi\nStart", shape=Mrecord ];
    	World [ label="<f0>one|<f1>two|<f2>three", shape=Mrecord ];
    }
    

    Only when defined like this, the output I want is completed.

    Looking at the source code, there seem to be no solutions. For now, is the only way to add properties to each node?

    ...
    go 1.14
    
    require github.com/awalterschulze/gographviz v2.0.1+incompatible
    ...
    
    opened by DreamerKMP 3
  • quoted string and its quirks

    quoted string and its quirks

    From the spec http://www.graphviz.org/content/dot-language

    As another aid for readability, dot allows double-quoted strings to span
    multiple physical lines using the standard C convention of a backslash
    immediately preceding a newline character.
    
    In addition, double-quoted strings can be concatenated using a '+' operator.
    
    opened by awalterschulze 3
  • isNumber accepts non-numbers

    isNumber accepts non-numbers

    isNumber in escape.go is supposed to return true if it is passed a string that represents a number. However, it accepts "127.0.0.1" as a number but dot does not accept that. More generally it allows an arbitrary number of "."s in a number. This causes strings to not be escaped when they should be.

    opened by drt24 2
Releases(v2.0.3)
  • v2.0.3(Nov 3, 2020)

  • v2.0.2(Oct 20, 2020)

  • v2.0.1(Apr 5, 2020)

  • v2.0(Apr 10, 2017)

    version 2.0 includes some backwards incompatible changes:

    • panics have been removed and replaced with the returning of errors.
    • attribute name validation has been added as has been requested multiple times.
    • golint and errcheck are now applied to the build.

    These backwards incompatible changes were not made lightly and only because it increases the maturity of the package.

    Source code(tar.gz)
    Source code(zip)
  • v1.1(Mar 23, 2017)

  • v1.0(Oct 1, 2016)

    Generated using gocc 1.0 Hand written scanner Open Issues:

    • https://github.com/awalterschulze/gographviz/issues/13
    • https://github.com/awalterschulze/gographviz/issues/12
    • https://github.com/awalterschulze/gographviz/issues/11
    • https://github.com/awalterschulze/gographviz/issues/10
    • https://github.com/awalterschulze/gographviz/issues/9
    • https://github.com/awalterschulze/gographviz/issues/4
    Source code(tar.gz)
    Source code(zip)
Owner
Walter Schulze
Pair programmer with an interest in language design.
Walter Schulze
Go language bindings for the COIN-OR Linear Programming library

clp Description The clp package provides a Go interface to the COIN-OR Linear Programming (CLP) library, part of the COIN-OR (COmputational INfrastruc

Los Alamos National Laboratory 34 Jun 6, 2022
Naive Bayesian Classification for Golang.

Naive Bayesian Classification Perform naive Bayesian classification into an arbitrary number of classes on sets of strings. bayesian also supports ter

Jake Brukhman 735 Jun 30, 2022
Implements a simple floating point arithmetic expression evaluator in Go (golang).

evaler https://github.com/soniah/evaler Package evaler implements a simple floating point arithmetic expression evaluator. Evaler uses Dijkstra's Shun

Sonia Hamilton 49 Jun 4, 2022
Golang RServe client. Use R from Go

Roger Roger is a Go RServe client, allowing the capabilities of R to be used from Go applications. The communication between Go and R is via TCP. It i

Senseye 260 Jun 1, 2022
A well tested and comprehensive Golang statistics library package with no dependencies.

Stats - Golang Statistics Package A well tested and comprehensive Golang statistics library / package / module with no dependencies. If you have any s

Montana Flynn 2.5k Jun 26, 2022
Parses the Graphviz DOT language in golang

Parses the Graphviz DOT language and creates an interface, in golang, with which to easily create new and manipulate existing graphs which can be writ

Walter Schulze 484 Jun 25, 2022
Ltree Visualizer - A golang library to visualize postgres ltree type data using DOT language and Graphviz

Ltree Visualizer A golang library to visualize postgres ltree type data using DOT language and Graphviz What is Ltree? Ltree is a data type which is u

Vasubabu Jinagam 8 Jun 12, 2022
Converts 'go mod graph' output into Graphviz's DOT language

modgv Converts 'go mod graph' output into GraphViz's DOT language. takes no options or arguments it reads the output generated by “go mod graph” on st

Luca Sepe 407 Jun 24, 2022
Go package for writing descriptions using the Graphviz DOT language

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

Ernest Micklei 227 Jun 27, 2022
An ease to use finit state machine golang implementation.Turn any struct to a fsm with graphviz visualization supported.

go-fsm An ease to use finit state machine golang implementation.Turn any struct to a fsm with graphviz visualization supported. usage import github.co

FingerLiu 5 Dec 26, 2021
Visualize call graph of a Go program using Graphviz

go-callvis go-callvis is a development tool to help visualize call graph of a Go program using interactive view. Introduction The purpose of this tool

Ondrej Fabry 4.2k Jun 29, 2022
Visualize call graph of a Go program using Graphviz

go-callvis go-callvis is a development tool to help visualize call graph of a Go program using interactive view. Introduction The purpose of this tool

Ondrej Fabry 4.2k Jul 2, 2022
Slice graph uses graphviz in order to pretty print slices for you.

slicegraph Slice graph uses graphviz in order to make you understand what happens underneath your slices.

Jędrzej 34 Mar 7, 2022
Visualize your Go data structures using graphviz

memviz How would you rather debug a data structure? "Pretty" printed Visual graph (*test.fib)(0xc04204a5a0)({ index: (int) 5, prev: (*test.fib)(0xc0

Bradley Kemp 1.3k Jun 15, 2022
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP

config A small configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP. Example func main() {

Josh Betz 210 Apr 10, 2022
:evergreen_tree: Parses indented code and returns a tree structure.

codetree Parses indented code (Python, Pug, Stylus, Pixy, codetree, etc.) and returns a tree structure. Installation go get github.com/aerogo/codetree

Aero 20 Mar 6, 2022
Parses Go tracebacks and finds possible deadlocks

findlock Parses Go tracebacks and finds possible deadlocks This works by checking how many locks have the same memory address. If there are multiple g

Luka Napotnik 28 Feb 16, 2022
Package gostackparse parses goroutines stack traces as produced by panic() or debug.Stack() at ~300 MiB/s.

gostackparse Package gostackparse parses goroutines stack traces as produced by panic() or debug.Stack() at ~300 MiB/s. Parsing this data can be usefu

Datadog, Inc. 75 Apr 25, 2022
Parses a file and associate SQL queries to a map. Useful for separating SQL from code logic

goyesql This package is based on nleof/goyesql but is not compatible with it any more. This package introduces support for arbitrary tag types and cha

null 0 Oct 20, 2021
This utility parses stackoverflow data and pushes it to Zinc/Elasticsearch

Gostack This utility parses stackoverflow data and pushes it to Zinc/Elasticsear

Prabhat Sharma 6 Jun 8, 2022
Peerconnection_explainer - PeerConnection-Explainer parses WebRTC Offers/Answers then provides summaries and suggestions

PeerConnection Explainer PeerConnection Explainer decodes WebRTC... so you don't have too! PeerConnection Explainer parses WebRTC Offers/Answers then

Pion 33 Jun 30, 2022
BRUS - Parses your web server (e.g. nginx) log files and checks with GreyNoise how much noise your website is exposed to.

BRUS bbbbbb rrrrrr u u sssss b b r r u u s bbbbbb rrrrrr u u sssss b b r r u u s bbbbbb r r

dubs3c 1 May 29, 2022
This project parses all mails from google-search within key-words and ban-words

mailParser This project parses all mails from google-search within key-words and ban-words For launch program create the input file first string conta

null 0 Feb 2, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Charles Banning 521 Jun 28, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Charles Banning 520 Jun 19, 2022
A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ.

q A tiny command line DNS client with support for UDP, DoT, DoH, and DoQ. Usage q command line DNS client (https://github.com/natesales/q) Usage: q

Nate Sales 670 Jun 28, 2022
GoLobby DotEnv is a lightweight package for loading dot env (.env) files into structs for Go projects

DotEnv GoLobby DotEnv is a lightweight package for loading dot env (.env) files into structs for Go projects Documentation Supported Versions It requi

GoLobby 12 Apr 5, 2022
🔄 Maintain a local copy of you dot files

Dotup This command line is in charge of maintaining a local copy of you dot files from a <source> folder. It copies all the files in the <source> fold

Kevin Disneur 2 Oct 20, 2021
DNS/DoT to DoH proxy with load-balancing, fail-over and SSL certificate management

dns-proxy Configuration Variable Example Description TLS_DOMAIN my.duckdns.org Domain name without wildcards. Used to create wildcard certificate and

Dimitri Herzog 3 Nov 23, 2021