| Crates.io | vizoxide |
| lib.rs | vizoxide |
| version | 1.0.5 |
| created_at | 2025-03-02 23:38:10.183246+00 |
| updated_at | 2025-03-09 03:06:59.984486+00 |
| description | Vizoxide is a high-level Rust wrapper for Graphviz that provides an idiomatic, builder-pattern interface for creating, styling, laying out, and rendering complex graphs in various output formats. |
| homepage | |
| repository | https://github.com/19h/vizoxide |
| max_upload_size | |
| id | 1574969 |
| size | 123,335 |
A comprehensive, memory-safe Rust wrapper for the GraphViz graph visualization library. This crate provides an ergonomic, idiomatic Rust interface for creating, manipulating, and rendering graphs.
This crate requires the GraphViz library to be installed on your system. Installation instructions vary by platform:
sudo apt-get install graphviz libgraphviz-dev
brew install graphviz
Download and install from GraphViz's official site or use:
choco install graphviz
Add this to your Cargo.toml:
[dependencies]
graphviz = "1.0.0"
use vizoxide::{Graph, Context};
use vizoxide::layout::{apply_layout, Engine};
use vizoxide::render::{render_to_file, Format};
use vizoxide::attr::AttributeContainer;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// Create a new GraphViz context
let context = Context::new()?;
// Create a directed graph
let mut graph = Graph::new("example", true)?;
// Add nodes
let a = graph.add_node("A")?;
let b = graph.add_node("B")?;
let c = graph.add_node("C")?;
// Add edges
graph.add_edge(&a, &b, None)?;
graph.add_edge(&b, &c, None)?;
graph.add_edge(&c, &a, None)?;
// Set attributes
graph.set_attribute("rankdir", "LR")?;
a.set_attribute("shape", "box")?;
b.set_attribute("style", "filled")?;
b.set_attribute("fillcolor", "lightblue")?;
// Apply layout
apply_layout(&context, &mut graph, Engine::Dot)?;
// Render to a file
render_to_file(&context, &graph, Format::Svg, "example.svg")?;
Ok(())
}
A Context represents the GraphViz runtime environment. It's required for layout and rendering operations:
let context = Context::new()?;
Create directed or undirected graphs:
// Directed graph
let directed = Graph::new("my_graph", true)?;
// Undirected graph
let undirected = Graph::new("my_graph", false)?;
// Strict graph (no duplicate edges)
let strict = Graph::new_with_strictness("my_graph", true, true)?;
Nodes and edges are the building blocks of graphs:
// Add nodes
let node1 = graph.add_node("Node1")?;
let node2 = graph.add_node("Node2")?;
// Add an edge
let edge = graph.add_edge(&node1, &node2, None)?;
Customize the appearance of graphs, nodes, and edges with attributes:
// Set attributes directly
graph.set_attribute("bgcolor", "lightgray")?;
node.set_attribute("shape", "box")?;
edge.set_attribute("color", "red")?;
// Check and remove attributes
if node.has_attribute("color")? {
node.remove_attribute("color")?;
}
// Get attribute value
let shape = node.get_attribute("shape")?;
The attr module provides constants for common attribute names:
use graphviz::attr::{graph, node, edge, values};
// Use predefined attribute constants
graph_obj.set_attribute(graph::RANKDIR, "LR")?;
node_obj.set_attribute(node::SHAPE, values::shape::BOX)?;
edge_obj.set_attribute(edge::STYLE, values::style::DASHED)?;
The crate supports a fluent builder pattern for creating graph elements:
// Create a graph with the builder
let graph = Graph::builder("flowchart")
.directed(true)
.strict(false)
.attribute("rankdir", "TD")
.build()?;
// Create a node with attributes
let start = graph.create_node("start")
.attribute("shape", "ellipse")
.attribute("style", "filled")
.attribute("fillcolor", "lightblue")
.build()?;
// Create an edge with attributes
let edge = graph.create_edge(&start, &process, None)
.attribute("label", "Begin")
.attribute("color", "blue")
.build()?;
GraphViz supports various layout algorithms:
// Basic layout application
apply_layout(&context, &mut graph, Engine::Dot)?;
// Other available engines
apply_layout(&context, &mut graph, Engine::Neato)?; // Spring model
apply_layout(&context, &mut graph, Engine::Fdp)?; // Force-directed
apply_layout(&context, &mut graph, Engine::Circo)?; // Circular
apply_layout(&context, &mut graph, Engine::Twopi)?; // Radial
apply_layout(&context, &mut graph, Engine::Sfdp)?; // Multiscale
Customize layout behavior with predefined or custom settings:
// Using predefined layout settings
let radial_settings = radial_layout();
radial_settings.apply(&graph)?;
// Using custom layout settings
let custom_settings = LayoutSettings::new()
.with_overlap("false")
.with_splines("ortho")
.with_nodesep(0.75)
.with_ranksep(1.0);
custom_settings.apply(&graph)?;
render_to_file(&context, &graph, Format::Svg, "output.svg")?;
render_to_file(&context, &graph, Format::Png, "output.png")?;
render_to_file(&context, &graph, Format::Pdf, "output.pdf")?;
// Render to string (for text formats like SVG, DOT)
let svg_string = render_to_string(&context, &graph, Format::Svg)?;
// Render to bytes (for any format)
let png_bytes = render_to_bytes(&context, &graph, Format::Png)?;
// Render to a writer
let mut buffer = Cursor::new(Vec::new());
render_to_writer(&context, &graph, Format::Svg, &mut buffer)?;
The crate supports all GraphViz output formats including:
Format enumIterate over nodes and edges:
// Iterate through all nodes
for node in graph.nodes() {
println!("Node: {}", node.name()?);
// Iterate through outgoing edges
for edge in graph.out_edges(&node) {
let target = edge.to_node().name()?;
println!(" -> {}", target);
}
}
// Check graph properties
println!("Node count: {}", graph.node_count());
println!("Edge count: {}", graph.edge_count());
println!("Directed: {}", graph.is_directed());
// Create a context with custom plugin settings
let context = Context::new_with_plugins(true, false)?;
// Customize rendering with options
let options = RenderOptions::new()
.with_anti_alias(true)
.with_transparency(true)
.with_dpi(300.0)
.with_background("white")
.with_scale(2.0);
// Apply options when rendering
render_with_options(&context, &graph, Format::Png, "high_quality.png", &options)?;
The crate includes several examples demonstrating various features:
simple_graph - Basic graph creation and renderingcomplex_graph_with_build_pattern - Using the builder patternedge_builder_with_multiple_attributes - Working with edge attributespredefined_layout_settings - Using predefined layoutscreating_context_with_plugins - Working with GraphViz pluginsiterating_over_nodes_and_edges - Graph traversalrender_graph_to_string_and_bytes - In-memory renderingcustom_layout_settings - Advanced layout configurationmodifying_attributes_and_removing_them - Attribute manipulationrender_graph_to_writer - Rendering to custom outputRun any example with:
cargo run --example example_name
The crate uses the GraphvizError type to represent various error conditions:
match result {
Ok(graph) => println!("Graph created successfully"),
Err(GraphvizError::GraphCreationFailed) => println!("Failed to create graph"),
Err(GraphvizError::LayoutFailed) => println!("Failed to apply layout"),
Err(GraphvizError::RenderFailed) => println!("Failed to render graph"),
Err(e) => println!("Other error: {}", e),
}
This crate is available under the MIT License. See the LICENSE file for more details.
Contributions are welcome! Please feel free to submit a Pull Request.