use embedded_charts::prelude::*;
#[path = "../common/mod.rs"]
mod common;
use common::WindowConfig;
#[cfg(feature = "std")]
fn main() -> ChartResult<()> {
let mut temperature_stream = StreamingAnimator::<Point2D>::new();
let mut cpu_usage_stream = StreamingAnimator::<Point2D>::new();
let mut network_stream = StreamingAnimator::<Point2D>::new();
let temp_chart = LineChart::builder()
.line_color(Rgb565::RED)
.line_width(2)
.build()?;
let cpu_chart = LineChart::builder()
.line_color(Rgb565::BLUE)
.line_width(2)
.build()?;
let network_chart = LineChart::builder()
.line_color(Rgb565::GREEN)
.line_width(2)
.build()?;
let mut last_temp_update = 0.0f32;
let mut last_cpu_update = 0.0f32;
let mut last_network_update = 0.0f32;
println!("🚀 Starting Streaming Animation Demo");
println!("📊 Red: Temperature (10 Hz), Blue: CPU Usage (5 Hz), Green: Network I/O (20 Hz)");
println!("⏱️ Each series updates at different rates to demonstrate streaming capabilities");
let _chart_config = ChartConfig {
background_color: Some(Rgb565::WHITE),
margins: Margins {
top: 5,
right: 80, bottom: 5,
left: 5,
},
..Default::default()
};
use embedded_graphics::{
mono_font::{ascii::FONT_6X10, MonoTextStyle},
prelude::*,
text::{Baseline, Text},
};
let text_style = MonoTextStyle::new(&FONT_6X10, Rgb565::BLACK);
let mut temp_series = StaticDataSeries::<Point2D, 256>::new();
let mut cpu_series = StaticDataSeries::<Point2D, 256>::new();
let mut network_series = StaticDataSeries::<Point2D, 256>::new();
let _temp_update_rate = 0.1; let _cpu_update_rate = 0.2; let _network_update_rate = 0.05; let _frame_delta_ms = 16;
let _temp_base = 20.0;
let _temp_amplitude_1 = 10.0;
let _temp_amplitude_2 = 2.0;
let _temp_freq_1 = 0.5;
let _temp_freq_2 = 2.0;
let _cpu_base = 30.0;
let _cpu_amplitude = 20.0;
let _cpu_freq = 0.3;
let _cpu_spike_amplitude = 15.0;
let _cpu_spike_interval = 3;
let _network_base = 10.0;
let _network_amplitude_1 = 25.0;
let _network_amplitude_2 = 20.0;
let _network_freq = 1.5;
let _network_burst_multiplier = 10.0;
let _network_burst_interval = 7;
let chart_height_divisor = 3u32;
let margin = 5u32;
common::window::run(
WindowConfig::new("Streaming Animation Demo")
.fps(60)
.background(Rgb565::WHITE),
move |display, viewport, elapsed| {
let time = elapsed;
if time - last_temp_update >= 0.1 {
let temp_value = 20.0 + 10.0 * (time * 0.5).sin() + 2.0 * (time * 2.0).cos();
temperature_stream.push_data(Point2D::new(time, temp_value));
last_temp_update = time;
}
if time - last_cpu_update >= 0.2 {
let cpu_value = 30.0
+ 20.0 * (time * 0.3).sin()
+ 15.0 * if (time as u32) % 3 == 0 { 1.0 } else { 0.0 };
cpu_usage_stream.push_data(Point2D::new(time, cpu_value.min(100.0)));
last_cpu_update = time;
}
if time - last_network_update >= 0.05 {
let network_value = 10.0
+ 25.0 * (time * 1.5).sin().abs()
+ 20.0
* if (time * 10.0) as u32 % 7 == 0 {
1.0
} else {
0.0
};
network_stream.push_data(Point2D::new(time, network_value.min(100.0)));
last_network_update = time;
}
let _ = temperature_stream.update_with_delta(16); let _ = cpu_usage_stream.update_with_delta(16);
let _ = network_stream.update_with_delta(16);
let chart_height = viewport.size.height / chart_height_divisor;
let temp_viewport = Rectangle::new(
viewport.top_left,
Size::new(viewport.size.width, chart_height - margin),
);
let cpu_viewport = Rectangle::new(
Point::new(
viewport.top_left.x,
viewport.top_left.y + chart_height as i32,
),
Size::new(viewport.size.width, chart_height - margin),
);
let network_viewport = Rectangle::new(
Point::new(
viewport.top_left.x,
viewport.top_left.y + (chart_height * 2) as i32,
),
Size::new(viewport.size.width, chart_height - margin),
);
temp_series.clear();
cpu_series.clear();
network_series.clear();
for point in temperature_stream.current_data() {
let _ = temp_series.push(point);
}
for point in cpu_usage_stream.current_data() {
let _ = cpu_series.push(point);
}
for point in network_stream.current_data() {
let _ = network_series.push(point);
}
if !temp_series.is_empty() {
temp_chart.draw(&temp_series, temp_chart.config(), temp_viewport, display)?;
}
if !cpu_series.is_empty() {
cpu_chart.draw(&cpu_series, cpu_chart.config(), cpu_viewport, display)?;
}
if !network_series.is_empty() {
network_chart.draw(
&network_series,
network_chart.config(),
network_viewport,
display,
)?;
}
Text::with_baseline(
"Temperature (°C)",
Point::new(temp_viewport.top_left.x + 5, temp_viewport.top_left.y + 15),
text_style,
Baseline::Top,
)
.draw(display)
.map_err(|_| ChartError::RenderingError)?;
Text::with_baseline(
"CPU Usage (%)",
Point::new(cpu_viewport.top_left.x + 5, cpu_viewport.top_left.y + 15),
text_style,
Baseline::Top,
)
.draw(display)
.map_err(|_| ChartError::RenderingError)?;
Text::with_baseline(
"Network I/O (MB/s)",
Point::new(
network_viewport.top_left.x + 5,
network_viewport.top_left.y + 15,
),
text_style,
Baseline::Top,
)
.draw(display)
.map_err(|_| ChartError::RenderingError)?;
Ok(())
},
)
}
#[cfg(not(feature = "std"))]
fn main() {
common::utils::print_feature_requirement("std", "streaming animation");
}