From 46d6b8910667abdfde31c56a017bda8a3d9ce8d3 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 13 Jul 2025 01:23:21 +0200 Subject: [PATCH] multi line chart --- assets/styles/dashboard.css | 29 ++++++++++++++++++ assets/styles/font.css | 1 + src/components/mod.rs | 59 +++++++++++++++++++++++++++++-------- src/dashboard.rs | 6 +++- 4 files changed, 82 insertions(+), 13 deletions(-) diff --git a/assets/styles/dashboard.css b/assets/styles/dashboard.css index 4937386..f8dd34e 100644 --- a/assets/styles/dashboard.css +++ b/assets/styles/dashboard.css @@ -96,6 +96,35 @@ body { border-radius: 10px; width: 100%; } +.performance-stack { + display: flex; + position: relative; +} + +.lc1, +.lc2, +.lc3 { + flex: 1; + position: relative; +} + +.lc2, +.lc3 { + margin-left: -100%; + z-index: 1; +} + +.lc1 { + color: var(--cpu); +} + +.lc2 { + color: var(--memory); +} + +.lc3 { + color: var(--network); +} .overview-card { background-color: var(--card-bg); diff --git a/assets/styles/font.css b/assets/styles/font.css index a8cc84a..1b4a1b3 100644 --- a/assets/styles/font.css +++ b/assets/styles/font.css @@ -87,4 +87,5 @@ body { width: 100%; height: 100%; display: block; + color: currentColor; } diff --git a/src/components/mod.rs b/src/components/mod.rs index b9863a6..ecfa1bf 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -6,17 +6,18 @@ use dioxus::prelude::*; pub fn LineChart( data: Vec, max: Option, - start_color: Option, start_opacity: Option, - end_color: Option, end_opacity: Option, + class: Option, ) -> Element { let width = 300.0; let height = 200.0; - let start_color = start_color.unwrap_or(0x4f46e5); let start_opacity = start_opacity.unwrap_or(0.4); - let end_color = end_color.unwrap_or(0x4f46e5); let end_opacity = end_opacity.unwrap_or(0.0); + let class_attr = match class { + Some(c) => format!("line-chart {}", c), + None => "line-chart".to_string(), + }; let max_y = max .map(|v| v as f64) @@ -34,24 +35,58 @@ pub fn LineChart( let path_data = { let mut d = format!("M {} {}", points[0].0, points[0].1); - for &(x, y) in &points[1..] { - d += &format!(" L {} {}", x, y); + for i in 0..points.len() - 1 { + let (x0, y0) = if i == 0 { points[0] } else { points[i - 1] }; + let (x1, y1) = points[i]; + let (x2, y2) = points[i + 1]; + let (x3, y3) = if i + 2 < points.len() { + points[i + 2] + } else { + points[i + 1] + }; + + let cp1x = x1 + (x2 - x0) / 6.0; + let cp1y = y1 + (y2 - y0) / 6.0; + let cp2x = x2 - (x3 - x1) / 6.0; + let cp2y = y2 - (y3 - y1) / 6.0; + + d += &format!(" C {} {}, {} {}, {} {}", cp1x, cp1y, cp2x, cp2y, x2, y2); } d }; let fill_path_data = { let mut d = format!("M {} {}", points[0].0, height); - for &(x, y) in &points { - d += &format!(" L {} {}", x, y); + + for i in 0..points.len() - 1 { + let (x0, y0) = if i == 0 { points[0] } else { points[i - 1] }; + let (x1, y1) = points[i]; + let (x2, y2) = points[i + 1]; + let (x3, y3) = if i + 2 < points.len() { + points[i + 2] + } else { + points[i + 1] + }; + + let cp1x = x1 + (x2 - x0) / 6.0; + let cp1y = y1 + (y2 - y0) / 6.0; + let cp2x = x2 - (x3 - x1) / 6.0; + let cp2y = y2 - (y3 - y1) / 6.0; + + if i == 0 { + d += &format!(" L {} {}", points[0].0, points[0].1); + } + + d += &format!(" C {} {}, {} {}, {} {}", cp1x, cp1y, cp2x, cp2y, x2, y2); } + d += &format!(" L {} {}", points.last().unwrap().0, height); d + " Z" }; rsx! { div { - class: "line-chart", + class: "{class_attr}", svg { preserve_aspect_ratio: "none", class: "line-chart-svg", @@ -70,12 +105,12 @@ pub fn LineChart( stop { offset: "0%", - stop_color: "#{start_color:06X}", + stop_color: "currentColor", stop_opacity: "{start_opacity}", } stop { offset: "100%", - stop_color: "#{end_color:06X}", + stop_color: "#currentColor", stop_opacity: "{end_opacity}", } } @@ -91,7 +126,7 @@ pub fn LineChart( class: "line", d: "{path_data}", fill: "none", - stroke: "#4f46e5", + stroke: "currentColor", stroke_width: "2" } } diff --git a/src/dashboard.rs b/src/dashboard.rs index c82cb6d..97e1ea8 100644 --- a/src/dashboard.rs +++ b/src/dashboard.rs @@ -54,7 +54,11 @@ pub fn Dashboard() -> Element { div { class: "overview-container", div { class: "performance-card", - LineChart { data: vec![90, 20, 40, 90, 60], max: 100 } + div { class: "performance-stack", + LineChart { data: vec![30, 30, 30, 70, 30], max: 100, class: "lc1" } + LineChart { data: vec![47, 50, 60, 30, 50], max: 100, class: "lc2" } + LineChart { data: vec![23, 50, 40, 50, 52], max: 100, class: "lc3" } + } } div { class: "overview-card",