Skip to main content

ggplot_rs/facet/
mod.rs

1pub mod grid;
2pub mod wrap;
3
4use crate::render::Rect;
5
6/// Whether facet panels share axes.
7#[derive(Clone, Debug)]
8pub enum FacetScales {
9    Fixed,
10    FreeX,
11    FreeY,
12    Free,
13}
14
15/// How facet strip labels are formatted.
16#[derive(Clone, Default)]
17pub enum FacetLabeller {
18    /// Show just the value (default).
19    #[default]
20    Value,
21    /// Show "var: value".
22    Both,
23    /// Custom formatting function: fn(variable_name, value) -> label.
24    Custom(fn(&str, &str) -> String),
25}
26
27impl FacetLabeller {
28    pub fn format(&self, var: &str, value: &str) -> String {
29        match self {
30            FacetLabeller::Value => value.to_string(),
31            FacetLabeller::Both => format!("{var}: {value}"),
32            FacetLabeller::Custom(f) => f(var, value),
33        }
34    }
35}
36
37/// A single panel in a faceted layout.
38#[derive(Clone, Debug)]
39pub struct Panel {
40    pub row: usize,
41    pub col: usize,
42    pub label: String,
43    pub row_label: Option<String>,
44    pub col_label: Option<String>,
45    pub rect: Rect,
46}
47
48/// Facet specification.
49#[derive(Clone, Default)]
50pub enum Facet {
51    #[default]
52    None,
53    Wrap {
54        var: String,
55        ncol: Option<usize>,
56        scales: FacetScales,
57        labeller: FacetLabeller,
58    },
59    Grid {
60        row_var: Option<String>,
61        col_var: Option<String>,
62        scales: FacetScales,
63        labeller: FacetLabeller,
64    },
65}
66
67impl Facet {
68    pub fn is_none(&self) -> bool {
69        matches!(self, Facet::None)
70    }
71
72    pub fn labeller(&self) -> &FacetLabeller {
73        match self {
74            Facet::None => &FacetLabeller::Value,
75            Facet::Wrap { labeller, .. } => labeller,
76            Facet::Grid { labeller, .. } => labeller,
77        }
78    }
79}