use kuva::backend::svg::SvgBackend;
use kuva::plot::line::LinePlot;
use kuva::plot::scatter::ScatterPlot;
use kuva::render::annotations::{ReferenceLine, TextAnnotation};
use kuva::render::layout::Layout;
use kuva::render::plots::Plot;
use kuva::render::render::render_multiple;
const OUT: &str = "docs/src/assets/scale";
fn base_plots() -> Vec<Plot> {
let scatter_pts: Vec<(f64, f64)> = vec![
(1.0, 2.1), (2.0, 3.8), (3.0, 5.5), (4.0, 7.0), (5.0, 9.2),
(6.0, 10.8), (7.0, 12.1), (8.0, 14.5), (9.0, 15.9), (10.0, 18.0),
];
let line_pts: Vec<(f64, f64)> = vec![(1.0, 1.9), (10.0, 18.2)];
vec![
Plot::Scatter(
ScatterPlot::new()
.with_data(scatter_pts)
.with_color("steelblue")
.with_legend("Observations"),
),
Plot::Line(
LinePlot::new()
.with_data(line_pts)
.with_color("crimson")
.with_legend("Trend"),
),
]
}
fn base_layout(plots: &[Plot]) -> Layout {
Layout::auto_from_plots(plots)
.with_title("Growth Rate")
.with_x_label("Time (weeks)")
.with_y_label("Count")
.with_annotation(
TextAnnotation::new("Peak", 9.0, 15.9)
.with_arrow(9.0, 15.9)
.with_font_size(11)
.with_color("dimgray"),
)
.with_reference_line(
ReferenceLine::horizontal(10.0)
.with_color("orange")
.with_label("threshold"),
)
}
fn write(name: &str, svg: String) {
let path = format!("{OUT}/{name}.svg");
std::fs::write(&path, svg).unwrap();
println!(" wrote {path}");
}
fn scale_comparison() {
for (label, scale) in [
("scale_0_5x", 0.5_f64),
("scale_1x", 1.0),
("scale_1_5x", 1.5),
("scale_2x", 2.0),
] {
let plots = base_plots();
let layout = base_layout(&plots).with_scale(scale);
let scene = render_multiple(plots, layout);
write(label, SvgBackend.render_scene(&scene));
}
}
fn annotation_not_scaled() {
let plots = base_plots();
let layout = base_layout(&plots).with_scale(2.0);
let scene = render_multiple(plots, layout);
write("annotation_not_scaled", SvgBackend.render_scene(&scene));
}
fn annotation_scaled_manually() {
let scatter_pts: Vec<(f64, f64)> = vec![
(1.0, 2.1), (2.0, 3.8), (3.0, 5.5), (4.0, 7.0), (5.0, 9.2),
(6.0, 10.8), (7.0, 12.1), (8.0, 14.5), (9.0, 15.9), (10.0, 18.0),
];
let line_pts: Vec<(f64, f64)> = vec![(1.0, 1.9), (10.0, 18.2)];
let plots = vec![
Plot::Scatter(
ScatterPlot::new()
.with_data(scatter_pts)
.with_color("steelblue")
.with_legend("Observations"),
),
Plot::Line(
LinePlot::new()
.with_data(line_pts)
.with_color("crimson")
.with_legend("Trend"),
),
];
let scale = 2.0_f64;
let layout = Layout::auto_from_plots(&plots)
.with_title("Growth Rate")
.with_x_label("Time (weeks)")
.with_y_label("Count")
.with_annotation(
TextAnnotation::new("Peak", 9.0, 15.9)
.with_arrow(9.0, 15.9)
.with_font_size((11.0 * scale).round() as u32) .with_color("dimgray"),
)
.with_reference_line(
ReferenceLine::horizontal(10.0)
.with_color("orange")
.with_label("threshold")
.with_stroke_width(1.0 * scale), )
.with_scale(scale);
let scene = render_multiple(plots, layout);
write("annotation_scaled_manually", SvgBackend.render_scene(&scene));
}
fn scale_with_larger_canvas() {
let plots = base_plots();
let layout = base_layout(&plots)
.with_scale(2.0)
.with_width(1200.0)
.with_height(900.0);
let scene = render_multiple(plots, layout);
write("scale_with_larger_canvas", SvgBackend.render_scene(&scene));
}
fn scale_3x() {
let plots = base_plots();
let layout = base_layout(&plots).with_scale(3.0);
let scene = render_multiple(plots, layout);
write("scale_3x", SvgBackend.render_scene(&scene));
}
fn main() {
std::fs::create_dir_all(OUT).unwrap();
scale_comparison();
annotation_not_scaled();
annotation_scaled_manually();
scale_with_larger_canvas();
scale_3x();
println!("Scale SVGs written to {OUT}/");
}