use anyhow::Result;
use std::collections::HashMap;
use vecstore::{Metadata, VecStore};
fn main() -> Result<()> {
println!("🔍 HNSW Graph Visualization Example\n");
let temp_dir = tempfile::tempdir()?;
let mut store = VecStore::open(temp_dir.path())?;
println!("📊 Inserting sample vectors...");
let vectors = vec![
("v1", vec![0.1, 0.1, 0.1]),
("v2", vec![0.2, 0.1, 0.1]),
("v3", vec![0.1, 0.2, 0.1]),
("v4", vec![0.8, 0.9, 0.8]),
("v5", vec![0.9, 0.8, 0.9]),
("v6", vec![0.85, 0.85, 0.85]),
("v7", vec![0.5, 0.5, 0.5]),
("v8", vec![0.6, 0.5, 0.5]),
("v9", vec![0.5, 0.6, 0.5]),
("v10", vec![0.3, 0.7, 0.2]),
("v11", vec![0.7, 0.3, 0.8]),
];
for (id, vector) in vectors {
store.upsert(
id.to_string(),
vector,
Metadata {
fields: HashMap::new(),
},
)?;
}
println!("✓ Inserted {} vectors\n", store.len());
println!("🎨 Creating graph visualizer...");
match store.visualizer() {
Ok(viz) => {
println!("✓ Visualizer created successfully!\n");
println!("📄 Exporting to DOT format...");
let dot = viz.export_dot()?;
std::fs::write("graph.dot", &dot)?;
println!(" → Saved to graph.dot");
println!(" → Render with: dot -Tpng graph.dot -o graph.png\n");
println!("📄 Exporting to D3.js JSON format...");
let json = viz.export_json()?;
std::fs::write("graph.json", &json)?;
println!(" → Saved to graph.json\n");
println!("📄 Exporting to Cytoscape.js format...");
let cyto = viz.export_cytoscape()?;
std::fs::write("graph_cytoscape.json", &cyto)?;
println!(" → Saved to graph_cytoscape.json\n");
println!("📊 Graph Statistics:");
let stats = viz.statistics();
println!(" Total Nodes: {}", stats.node_count);
println!(" Total Edges: {}", stats.edge_count);
println!(" Layers: {}", stats.layer_count);
println!(" Avg Degree: {:.2}", stats.avg_degree);
println!(" Min Degree: {}", stats.min_degree);
println!(" Max Degree: {}", stats.max_degree);
println!("\n Per-Layer Breakdown:");
for layer in 0..stats.layer_count {
println!(
" Layer {}: {} nodes, {} edges, {:.2} avg degree",
layer,
stats.nodes_per_layer.get(layer).unwrap_or(&0),
stats.edges_per_layer.get(layer).unwrap_or(&0),
stats.avg_degree_per_layer.get(layer).unwrap_or(&0.0)
);
}
println!("\n📄 Exporting statistics...");
let stats_text = viz.export_statistics_text();
std::fs::write("graph_stats.txt", &stats_text)?;
println!(" → Saved to graph_stats.txt\n");
if viz.node_count() > 100 {
println!("📄 Creating sampled graph (first 50 nodes)...");
let sampled = viz.sample(50);
let sampled_dot = sampled.export_dot()?;
std::fs::write("graph_sampled.dot", &sampled_dot)?;
println!(" → Saved to graph_sampled.dot\n");
}
println!("✅ Graph visualization complete!");
println!("\n🎯 Next Steps:");
println!(" 1. Render DOT file: dot -Tpng graph.dot -o graph.png");
println!(" 2. Open graph.json in a D3.js visualization tool");
println!(" 3. Load graph_cytoscape.json in Cytoscape.js");
println!(" 4. Read graph_stats.txt for detailed metrics");
}
Err(e) => {
println!("⚠️ Graph visualization not available: {}", e);
println!("\nNote: Graph visualization is currently only supported for WASM builds.");
println!("To use visualization:");
println!(" 1. Build with: cargo build --target wasm32-unknown-unknown");
println!(" 2. Or use the WASM-based backend");
}
}
Ok(())
}