My personal-knowledge-system, with deeply integrated task tracking and long term goal planning capabilities.
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: dirt basic visualizer

+51 -23
+15 -9
src/gui/mod.rs
··· 1 1 use eframe::egui; 2 2 3 + use crate::types::{Filaments, Index}; 4 + 3 5 /// The `Filaments Visualizer`, which is an instance of `eframe`, which uses `egui` 4 - #[derive(Default)] 5 6 pub struct FilViz { 6 - /// example for now 7 - text: String, 7 + filaments: Filaments, 8 8 } 9 9 10 10 impl FilViz { 11 11 /// Create a new instance of the `FiLViz` 12 - const fn new(_cc: &eframe::CreationContext<'_>) -> Self { 12 + fn new(_cc: &eframe::CreationContext<'_>, idx: &Index) -> Self { 13 13 // Customize egui here with cc.egui_ctx.set_fonts and cc.egui_ctx.set_global_style. 14 14 // Restore app state using cc.storage (requires the "persistence" feature). 15 15 // Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use 16 16 // for e.g. egui::PaintCallback. 17 17 Self { 18 - text: String::new(), 18 + filaments: Filaments::from(idx), 19 19 } 20 20 } 21 21 22 22 /// Create and run the `FilViz`. 23 - pub fn run() -> color_eyre::Result<()> { 23 + pub fn run(idx: &Index) -> color_eyre::Result<()> { 24 24 let native_options = eframe::NativeOptions::default(); 25 25 eframe::run_native( 26 26 "Filaments Visualizer", 27 27 native_options, 28 - Box::new(|cc| Ok(Box::new(Self::new(cc)))), 28 + Box::new(|cc| Ok(Box::new(Self::new(cc, idx)))), 29 29 )?; 30 30 31 31 Ok(()) 32 32 } 33 33 } 34 34 35 + type L = egui_graphs::LayoutForceDirected<egui_graphs::FruchtermanReingoldWithCenterGravity>; 36 + type S = egui_graphs::FruchtermanReingoldWithCenterGravityState; 37 + 35 38 impl eframe::App for FilViz { 36 39 fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { 37 40 egui::CentralPanel::default().show_inside(ui, |ui| { 38 - ui.heading("Hello World!"); 39 - ui.text_edit_singleline(&mut self.text); 41 + let g = &mut self.filaments.graph; 42 + 43 + let mut view = egui_graphs::GraphView::<_, _, _, _, _, _, S, L>::new(g); 44 + 45 + ui.add(&mut view); 40 46 41 47 // credits! 42 48 ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
+3 -1
src/main.rs
··· 52 52 let tui_handle = std::thread::spawn({ 53 53 // arc stuff 54 54 let tui_rt = rt.clone(); 55 + let kh = kh.clone(); 55 56 56 57 // closure to run the tui 57 58 move || -> color_eyre::Result<()> { ··· 69 70 if args.visualizer { 70 71 // enter the guard so egui_async works properly 71 72 let _rt_guard = rt.enter(); 72 - FilViz::run()?; 73 + let index = rt.block_on(async { kh.read().await.index.clone() }); 74 + FilViz::run(&index)?; 73 75 } 74 76 75 77 // join on the tui
+33 -12
src/types/filaments.rs
··· 1 1 #![expect(dead_code)] 2 2 use std::{cmp::max, collections::HashMap}; 3 3 4 + use eframe::emath; 4 5 use egui_graphs::{ 5 6 Graph, 6 7 petgraph::{Directed, graph::NodeIndex, prelude::StableGraph}, ··· 16 17 const GRAPH_MIN_EDGES: usize = GRAPH_MIN_NODES * 3; 17 18 18 19 pub struct Filaments { 19 - graph: ZkGraph, 20 + pub graph: ZkGraph, 20 21 /// simple conversions 21 22 zid_to_gid: HashMap<ZettelId, NodeIndex>, 22 23 } 23 24 24 - // pub type FilamentsHandle = Arc<RwLock> 25 - // 26 - 27 - // impl Filaments { 28 - // pub fn construct() -> Result<Self> {} 29 - // } 30 - 31 25 impl From<&Index> for Filaments { 32 26 fn from(value: &Index) -> Self { 33 27 let number_of_zettels = value.zods().len(); 34 28 35 - let mut _graph: ZkGraph = ZkGraph::from(&StableGraph::with_capacity( 29 + let mut zid_to_gid = HashMap::new(); 30 + 31 + let mut graph: ZkGraph = ZkGraph::from(&StableGraph::with_capacity( 36 32 max(number_of_zettels * 2, GRAPH_MIN_EDGES), 37 33 max(number_of_zettels * 3, GRAPH_MIN_EDGES), 38 34 )); 39 35 40 - #[expect(clippy::for_kv_map)] 41 - for (_id, _zod) in value.zods() {} 36 + for (zid, zod) in value.zods() { 37 + let node_idx = graph.add_node_custom(zid.clone(), |node| { 38 + node.set_label(zod.fm.title.clone()); 39 + let disp = node.display_mut(); 40 + disp.radius = 100.0; 41 + 42 + // randomize position 43 + let x = rand::random_range(0.0..=100.0); 44 + let y = rand::random_range(0.0..=100.0); 45 + node.set_location(emath::Pos2 { x, y }); 46 + }); 47 + 48 + let _ = zid_to_gid.insert(zid.clone(), node_idx); 49 + } 42 50 43 - todo!() 51 + for (_, links) in value.outgoing_links.clone() { 52 + for link in links { 53 + let start = zid_to_gid 54 + .get(&link.source) 55 + .expect("Invariant broken, must exist in here if its in the index"); 56 + let end = zid_to_gid 57 + .get(&link.dest) 58 + .expect("Invariant broken, must exist in here if its in the index"); 59 + 60 + let _ = graph.add_edge(*start, *end, link); 61 + } 62 + } 63 + 64 + Self { graph, zid_to_gid } 44 65 } 45 66 }
-1
src/types/mod.rs
··· 22 22 pub use link::Link; 23 23 24 24 mod filaments; 25 - #[expect(unused_imports)] 26 25 pub use filaments::Filaments; 27 26 28 27 mod index;