Expand description
§GraphWiz.
Builders to generate and render graphs in the GraphViz DOT format.
§Example
The test file example.rs contains the following:
use goldie;
use graphwiz::attributes as attrs;
use graphwiz::*;
use std::collections::HashMap;
#[test]
fn example() {
let mut root = Graph::new_builder();
root.defaults_mut(Kind::Node).extend(HashMap::from([
(attrs::FILLCOLOR, "lavender".to_string()),
(attrs::STYLE, "filled".to_string()),
]));
let a = root.new_node("a");
let b = root.new_node("b");
let ab = root.new_edge(a, b);
root.attributes_mut(ab)
.insert(attrs::STYLE, "dotted".to_string());
let mut cluster = root.new_cluster("box");
let c = cluster.new_node_with(
"c",
HashMap::from([
(attrs::SHAPE, "circle".to_string()),
(attrs::FILLCOLOR, "cornflowerblue".to_string()),
]),
);
cluster.build();
root.new_edge(c, a);
root.new_edge(c, b);
let graph = root.build();
goldie::assert!(render_digraph(&graph));
}This generates the following DOT graph.
digraph {
node_1 [fillcolor="lavender", label="a", style="filled"]
node_2 [fillcolor="lavender", label="b", style="filled"]
node_1 -> node_2 [style="dotted"]
node_5 -> node_1
node_5 -> node_2
subgraph cluster_4 {
label="box"
node_5 [fillcolor="cornflowerblue", label="c", shape="circle", style="filled"]
}
}Which DOT renders like this:
§Usage
The only way to create a graph is to obtain a RootBuilder. You can do so with Graph::new_builder. This type implements the Builder trait, which lets you create one of the four kinds of graph entities: nodes, edges, subgraphs, or clusters1. Once you are done, a call to RootBuilder::build will finalize the build and give you a Graph, which you can then render using one of the rendering functions such as render_digraph.
§Entities
When created, any element gives you an Entity, which is a lightweight and opaque identifier. It uniquely identifies said entity within the graph, regardless of its label, and is therefore used to build edges.
Nodes and edges return the corresponding Entity immediately upon creation, but subgraphs and clusters only do so when their builder is finalized.
§Edges
new_edge is smart, and will let you link two entities regardless of their Kind. If one end of an edge is another edge, the newly created edge will be a “continuation” of the previous one:
use graphwiz::{Graph, Builder};
let mut root = Graph::new_builder();
let a = root.new_node("a");
let b = root.new_node("b");
let c = root.new_node("c");
let d = root.new_node("d");
let ab = root.new_edge(a, b);
let cd = root.new_edge(c, d);
let bc = root.new_edge(ab, cd);If one of the two ends of an edge is a subgraph or a cluster, then the graph’s compound attribute will atumatically be set to “true”, and the edge will be altered to match the required DOT syntax: the edge will be between nodes within the given subgraphs / clusters, but the lhead or ltail attributes will be set properly.
§Subgraphs
When you call new_subgraph or new_cluster, you obtain a new builder, specifically a SubgraphBuilder. It also implements the Builder trait, meaning you can use it to build new nodes, edges, subgraphs, or clusters. Each Builder creates entities within its own scope.
Crucially, every builder holds a mutable reference to the underlying Graph, meaning only one builder can be used at a time. A child builder must be finalized to release its hold on the reference, allowing the parent to be used again. SubgraphBuilder implements the Drop trait to finalize the build properly, meaning calling build isn’t required.
§Attributes
Each entity has attributes associated to it, which is a simple mapping from &str to String. The attributes module provides constants for every known attribute, but having the key be an arbitrary &str makes this more flexible. Some attributes are automatically set, such as a node or a cluster’s label.
You can provide default attribute values for a given Kind of entity using a builder’s defaults functions. Defaults are scoped, meaning that changes made to the defaults in a builder are not forwarded back to its parent, but builders for subgraphs get initialized with a copy of their parent’s defaults, which allows you to “scope” them.
Any builder has access to the full graph, meaning that you can always use the current builder’s attributes function to access or modify any entity’s attributes, even if it was created by a different builder.
§Rendering
Each render function takes a Graph and creates a String that represents said graph. You can choose between rendering the graph as directed or undirected, and optionally as strict. See GraphViz’s documentation for more information about the distinction.
Clusters are a peculiarity of DOT: they are subgraphs whose name happen to start with “cluster”. They are rendered, while other subgraphs are not. This library treats them as different for the purpose of allowing different default attributes for each. ↩
Modules§
- attributes
- DOT Attributes.
Structs§
- Entity
- Unique identifier for a graph entity.
- Graph
- Resulting graph.
- Root
Builder - Builder for the root graph.
- Subgraph
Builder - Builder for all subgraphs.
Enums§
- Kind
- Simple enum representing the four kinds of entities.
Traits§
- Builder
- All required functions to build new graph elements.
Functions§
- render_
digraph - Renders the given graph as a directed DOT graph.
- render_
graph - Renders the given graph as an undirected DOT graph.
- render_
strict_ digraph - Renders the given graph as a strict directed DOT graph.
- render_
strict_ graph - Renders the given graph as a strict undirected DOT graph.
Type Aliases§
- Attributes
- Attributes of an entity.
- Defaults
- Default attributes for a given
Kind.