use kuva::plot::SeriesPlot;
use kuva::backend::svg::SvgBackend;
use kuva::render::render::render_multiple;
use kuva::render::layout::Layout;
use kuva::render::plots::Plot;
const OUT: &str = "docs/src/assets/series";
const N: usize = 80;
fn main() {
std::fs::create_dir_all(OUT).expect("could not create docs/src/assets/series");
basic();
multi_series();
styles();
styled();
println!("Series SVGs written to {OUT}/");
}
fn basic() {
let data: Vec<f64> = (0..N)
.map(|i| (i as f64 * 2.0 * std::f64::consts::PI / N as f64).sin())
.collect();
let series = SeriesPlot::new()
.with_data(data)
.with_color("steelblue")
.with_line_style();
let plots = vec![Plot::Series(series)];
let layout = Layout::auto_from_plots(&plots)
.with_title("Series Plot — Line Style")
.with_x_label("Sample")
.with_y_label("Amplitude");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/basic.svg"), svg).unwrap();
}
fn multi_series() {
let pi2 = 2.0 * std::f64::consts::PI;
let sin_data: Vec<f64> = (0..N)
.map(|i| (i as f64 * pi2 / N as f64).sin())
.collect();
let cos_data: Vec<f64> = (0..N)
.map(|i| (i as f64 * pi2 / N as f64).cos())
.collect();
let damped: Vec<f64> = (0..N)
.map(|i| {
let t = i as f64 * pi2 / N as f64;
(-t * 0.5).exp() * t.sin()
})
.collect();
let s1 = SeriesPlot::new()
.with_data(sin_data)
.with_color("steelblue")
.with_line_style()
.with_legend("sin(t)");
let s2 = SeriesPlot::new()
.with_data(cos_data)
.with_color("firebrick")
.with_line_style()
.with_legend("cos(t)");
let s3 = SeriesPlot::new()
.with_data(damped)
.with_color("seagreen")
.with_line_style()
.with_stroke_width(1.5)
.with_legend("e^(−t/2)·sin(t)");
let plots = vec![Plot::Series(s1), Plot::Series(s2), Plot::Series(s3)];
let layout = Layout::auto_from_plots(&plots)
.with_title("Multiple Series")
.with_x_label("Sample")
.with_y_label("Amplitude");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/multi.svg"), svg).unwrap();
}
fn styles() {
let data: Vec<f64> = (0..30)
.map(|i| (i as f64 * 2.0 * std::f64::consts::PI / 30.0).sin())
.collect();
let make = |name: &str, title: &str, series: SeriesPlot| {
let plots = vec![Plot::Series(series)];
let layout = Layout::auto_from_plots(&plots)
.with_title(title)
.with_x_label("Sample")
.with_y_label("Amplitude");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/style_{name}.svg"), svg).unwrap();
};
make("line", "SeriesStyle::Line",
SeriesPlot::new().with_data(data.clone()).with_color("steelblue").with_line_style());
make("point", "SeriesStyle::Point",
SeriesPlot::new().with_data(data.clone()).with_color("steelblue").with_point_style());
make("both", "SeriesStyle::Both",
SeriesPlot::new().with_data(data).with_color("steelblue").with_line_point_style());
}
fn styled() {
let data: Vec<f64> = (0..N)
.map(|i| {
let t = i as f64 * 2.0 * std::f64::consts::PI / N as f64;
t.sin() + (3.0 * t).sin() * 0.3
})
.collect();
let series = SeriesPlot::new()
.with_data(data)
.with_color("darkorchid")
.with_line_point_style()
.with_stroke_width(1.5)
.with_point_radius(4.0)
.with_legend("signal");
let plots = vec![Plot::Series(series)];
let layout = Layout::auto_from_plots(&plots)
.with_title("Custom Stroke & Point Size")
.with_x_label("Sample")
.with_y_label("Amplitude");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/styled.svg"), svg).unwrap();
}