pub struct GraphMetrics { /* private fields */ }Expand description
Statistical metrics for a dependency graph.
§Examples
use ascii_dag::layout::generic::metrics::GraphMetrics;
let get_deps = |&id: &usize| match id {
1 => vec![],
2 => vec![1],
3 => vec![1, 2],
_ => vec![],
};
let items = [1, 2, 3];
let metrics = GraphMetrics::compute(&items, get_deps);
println!("Nodes: {}", metrics.node_count());
println!("Max depth: {}", metrics.max_depth());
println!("Avg dependencies: {:.2}", metrics.avg_dependencies());Implementations§
Source§impl GraphMetrics
impl GraphMetrics
Sourcepub fn compute<Id, F>(items: &[Id], get_dependencies: F) -> Self
pub fn compute<Id, F>(items: &[Id], get_dependencies: F) -> Self
Compute metrics for a graph.
§Examples
use ascii_dag::layout::generic::metrics::GraphMetrics;
let get_deps = |&id: &usize| match id {
1 => vec![],
2 => vec![1],
3 => vec![2],
_ => vec![],
};
let items = [1, 2, 3];
let metrics = GraphMetrics::compute(&items, get_deps);
assert_eq!(metrics.node_count(), 3);Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Total number of nodes in the graph.
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
Total number of edges (dependencies) in the graph.
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn root_count(&self) -> usize
pub fn root_count(&self) -> usize
Number of root nodes (nodes with no dependencies).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn leaf_count(&self) -> usize
pub fn leaf_count(&self) -> usize
Number of leaf nodes (nodes that nothing depends on).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn max_depth(&self) -> usize
pub fn max_depth(&self) -> usize
Maximum depth (longest dependency chain from a root).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn max_descendants(&self) -> usize
pub fn max_descendants(&self) -> usize
Maximum number of descendants any single node has.
This represents the “blast radius” of the most impactful node.
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn avg_dependencies(&self) -> f64
pub fn avg_dependencies(&self) -> f64
Average number of dependencies per node.
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn density(&self) -> f64
pub fn density(&self) -> f64
Graph density (ratio of actual edges to possible edges).
Returns a value between 0.0 (no edges) and 1.0 (complete graph).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn is_tree(&self) -> bool
pub fn is_tree(&self) -> bool
Check if this is a tree (single root, no multiple paths to same node).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn is_forest(&self) -> bool
pub fn is_forest(&self) -> bool
Check if this is a forest (multiple trees, no cycles).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn is_sparse(&self) -> bool
pub fn is_sparse(&self) -> bool
Check if the graph is sparse (few edges relative to nodes).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Sourcepub fn is_dense(&self) -> bool
pub fn is_dense(&self) -> bool
Check if the graph is dense (many edges relative to nodes).
Examples found in repository?
155fn example_metrics_dashboard() {
156 println!("3. Dependency Graph Metrics");
157 println!(" Statistical analysis of the dependency structure\n");
158
159 // Build system example
160 let get_deps = |file: &&str| match *file {
161 "app.exe" => vec!["main.o", "utils.o", "io.o"],
162 "main.o" => vec!["main.c", "types.h"],
163 "utils.o" => vec!["utils.c", "types.h"],
164 "io.o" => vec!["io.c", "types.h"],
165 "main.c" => vec![],
166 "utils.c" => vec![],
167 "io.c" => vec![],
168 "types.h" => vec![],
169 _ => vec![],
170 };
171
172 let files = [
173 "app.exe", "main.o", "utils.o", "io.o", "main.c", "utils.c", "io.c", "types.h",
174 ];
175
176 let metrics = GraphMetrics::compute(&files, get_deps);
177
178 println!(" 📈 Graph Statistics:");
179 println!(" Total files: {}", metrics.node_count());
180 println!(" Total dependencies: {}", metrics.edge_count());
181 println!(" Root files (sources): {}", metrics.root_count());
182 println!(" Leaf files (outputs): {}", metrics.leaf_count());
183 println!(" Max depth: {}", metrics.max_depth());
184 println!(" Max impact: {} files", metrics.max_descendants());
185 println!(" Avg dependencies: {:.2}", metrics.avg_dependencies());
186 println!(" Density: {:.2}%", metrics.density() * 100.0);
187 println!();
188
189 println!(" 🔍 Graph Properties:");
190 println!(" Is tree: {}", metrics.is_tree());
191 println!(" Is forest: {}", metrics.is_forest());
192 println!(" Is sparse: {}", metrics.is_sparse());
193 println!(" Is dense: {}", metrics.is_dense());
194 println!();
195
196 // Visualize with DAG
197 println!(" 📊 Visualization:");
198 let mut dag = DAG::new();
199 dag.add_node(1, "types.h");
200 dag.add_node(2, "main.c");
201 dag.add_node(3, "main.o");
202 dag.add_node(4, "app.exe");
203 dag.add_edge(2, 3);
204 dag.add_edge(1, 3);
205 dag.add_edge(3, 4);
206
207 println!("{}", dag.render());
208
209 // Find the most impactful file
210 let mut max_impact = 0;
211 let mut most_impactful = "";
212 for file in &files {
213 let impact = compute_descendants_fn(&files, file, get_deps).len();
214 if impact > max_impact {
215 max_impact = impact;
216 most_impactful = file;
217 }
218 }
219
220 println!(
221 " ⚡ Most impactful file: '{}' (affects {} other files)",
222 most_impactful, max_impact
223 );
224 println!();
225}Trait Implementations§
Source§impl Clone for GraphMetrics
impl Clone for GraphMetrics
Source§fn clone(&self) -> GraphMetrics
fn clone(&self) -> GraphMetrics
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more