Back to godoc.org

Package dot

v0.7.0
Latest Go to latest
Published: Feb 26, 2020 | License: BSD-3-Clause | Module: gonum.org/v1/gonum

Overview

Package dot implements GraphViz DOT marshaling and unmarshaling of graphs.

See the GraphViz DOT Guide and the DOT grammar for more information on using specific aspects of the DOT language:

DOT Guide: https://www.graphviz.org/pdf/dotguide.pdf

DOT grammar: http://www.graphviz.org/doc/info/lang.html

Attribute quoting

Attributes and IDs are quoted if needed during marshalling, to conform with valid DOT syntax. Quoted IDs and attributes are unquoted during unmarshaling, so the data is kept in raw form. As an exception, quoted text with a leading `"<` and a trailing `>"` is not unquoted to ensure preservation of the string during a round-trip.

Index

Examples

Package Files

func Marshal

func Marshal(g graph.Graph, name, prefix, indent string) ([]byte, error)

Marshal returns the DOT encoding for the graph g, applying the prefix and indent to the encoding. Name is used to specify the graph name. If name is empty and g implements Graph, the returned string from DOTID will be used.

Graph serialization will work for a graph.Graph without modification, however, advanced GraphViz DOT features provided by Marshal depend on implementation of the Node, Attributer, Porter, Attributers, Structurer, Subgrapher and Graph interfaces.

Attributes and IDs are quoted if needed during marshalling.

func MarshalMulti

func MarshalMulti(g graph.Multigraph, name, prefix, indent string) ([]byte, error)

MarshalMulti returns the DOT encoding for the multigraph g, applying the prefix and indent to the encoding. Name is used to specify the graph name. If name is empty and g implements Graph, the returned string from DOTID will be used.

Graph serialization will work for a graph.Multigraph without modification, however, advanced GraphViz DOT features provided by Marshal depend on implementation of the Node, Attributer, Porter, Attributers, Structurer, MultiSubgrapher and Multigraph interfaces.

Attributes and IDs are quoted if needed during marshalling.

func Unmarshal

func Unmarshal(data []byte, dst encoding.Builder) error

Unmarshal parses the Graphviz DOT-encoded data and stores the result in dst. If the number of graphs encoded in data is not one, an error is returned and dst will hold the first graph in data.

Attributes and IDs are unquoted during unmarshalling if appropriate.

Example (Weighted)

Code:

// Copyright ©2019 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dot_test

import (
	"fmt"
	"log"
	"math"
	"strconv"

	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/encoding"
	"gonum.org/v1/gonum/graph/encoding/dot"
	"gonum.org/v1/gonum/graph/simple"
)

// dotGraph provides a shim for interaction between the DOT
// unmarshaler and a simple.WeightedUndirectedGraph.
type dotGraph struct {
	*simple.WeightedUndirectedGraph
}

func newDotGraph() *dotGraph {
	return &dotGraph{WeightedUndirectedGraph: simple.NewWeightedUndirectedGraph(0, 0)}
}

// NewEdge returns a DOT-aware edge.
func (g *dotGraph) NewEdge(from, to graph.Node) graph.Edge {
	e := g.WeightedUndirectedGraph.NewWeightedEdge(from, to, math.NaN()).(simple.WeightedEdge)
	return &weightedEdge{WeightedEdge: e}
}

// NewNode returns a DOT-aware node.
func (g *dotGraph) NewNode() graph.Node {
	return &node{Node: g.WeightedUndirectedGraph.NewNode()}
}

// SetEdge is a shim to allow the DOT unmarshaler to
// add weighted edges to a graph.
func (g *dotGraph) SetEdge(e graph.Edge) {
	g.WeightedUndirectedGraph.SetWeightedEdge(e.(*weightedEdge))
}

// weightedEdge is a DOT-aware weighted edge.
type weightedEdge struct {
	simple.WeightedEdge
}

// SetAttribute sets the weight of the receiver.
func (e *weightedEdge) SetAttribute(attr encoding.Attribute) error {
	if attr.Key != "weight" {
		return fmt.Errorf("unable to unmarshal node DOT attribute with key %q", attr.Key)
	}
	var err error
	e.W, err = strconv.ParseFloat(attr.Value, 64)
	return err
}

// node is a DOT-aware node.
type node struct {
	graph.Node
	dotID string
}

// SetDOTID sets the DOT ID of the node.
func (n *node) SetDOTID(id string) { n.dotID = id }

func (n *node) String() string { return n.dotID }

const ug = `
graph {
	a
	b
	c
	a--b ["weight"=0.5]
	a--c ["weight"=1]
}
`

func ExampleUnmarshal_weighted() {
	dst := newDotGraph()
	err := dot.Unmarshal([]byte(ug), dst)
	if err != nil {
		log.Fatal(err)
	}
	for _, e := range graph.EdgesOf(dst.Edges()) {
		fmt.Printf("%+v\n", e.(*weightedEdge).WeightedEdge)
	}

	// Unordered output:
	// {F:a T:b W:0.5}
	// {F:a T:c W:1}
}
{F:a T:b W:0.5}
{F:a T:c W:1}

func UnmarshalMulti

func UnmarshalMulti(data []byte, dst encoding.MultiBuilder) error

UnmarshalMulti parses the Graphviz DOT-encoded data as a multigraph and stores the result in dst. If the number of graphs encoded in data is not one, an error is returned and dst will hold the first graph in data.

Attributes and IDs are unquoted during unmarshalling if appropriate.

type AttributeSetters

type AttributeSetters interface {
	// DOTAttributeSetters returns the global attribute setters.
	DOTAttributeSetters() (graph, node, edge encoding.AttributeSetter)
}

AttributeSetters is implemented by graph values that can set global DOT attributes.

type Attributers

type Attributers interface {
	DOTAttributers() (graph, node, edge encoding.Attributer)
}

Attributers are graph.Graph values that specify top-level DOT attributes.

type DOTIDSetter

type DOTIDSetter interface {
	SetDOTID(id string)
}

DOTIDSetter is implemented by types that can set a DOT ID.

type Graph

type Graph interface {
	graph.Graph
	DOTID() string
}

Graph wraps named graph.Graph values.

type MultiStructurer

type MultiStructurer interface {
	Structure() []Multigraph
}

MultiStructurer represents a graph.Multigraph that can define subgraphs.

type MultiSubgrapher

type MultiSubgrapher interface {
	Subgraph() graph.Multigraph
}

MultiSubgrapher wraps graph.Node values that represent subgraphs.

type Multigraph

type Multigraph interface {
	graph.Multigraph
	DOTID() string
}

Multigraph wraps named graph.Multigraph values.

type Node

type Node interface {
	// DOTID returns a DOT node ID.
	//
	// An ID is one of the following:
	//
	//  - a string of alphabetic ([a-zA-Z\x80-\xff]) characters, underscores ('_').
	//    digits ([0-9]), not beginning with a digit.
	//  - a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)?).
	//  - a double-quoted string ("...") possibly containing escaped quotes (\").
	//  - an HTML string (<...>).
	DOTID() string
}

Node is a DOT graph node.

type PortSetter

type PortSetter interface {
	// SetFromPort sets the From port and
	// compass direction of the receiver.
	SetFromPort(port, compass string) error

	// SetToPort sets the To port and compass
	// direction of the receiver.
	SetToPort(port, compass string) error
}

PortSetter is implemented by graph.Edge and graph.Line that can set the DOT port and compass directions of an edge.

type Porter

type Porter interface {
	// FromPort returns the port and compass for
	// the From node of a graph.Edge.
	FromPort() (port, compass string)

	// ToPort returns the port and compass for
	// the To node of a graph.Edge.
	ToPort() (port, compass string)
}

Porter defines the behavior of graph.Edge values that can specify connection ports for their end points. The returned port corresponds to the DOT node port to be used by the edge, compass corresponds to DOT compass point to which the edge will be aimed.

Example

Code:

// Copyright ©2018 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dot_test

import (
	"fmt"

	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/encoding/dot"
	"gonum.org/v1/gonum/graph/simple"
)

type edgeWithPorts struct {
	simple.Edge
	fromPort, toPort string
}

func (e edgeWithPorts) ReversedEdge() graph.Edge {
	e.F, e.T = e.T, e.F
	e.fromPort, e.toPort = e.toPort, e.fromPort
	return e
}

func (e edgeWithPorts) FromPort() (string, string) {
	return e.fromPort, ""
}

func (e edgeWithPorts) ToPort() (string, string) {
	return e.toPort, ""
}

func ExamplePorter() {
	g := simple.NewUndirectedGraph()
	g.SetEdge(edgeWithPorts{
		Edge:     simple.Edge{F: simple.Node(1), T: simple.Node(0)},
		fromPort: "p1",
		toPort:   "p2",
	})

	result, _ := dot.Marshal(g, "", "", "  ")
	fmt.Print(string(result))

	// Output:
	// strict graph {
	//   // Node definitions.
	//   0;
	//   1;
	//
	//   // Edge definitions.
	//   0:p2 -- 1:p1;
	// }
}
strict graph {
  // Node definitions.
  0;
  1;

  // Edge definitions.
  0:p2 -- 1:p1;
}

type Structurer

type Structurer interface {
	Structure() []Graph
}

Structurer represents a graph.Graph that can define subgraphs.

type Subgrapher

type Subgrapher interface {
	Subgraph() graph.Graph
}

Subgrapher wraps graph.Node values that represent subgraphs.

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier