diff --git a/src/gui/mod.rs b/src/gui/mod.rs index aea2471..79f3c0c 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -1,42 +1,48 @@ use eframe::egui; +use crate::types::{Filaments, Index}; + /// The `Filaments Visualizer`, which is an instance of `eframe`, which uses `egui` -#[derive(Default)] pub struct FilViz { - /// example for now - text: String, + filaments: Filaments, } impl FilViz { /// Create a new instance of the `FiLViz` - const fn new(_cc: &eframe::CreationContext<'_>) -> Self { + fn new(_cc: &eframe::CreationContext<'_>, idx: &Index) -> Self { // Customize egui here with cc.egui_ctx.set_fonts and cc.egui_ctx.set_global_style. // Restore app state using cc.storage (requires the "persistence" feature). // Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use // for e.g. egui::PaintCallback. Self { - text: String::new(), + filaments: Filaments::from(idx), } } /// Create and run the `FilViz`. - pub fn run() -> color_eyre::Result<()> { + pub fn run(idx: &Index) -> color_eyre::Result<()> { let native_options = eframe::NativeOptions::default(); eframe::run_native( "Filaments Visualizer", native_options, - Box::new(|cc| Ok(Box::new(Self::new(cc)))), + Box::new(|cc| Ok(Box::new(Self::new(cc, idx)))), )?; Ok(()) } } +type L = egui_graphs::LayoutForceDirected; +type S = egui_graphs::FruchtermanReingoldWithCenterGravityState; + impl eframe::App for FilViz { fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show_inside(ui, |ui| { - ui.heading("Hello World!"); - ui.text_edit_singleline(&mut self.text); + let g = &mut self.filaments.graph; + + let mut view = egui_graphs::GraphView::<_, _, _, _, _, _, S, L>::new(g); + + ui.add(&mut view); // credits! ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| { diff --git a/src/main.rs b/src/main.rs index 491a4b4..8821878 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,6 +52,7 @@ fn main() -> color_eyre::Result<()> { let tui_handle = std::thread::spawn({ // arc stuff let tui_rt = rt.clone(); + let kh = kh.clone(); // closure to run the tui move || -> color_eyre::Result<()> { @@ -69,7 +70,8 @@ fn main() -> color_eyre::Result<()> { if args.visualizer { // enter the guard so egui_async works properly let _rt_guard = rt.enter(); - FilViz::run()?; + let index = rt.block_on(async { kh.read().await.index.clone() }); + FilViz::run(&index)?; } // join on the tui diff --git a/src/types/filaments.rs b/src/types/filaments.rs index 6673837..44c6c12 100644 --- a/src/types/filaments.rs +++ b/src/types/filaments.rs @@ -1,6 +1,7 @@ #![expect(dead_code)] use std::{cmp::max, collections::HashMap}; +use eframe::emath; use egui_graphs::{ Graph, petgraph::{Directed, graph::NodeIndex, prelude::StableGraph}, @@ -16,30 +17,50 @@ const GRAPH_MIN_NODES: usize = 128; const GRAPH_MIN_EDGES: usize = GRAPH_MIN_NODES * 3; pub struct Filaments { - graph: ZkGraph, + pub graph: ZkGraph, /// simple conversions zid_to_gid: HashMap, } -// pub type FilamentsHandle = Arc -// - -// impl Filaments { -// pub fn construct() -> Result {} -// } - impl From<&Index> for Filaments { fn from(value: &Index) -> Self { let number_of_zettels = value.zods().len(); - let mut _graph: ZkGraph = ZkGraph::from(&StableGraph::with_capacity( + let mut zid_to_gid = HashMap::new(); + + let mut graph: ZkGraph = ZkGraph::from(&StableGraph::with_capacity( max(number_of_zettels * 2, GRAPH_MIN_EDGES), max(number_of_zettels * 3, GRAPH_MIN_EDGES), )); - #[expect(clippy::for_kv_map)] - for (_id, _zod) in value.zods() {} + for (zid, zod) in value.zods() { + let node_idx = graph.add_node_custom(zid.clone(), |node| { + node.set_label(zod.fm.title.clone()); + let disp = node.display_mut(); + disp.radius = 100.0; + + // randomize position + let x = rand::random_range(0.0..=100.0); + let y = rand::random_range(0.0..=100.0); + node.set_location(emath::Pos2 { x, y }); + }); + + let _ = zid_to_gid.insert(zid.clone(), node_idx); + } + + for (_, links) in value.outgoing_links.clone() { + for link in links { + let start = zid_to_gid + .get(&link.source) + .expect("Invariant broken, must exist in here if its in the index"); + let end = zid_to_gid + .get(&link.dest) + .expect("Invariant broken, must exist in here if its in the index"); + + let _ = graph.add_edge(*start, *end, link); + } + } - todo!() + Self { graph, zid_to_gid } } } diff --git a/src/types/mod.rs b/src/types/mod.rs index 3be8929..ea43a7d 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -22,7 +22,6 @@ mod link; pub use link::Link; mod filaments; -#[expect(unused_imports)] pub use filaments::Filaments; mod index;