diff options
-rw-r--r-- | src/lib.rs | 122 | ||||
-rw-r--r-- | tests/dot.rs | 5 |
2 files changed, 113 insertions, 14 deletions
@@ -13,8 +13,6 @@ //! //! ```rust //! use dotavious::{Dot, Edge, Graph, GraphBuilder, Node}; -//! use std::io; -//! use std::io::Read; //! //! let g = GraphBuilder::new_directed(Some("example".to_string())) //! .add_node(Node::new("N0".to_string())) @@ -22,14 +20,8 @@ //! .add_edge(Edge::new("N0".to_string(), "N1".to_string())) //! .build(); //! -//! let mut writer= Vec::new(); //! let dot = Dot { graph: g }; -//! dot.render(&mut writer).unwrap(); -//! -//! // output to graphviz DOT formatted string -//! let mut dot_string = String::new(); -//! Read::read_to_string(&mut &*writer, &mut dot_string).unwrap(); -//! println!("{}", dot_string); +//! println!("{}", dot); //! ``` //! Produces //! ```dot @@ -40,6 +32,28 @@ //! } //! ``` //! +//! We can also output to a Writer via the `render` function +//! ```rust +//! use dotavious::{Dot, Edge, Graph, GraphBuilder, Node}; +//! use std::io; +//! use std::io::Read; +//! +//! let g = GraphBuilder::new_directed(Some("example".to_string())) +//! .add_node(Node::new("N0".to_string())) +//! .add_node(Node::new("N1".to_string())) +//! .add_edge(Edge::new("N0".to_string(), "N1".to_string())) +//! .build(); +//! +//! let dot = Dot { graph: g }; +//! let mut writer= Vec::new(); +//! dot.render(&mut writer).unwrap(); +//! +//! // output to graphviz DOT formatted string +//! let mut dot_string = String::new(); +//! Read::read_to_string(&mut &*writer, &mut dot_string).unwrap(); +//! println!("{}", dot_string); +//! ``` +//! //! Second example provides a more complex graph showcasing //! Dotavious' various builders and strongly typed attribute //! functions. @@ -47,20 +61,106 @@ //! ```rust //! use dotavious::attributes::{ //! AttributeText, Color, CompassPoint, EdgeAttributes, EdgeStyle, -//! GraphAttributeStatementBuilder, GraphAttributes, NodeAttributes, +//! GraphAttributeStatementBuilder, GraphAttributes, GraphStyle, NodeAttributes, //! NodeStyle, PortPosition, RankDir, Shape, //! }; //! use dotavious::{ //! Dot, Edge, EdgeAttributeStatementBuilder, EdgeBuilder, Graph, //! GraphBuilder, Node, NodeAttributeStatementBuilder, NodeBuilder, +//! SubGraphBuilder //! }; //! use std::io; //! use std::io::Read; +//! +//! let cluster_0 = SubGraphBuilder::new(Some("cluster_0".to_string())) +//! .add_graph_attributes( +//! GraphAttributeStatementBuilder::new() +//! .label("process #1".to_string()) +//! .style(GraphStyle::Filled) +//! .color(Color::Named("lightgrey")) +//! .build(), +//! ) +//! .add_node_attributes( +//! NodeAttributeStatementBuilder::new() +//! .style(NodeStyle::Filled) +//! .color(Color::Named("white")) +//! .build(), +//! ) +//! .add_edge(Edge::new("a0".to_string(), "a1".to_string())) +//! .add_edge(Edge::new("a1".to_string(), "a2".to_string())) +//! .add_edge(Edge::new("a2".to_string(), "a3".to_string())) +//! .build(); +//! +//! let cluster_1 = SubGraphBuilder::new(Some("cluster_1".to_string())) +//! .add_graph_attributes( +//! GraphAttributeStatementBuilder::new() +//! .label("process #2".to_string()) +//! .style(GraphStyle::Filled) +//! .color(Color::Named("blue")) +//! .build(), +//! ) +//! .add_node_attributes( +//! NodeAttributeStatementBuilder::new() +//! .style(NodeStyle::Filled) +//! .build(), +//! ) +//! .add_edge(Edge::new("b0".to_string(), "b1".to_string())) +//! .add_edge(Edge::new("b1".to_string(), "b2".to_string())) +//! .add_edge(Edge::new("b2".to_string(), "b3".to_string())) +//! .build(); +//! +//! let g = GraphBuilder::new_directed(Some("G".to_string())) +//! .add_node( +//! NodeBuilder::new("start".to_string()) +//! .shape(Shape::Mdiamond) +//! .build(), +//! ) +//! .add_node( +//! NodeBuilder::new("end".to_string()) +//! .shape(Shape::Msquare) +//! .build(), +//! ) +//! .add_sub_graph(cluster_0) +//! .add_sub_graph(cluster_1) +//! .add_edge(Edge::new("start".to_string(), "a0".to_string())) +//! .add_edge(Edge::new("start".to_string(), "b0".to_string())) +//! .add_edge(Edge::new("a1".to_string(), "b3".to_string())) +//! .add_edge(Edge::new("b2".to_string(), "a3".to_string())) +//! .add_edge(Edge::new("a3".to_string(), "a0".to_string())) +//! .add_edge(Edge::new("a3".to_string(), "end".to_string())) +//! .add_edge(Edge::new("b3".to_string(), "end".to_string())) +//! .build(); //! ``` //! //! Produces //! ```dot +//! digraph G { +//! subgraph cluster_0 { +//! graph [label="process #1", style=filled, color="lightgrey"]; +//! node [style=filled, color="white"]; +//! a0 -> a1; +//! a1 -> a2; +//! a2 -> a3; +//! } //! +//! subgraph cluster_1 { +//! graph [label="process #2", style=filled, color="blue"]; +//! node [style=filled]; +//! b0 -> b1; +//! b1 -> b2; +//! b2 -> b3; +//! } +//! +//! start [shape=Mdiamond]; +//! end [shape=Msquare]; +//! start -> a0; +//! start -> b0; +//! a1 -> b3; +//! b2 -> a3; +//! a3 -> a0; +//! a3 -> end; +//! b3 -> end; +//! } //! ``` pub mod attributes; @@ -69,7 +169,7 @@ pub mod dot; #[doc(hidden)] pub use crate::dot::{ Dot, DotString, Edge, EdgeAttributeStatementBuilder, EdgeBuilder, Graph, - GraphBuilder, Node, NodeAttributeStatementBuilder, NodeBuilder, + GraphBuilder, Node, NodeAttributeStatementBuilder, NodeBuilder, SubGraphBuilder, }; // TODO: support adding edge based on index of nodes? diff --git a/tests/dot.rs b/tests/dot.rs index c4d31ba..8244a52 100644 --- a/tests/dot.rs +++ b/tests/dot.rs @@ -3,10 +3,9 @@ use dotavious::attributes::{ GraphAttributeStatementBuilder, GraphAttributes, GraphStyle, NodeAttributes, NodeStyle, PortPosition, RankDir, Shape, }; -use dotavious::dot::SubGraphBuilder; use dotavious::{ Dot, Edge, EdgeAttributeStatementBuilder, EdgeBuilder, Graph, GraphBuilder, Node, - NodeAttributeStatementBuilder, NodeBuilder, + NodeAttributeStatementBuilder, NodeBuilder, SubGraphBuilder, }; use std::io; use std::io::Read; @@ -35,7 +34,7 @@ fn empty_digraph_without_id() { } #[test] -fn display() { +fn support_display() { let g = GraphBuilder::new_directed(None).build(); let dot = Dot { graph: g }; |