Crate dot_writer
source ·Expand description
Graphviz Writer
This library is an 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 hard
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. The compiler will tell you if you forget to do this though.
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 to create an image file:
$ echo "digraph {Hello->World;}" | dot -Tsvg > mygraph.svg
This generate the following image (you can open in firefox or chrome, or switch the image type to png
and use an image viewer of your choice):
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:
Structs
AttributesList
sets the attributes of an edge or node.
See the Attributes
trait for more information on what fields can be set.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
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
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
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
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).Enums
Attributes::set
Attributes::set
.Traits
Attributes
are used for writing the attributes
of a diagraph, graph, subgraph, subgraph cluster, node or edge.