From 88b84f615d32bc4641d8dbbe3d3cf3584666542f Mon Sep 17 00:00:00 2001 From: Armin Date: Sun, 17 Aug 2025 02:04:25 +0200 Subject: [PATCH] Allow multiple obj / attr per label --- src/components/graph.rs | 35 ++++++++++++-------- src/components/svg/node.rs | 68 ++++++++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/src/components/graph.rs b/src/components/graph.rs index 3216814..1a67a5e 100644 --- a/src/components/graph.rs +++ b/src/components/graph.rs @@ -12,7 +12,7 @@ use crate::components::{ #[derive(Clone, Debug)] pub struct Node { pub id: usize, - pub label: (Option, Option), + pub label: (Option>, Option>), pub x: f64, pub y: f64, pub x_signal: RwSignal, @@ -24,12 +24,18 @@ pub struct Dimensions { pub width: f64, pub height: f64, pub margin: f64, + pub node_count_xy: (f64, f64), pub radius: f64, pub font_size: u8, } impl Node { - pub fn new(id: usize, label: (Option, Option), x: f64, y: f64) -> Self { + pub fn new( + id: usize, + label: (Option>, Option>), + x: f64, + y: f64, + ) -> Self { Node { id, label, @@ -61,6 +67,7 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext width: 600.0, height: 600.0, margin: 70.0, + node_count_xy: (1.0, 1.0), radius: 8.0, font_size: 16, }); @@ -76,6 +83,8 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext } } + dimensions.update(|dim| dim.node_count_xy = (x_max, y_max)); + let mut x_not_zero = false; if x_max > 0.0 { x_not_zero = true; @@ -105,10 +114,10 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext }); Effect::new(move || { - let dimensions = dimensions.get(); + let dim = dimensions.get(); - let x_coef = (dimensions.width - 2.0 * dimensions.margin) / x_max; - let y_coef = (dimensions.height - 2.0 * dimensions.margin) / y_max; + let x_coef = (dim.width - 2.0 * dim.margin) / x_max; + let y_coef = (dim.height - 2.0 * dim.margin) / y_max; if x_not_zero { nodes.set( @@ -119,8 +128,8 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext Node::new( node.id, node.label.clone(), - node.x as f64 * x_coef + dimensions.margin, - node.y as f64 * y_coef + dimensions.margin, + node.x as f64 * x_coef + dim.margin, + node.y as f64 * y_coef + dim.margin, ) }) .collect(), @@ -134,8 +143,8 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext Node::new( node.id, node.label.clone(), - dimensions.width / 2.0, - node.y as f64 * y_coef + dimensions.margin, + dim.width / 2.0, + node.y as f64 * y_coef + dim.margin, ) }) .collect(), @@ -256,13 +265,11 @@ pub fn GraphComp(concepts: Vec<(BitSet, BitSet)>, context: FormalContext view! { {error} } ) diff --git a/src/components/svg/node.rs b/src/components/svg/node.rs index f27a6fc..c117089 100644 --- a/src/components/svg/node.rs +++ b/src/components/svg/node.rs @@ -5,6 +5,22 @@ use leptos_use::{ }; use web_sys::MouseEvent; +// pub fn format_label(label_vec: Vec, dimensions: &Dimensions) -> String { +// // 20px: 11 / 23.04 +// // 18px: 9.91 / 20.95 +// // 16px: 8.8 / 18.85 +// // 14px: 7.7 / 16.06 +// let font_char_width = 8.8; +// let font_char_height = 18.85; +// let x_coef = (dimensions.width - 2.0 * dimensions.margin) / dimensions.node_count_xy.0; +// let y_coef = (dimensions.height - 2.0 * dimensions.margin) / dimensions.node_count_xy.1; +// let max_char_per_line = (x_coef / font_char_width).ceil(); +// let max_lines = (y_coef / font_char_height).ceil(); +// leptos::logging::log!("{}", max_char_per_line); +// leptos::logging::log!("{}", max_lines); +// String::from("value") +// } + #[component] pub fn NodeComp(node: Node, offset: (f64, f64), dimensions: Dimensions) -> impl IntoView { let node_ref: NodeRef = NodeRef::new(); @@ -87,17 +103,20 @@ pub fn NodeComp(node: Node, offset: (f64, f64), dimensions: Dimensions) -> impl // object labels { - if let Some(obj) = node.label.0.clone() { - let len = obj.len(); - let string = "0".to_string().repeat(len); + if let Some(obj_vec) = node.label.0.clone() { + let mut len = 0; + len += obj_vec.len() - 1; + for obj in obj_vec { + len += obj.len(); + } + let string = "N".to_string().repeat(len); string } else { "".to_string() @@ -105,16 +124,20 @@ pub fn NodeComp(node: Node, offset: (f64, f64), dimensions: Dimensions) -> impl } { - if let Some(obj) = node.label.0 { - obj + if let Some(obj_vec) = node.label.0 { + let mut obj_string = String::new(); + for obj in obj_vec { + obj_string.push_str(&(obj + " ")); + } + obj_string.pop(); + obj_string } else { "".to_string() } @@ -126,15 +149,19 @@ pub fn NodeComp(node: Node, offset: (f64, f64), dimensions: Dimensions) -> impl dy=".35em" text-anchor="middle" stroke="white" - stroke-width="0.3em" + stroke-width="0.4em" font-style="italic" font-family="monospace" x=x_pos - y=move || {y_pos() - dimensions.radius * 2.8} + y=move || {y_pos() - dimensions.radius * 3.0} >{ - if let Some(attr) = node.label.1.clone() { - let len = attr.len(); - let string = "0".to_string().repeat(len); + if let Some(attr_vec) = node.label.1.clone() { + let mut len = 0; + len += attr_vec.len() - 1; + for attr in attr_vec { + len += attr.len(); + } + let string = "N".to_string().repeat(len); string } else { "".to_string() @@ -149,10 +176,15 @@ pub fn NodeComp(node: Node, offset: (f64, f64), dimensions: Dimensions) -> impl font-style="italic" font-family="monospace" x=x_pos - y=move || {y_pos() - dimensions.radius * 2.8} + y=move || {y_pos() - dimensions.radius * 3.0} >{ - if let Some(attr) = node.label.1 { - attr + if let Some(attr_vec) = node.label.1 { + let mut attr_string = String::new(); + for attr in attr_vec { + attr_string.push_str(&(attr + " ")); + } + attr_string.pop(); + attr_string } else { "".to_string() }