1use densa_core::Rect;
2
3use crate::Axis;
4
5#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Plot {
9 area: Rect,
10 x: Axis,
11 y: Axis,
12}
13
14impl Plot {
15 pub fn new(area: Rect, x: Axis, y: Axis) -> Self {
17 Self { area, x, y }
18 }
19
20 pub fn area(&self) -> Rect {
22 self.area
23 }
24
25 pub fn x(&self) -> Axis {
27 self.x
28 }
29
30 pub fn y(&self) -> Axis {
32 self.y
33 }
34
35 #[must_use]
37 pub fn with_x(self, x: Axis) -> Self {
38 Self { x, ..self }
39 }
40
41 #[must_use]
43 pub fn with_y(self, y: Axis) -> Self {
44 Self { y, ..self }
45 }
46
47 pub fn x_px(&self, value: f64) -> f32 {
49 self.x_at(value) as f32
51 }
52
53 pub fn y_px(&self, value: f64) -> f32 {
55 self.y_at(value) as f32
57 }
58
59 pub fn x_value(&self, px: f32) -> f64 {
61 let width = f64::from(self.area.width());
62 self.x
63 .value_at((f64::from(px) - f64::from(self.area.x0)) / width)
64 }
65
66 pub fn y_value(&self, px: f32) -> f64 {
68 let height = f64::from(self.area.height());
69 self.y
70 .value_at((f64::from(self.area.y1) - f64::from(px)) / height)
71 }
72
73 pub(crate) fn x_at(&self, value: f64) -> f64 {
75 f64::from(self.area.x0) + self.x.fraction(value) * f64::from(self.area.width())
76 }
77
78 pub(crate) fn y_at(&self, value: f64) -> f64 {
80 f64::from(self.area.y1) - self.y.fraction(value) * f64::from(self.area.height())
81 }
82
83 pub(crate) fn x_length(&self, distance: f64) -> f64 {
85 distance / self.x.span() * f64::from(self.area.width())
86 }
87
88 pub(crate) fn clamp_y(&self, y: f64) -> f64 {
90 let (top, bottom) = (f64::from(self.area.y0), f64::from(self.area.y1));
91 y.clamp(top - 1.0, bottom + 1.0)
92 }
93}