Skip to main content

ggplot_rs/position/
dodge2.rs

1use crate::data::DataFrame;
2
3use super::dodge::dodge_rows;
4use super::{Position, PositionParams};
5
6/// Like position_dodge but preserves total width and adds padding between
7/// groups (ggplot2's `position_dodge2(width, padding, reverse)`). Elements
8/// are centred exactly as [`PositionDodge`](struct@super::dodge::PositionDodge)
9/// places them; on a continuous axis `xmin`/`xmax` shrink to
10/// `(1 − padding)` of each group's share.
11#[derive(Clone, Debug, PartialEq)]
12pub struct PositionDodge2 {
13    pub padding: f64,
14    /// Total dodge width; `None` = the layer default (0.9).
15    pub width: Option<f64>,
16    /// Reverse the group order.
17    pub reverse: bool,
18}
19
20impl PositionDodge2 {
21    pub fn new(padding: f64) -> Self {
22        PositionDodge2 {
23            padding,
24            ..Default::default()
25        }
26    }
27
28    /// Set the total dodge width.
29    pub fn with_width(mut self, width: f64) -> Self {
30        self.width = Some(width);
31        self
32    }
33
34    /// Reverse the order of the dodged groups (`reverse = TRUE`).
35    pub fn with_reverse(mut self, reverse: bool) -> Self {
36        self.reverse = reverse;
37        self
38    }
39}
40
41impl Default for PositionDodge2 {
42    fn default() -> Self {
43        PositionDodge2 {
44            padding: 0.1,
45            width: None,
46            reverse: false,
47        }
48    }
49}
50
51impl Position for PositionDodge2 {
52    fn compute(&self, data: &mut DataFrame, params: &PositionParams) {
53        dodge_rows(
54            data,
55            self.width.unwrap_or(params.width),
56            Some(self.padding),
57            self.reverse,
58        );
59    }
60
61    fn name(&self) -> &str {
62        "dodge2"
63    }
64}