Skip to main content

riker_lib/
plotting.rs

1use std::path::Path;
2
3use anyhow::{Result, anyhow};
4use kuva::render::layout::Layout;
5use kuva::render::plots::Plot;
6use kuva::render::render::render_twin_y;
7
8// ─── Fulcrum Genomics brand colours (hex for kuva) ──────────────────────────
9
10pub const FG_BLUE: &str = "#26a8e0";
11pub const FG_GREEN: &str = "#38b44a";
12pub const FG_PACIFIC: &str = "#1693b9";
13pub const FG_SKY: &str = "#4dcce8";
14pub const FG_TEAL: &str = "#2fae99";
15pub const FG_EMERALD: &str = "#4dcc68";
16pub const FG_FOREST: &str = "#269e2a";
17
18/// Warm red for warning/alert data series.
19pub const FG_RED: &str = "#e04040";
20
21/// Neutral gray for reference lines and gridlines.
22pub const FG_GRAY: &str = "#b4b4b4";
23
24// ─── Standard plot dimensions (8 × 6 inches at 72 DPI) ─────────────────────
25
26/// Standard plot width in pixels.
27pub const PLOT_WIDTH: f64 = 800.0;
28/// Standard plot height in pixels.
29pub const PLOT_HEIGHT: f64 = 600.0;
30
31// ─── PDF rendering helpers ──────────────────────────────────────────────────
32
33/// Render plots to a PDF file.
34///
35/// Builds a single-Y-axis chart from `plots` and `layout`, renders to PDF,
36/// and writes the result to `path`.
37///
38/// # Errors
39/// Returns an error if PDF rendering fails or the file cannot be written.
40pub fn write_plot_pdf(plots: Vec<Plot>, layout: Layout, path: &Path) -> Result<()> {
41    let pdf_bytes = kuva::render_to_pdf(plots, layout).map_err(|e| anyhow!("{e}"))?;
42    std::fs::write(path, pdf_bytes)?;
43    Ok(())
44}
45
46/// Render a dual-Y-axis chart to a PDF file.
47///
48/// `primary` plots are drawn against the left Y axis; `secondary` plots are
49/// drawn against the right Y2 axis.
50///
51/// # Errors
52/// Returns an error if PDF rendering fails or the file cannot be written.
53pub fn write_twin_y_plot_pdf(
54    primary: Vec<Plot>,
55    secondary: Vec<Plot>,
56    layout: Layout,
57    path: &Path,
58) -> Result<()> {
59    let scene = render_twin_y(primary, secondary, layout);
60    let pdf_bytes =
61        kuva::backend::pdf::PdfBackend.render_scene(&scene).map_err(|e| anyhow!("{e}"))?;
62    std::fs::write(path, pdf_bytes)?;
63    Ok(())
64}