use densa_core::Rect;
use crate::Axis;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Plot {
area: Rect,
x: Axis,
y: Axis,
}
impl Plot {
pub fn new(area: Rect, x: Axis, y: Axis) -> Self {
Self { area, x, y }
}
pub fn area(&self) -> Rect {
self.area
}
pub fn x(&self) -> Axis {
self.x
}
pub fn y(&self) -> Axis {
self.y
}
#[must_use]
pub fn with_x(self, x: Axis) -> Self {
Self { x, ..self }
}
#[must_use]
pub fn with_y(self, y: Axis) -> Self {
Self { y, ..self }
}
pub fn x_px(&self, value: f64) -> f32 {
self.x_at(value) as f32
}
pub fn y_px(&self, value: f64) -> f32 {
self.y_at(value) as f32
}
pub fn x_value(&self, px: f32) -> f64 {
let width = f64::from(self.area.width());
self.x
.value_at((f64::from(px) - f64::from(self.area.x0)) / width)
}
pub fn y_value(&self, px: f32) -> f64 {
let height = f64::from(self.area.height());
self.y
.value_at((f64::from(self.area.y1) - f64::from(px)) / height)
}
pub(crate) fn x_at(&self, value: f64) -> f64 {
f64::from(self.area.x0) + self.x.fraction(value) * f64::from(self.area.width())
}
pub(crate) fn y_at(&self, value: f64) -> f64 {
f64::from(self.area.y1) - self.y.fraction(value) * f64::from(self.area.height())
}
pub(crate) fn x_length(&self, distance: f64) -> f64 {
distance / self.x.span() * f64::from(self.area.width())
}
pub(crate) fn clamp_y(&self, y: f64) -> f64 {
let (top, bottom) = (f64::from(self.area.y0), f64::from(self.area.y1));
y.clamp(top - 1.0, bottom + 1.0)
}
}