From 5bf73a23e94dc22db1458a0421fe34615b2c441e Mon Sep 17 00:00:00 2001 From: Nina Hammer Date: Tue, 1 Aug 2023 18:26:59 +0200 Subject: [PATCH] add documentation, visualizer now returns string, clean test --- Cargo.toml | 1 - src/tools/graph_visualizer.rs | 58 +++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a2aa96e..2b8886e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rand = "0.8.5" [dev-dependencies] rand = "0.8.5" diff --git a/src/tools/graph_visualizer.rs b/src/tools/graph_visualizer.rs index d1fa56b..11b1f2f 100644 --- a/src/tools/graph_visualizer.rs +++ b/src/tools/graph_visualizer.rs @@ -1,13 +1,36 @@ use crate::data_structures::{graph::Graph, subgraph::Subgraph}; -use rand::{seq::IteratorRandom, thread_rng}; -use std::{ - fs::File, - io::{Error, Write}, -}; +/// Generates a .dot file for the given graph. The subgraphs are colored in the order they are given. +/// +/// # Example +/// ``` +/// use star::data_structures::{graph::Graph, choice_dict::ChoiceDict, subgraph::Subgraph}; +/// use star::tools::graph_visualizer::dot_graph; +/// let graph = Graph::new_with_edges( +/// 6, +/// vec![ +/// [3, 2].to_vec(), +/// [4, 2, 5].to_vec(), +/// [0, 1].to_vec(), +/// [0, 5].to_vec(), +/// [1].to_vec(), +/// [1, 3].to_vec(), +/// ], +/// ); +/// let mut subset = ChoiceDict::new(graph.nodes.len()); +/// subset.set(0); +/// subset.set(3); +/// subset.set(4); +/// let mut subset1 = ChoiceDict::new(graph.nodes.len()); +/// subset1.set(1); +/// subset1.set(2); +/// let sub = Subgraph::new(&graph, subset); +/// let sub1 = Subgraph::new(&graph, subset1); +/// dot_graph(&graph, vec![sub, sub1]); +/// ``` -pub fn dot_graph(graph: &Graph, filename: &str, subgraphs: Vec) -> Result<(), Error> { - let mut graph_string = String::from("graph {\n"); +pub fn dot_graph(graph: &Graph, subgraphs: Vec) -> String { + let mut graph_string = String::from("graph {"); let mut already_written: Vec<(usize, usize)> = Vec::new(); let mut nodes_visited: Vec = vec![false; graph.nodes.len()]; let available_colors = ["red", "green", "blue", "yellow", "orange", "purple"]; @@ -17,7 +40,7 @@ pub fn dot_graph(graph: &Graph, filename: &str, subgraphs: Vec) -> Res already_written.push((i, *j)); nodes_visited[i] = true; nodes_visited[*j] = true; - graph_string.push_str(&format!("\t{} -- {};\n", i, j)); + graph_string.push_str(&format!("{} -- {};", i, j)); } }) }); @@ -27,32 +50,29 @@ pub fn dot_graph(graph: &Graph, filename: &str, subgraphs: Vec) -> Res .enumerate() .filter(|v| !*v.1) .map(|(i, _)| i) - .for_each(|v| graph_string.push_str(&format!("\t{};\n", v))); + .for_each(|v| graph_string.push_str(&format!("{};", v))); subgraphs.iter().enumerate().for_each(|(i, sg)| { - let color = available_colors.iter().choose(&mut thread_rng()).unwrap(); - graph_string.push_str(&format!("\tsubgraph cluster_{} {{\n\t\tstyle=invis;\n", i)); + let color = available_colors[i % available_colors.len()]; + graph_string.push_str(&format!("subgraph cluster_{} {{style=invis;", i)); sg.subset.iter_1().for_each(|v| { - graph_string.push_str(&format!("\t\t{} [fillcolor={}, style=filled];\n", v, color)); + graph_string.push_str(&format!("{} [fillcolor={}, style=filled];", v, color)); }); - graph_string.push_str("\t}\n"); + graph_string.push('}'); }); graph_string.push('}'); - File::create(filename)?.write_all(graph_string.as_bytes())?; - Ok(()) + graph_string } -#[cfg(test)] mod tests { - use crate::data_structures::{choice_dict::ChoiceDict, subgraph::Subgraph}; #[test] - #[cfg(not(miri))] fn test_dot_graph() { use super::dot_graph; use crate::data_structures::graph::Graph; + use crate::data_structures::{choice_dict::ChoiceDict, subgraph::Subgraph}; let graph = Graph::new_with_edges( 6, vec![ @@ -75,6 +95,6 @@ mod tests { let sub = Subgraph::new(&graph, subset); let sub1 = Subgraph::new(&graph, subset1); - dot_graph(&graph, "test.dot", vec![sub, sub1]).unwrap(); + assert_eq!(dot_graph(&graph, vec![sub, sub1]), "graph {0 -- 3;0 -- 2;1 -- 4;1 -- 2;5;subgraph cluster_0 {style=invis;0 [fillcolor=red, style=filled];3 [fillcolor=red, style=filled];4 [fillcolor=red, style=filled];}subgraph cluster_1 {style=invis;1 [fillcolor=green, style=filled];2 [fillcolor=green, style=filled];}}"); } }