Crate dot_writer[][src]

Expand description

Graphviz Writer

This library is a (hopefully) ergonomic library for plotting graphs. It outputs the Graphviz language DOT. Graphs written in DOT can then be easily converted to SVG or other image formats using the Graphviz dot executable.

The structs in this library leverage the Rust type system and lifetimes to ensure that it’s (in theory) impossible to use them to construct an invalid DOT graph. It’s important to note that this means you need to make sure that child structs go out of scope before using their parents again. This is to make sure that the Drop writes the closing brackets correctly.

Non Goals

This library only writes DOT in a strongly typed way. It doesn’t read DOT or render DOT into image files.

Usage

The first part of the library is the DotWriter struct, which is constructed from a mutable reference to any struct that implements std::io::Write (for example std::io::stdout() or even just a Vec<u8>). This DotWriter can then be used to construct a graph:

use dot_writer::{Color, DotWriter};

let mut output_bytes = Vec::new();
{
    let mut writer = DotWriter::from(&mut output_bytes);
    writer.set_pretty_print(false);
    writer
        .digraph()
        .edge("Hello", "World"); // digraph goes out of scope here, writing closing bracket
    // writer goes out of scope here, freeing up output_bytes for reading
}
assert_eq!(
    String::from_utf8(output_bytes).unwrap(),
    "digraph {Hello->World;}"
);

If instead you used std::io::stdout() or wrote to a file using File or BufReader, you could then use the dot executable:

$ echo "digraph {Hello->World;}" | dot -Tsvg > mygraph.svg

To generate an image (you can open in firefox or chrome, or switch the image type to png and use an image viewer of your choice):

Hello World example graph

Heres a more complex example, demonstrating clustering, colors, labeling and shapes:

use dot_writer::{Color, DotWriter, Attributes, Shape, Style};

let mut output_bytes = Vec::new();
{
    let mut writer = DotWriter::from(&mut output_bytes);
    writer.set_pretty_print(false);
    let mut digraph = writer.digraph();
    {
        let mut cluster = digraph.cluster();
        cluster.set_style(Style::Filled);
        cluster.set_color(Color::LightGrey);
        cluster.node_attributes()
            .set_style(Style::Filled)
            .set_color(Color::White);
        cluster.edge("a0", "a1").edge("a2").edge("a3");
        cluster.set_label("process #1");
        // cluster goes out of scope here to write closing bracket
    }
    {
        let mut cluster = digraph.cluster();
        cluster.node_attributes()
            .set_style(Style::Filled);
        cluster.edge("b0", "b1").edge("b2").edge("b3");
        cluster.set_label("process #2");
        cluster.set_color(Color::Blue);
        // cluster goes out of scope here to write closing bracket
    }
    digraph.edge("start", "a0");
    digraph.edge("start", "b0");
    digraph.edge("a1", "b3");
    digraph.edge("b2", "a3");
    digraph.edge("a3", "a0");
    digraph.edge("a3", "end");
    digraph.edge("b3", "end");
    digraph.node_named("start")
        .set_shape(Shape::Mdiamond);
    digraph.node_named("end")
        .set_shape(Shape::Msquare);
    // digraph goes out of scope here to write closing bracket
    // then writer goes out of scope here to free up output_bytes for reading
}
assert_eq!(
    String::from_utf8(output_bytes).unwrap(),
    "digraph {subgraph cluster_0 {style=\"filled\";color=lightgray;node [style=\"filled\", color=white];a0->a1->a2->a3;label=\"process #1\";}subgraph cluster_1 {node [style=\"filled\"];b0->b1->b2->b3;label=\"process #2\";color=blue;}start->a0;start->b0;a1->b3;b2->a3;a3->a0;a3->end;b3->end;start [shape=Mdiamond];end [shape=Msquare];}"
);

This produces (after render with dot) the following lovely graph:

More complex example graph

Structs

AttributesList

An AttributesList sets the attributes of an edge or node. See the Attributes trait for more information.

DotWriter

The entry point struct for writing a DOT graph. See the examples on the index for how to use it. This struct must live for the livetime of writing the graph, and also outlive the Write struct it points to, because it’s Drop trait will finish writing graph.

EdgeList

An EdgeList is returned from Scope::edge and can be used to set the attributes of an edge, or to chain additional nodes onto the edge statement.

Node

A Node is returned from Scope::node_named or Scope::node_auto, and allows for getting the id of the node for future reference via Node::id,

NodeId

A NodeId wraps a string storing the Id of a Node It’s designed for use with the Scope::edge function, and for creating PortId using NodeId::port.

PortId

A PortId wraps a string referning to the nnode id and port of a specifc record or Mrecord node (for more information see “Record-based Nodes” in the Graphviz documentation).

PortPosId

A PortPosId wraps a string referning to the NodeId, PortId and PortPosition of a specifc record or Mrecord node (for more information see “portPos” in the Graphviz documentation).

Scope

A Scope struct represents either a graph, digraph, subgraph or cluster. Its the workhorse of the DOT writing, and can be used to create new sub-scopes, add nodes, add edges, or adjust default attributes for any of the above.

Enums

Color

Color of a line or fill. This list is far from comprehensive, the full list is visible here, and can instead be set using Attributes::set

PortPosition

Refers the position to add an edge for of a specifc record or Mrecord node (for more information see “portPos” in the Graphviz documentation).

Rank

Node rank type, for more information see Graphviz documentation.

Shape

Shape of a component. This list is not comprehensive, the full list is visible here and can instead be set using Attributes::set.

Style

Style of design. Note that some of these or only valid for certain combinations of node, edge and cluster. See documentation here for more information.

Traits

Attributes

Structs that implement Attributes are used for writing the attributes of a diagraph, graph, subgraph, subgraph cluster, node or edge.