use super::{CoordLayout, CoordinateTrait, Rect};
use crate::error::ChartonError;
use crate::scale::{ExplicitTick, ScaleTrait};
use crate::theme::Theme;
use crate::visual::color::SingleColor;
use std::sync::Arc;
pub struct Cartesian2D {
pub x_scale: Arc<dyn ScaleTrait>,
pub y_scale: Arc<dyn ScaleTrait>,
pub x_field: String,
pub y_field: String,
pub flipped: bool,
}
impl Cartesian2D {
pub fn new(
x_scale: Arc<dyn ScaleTrait>,
y_scale: Arc<dyn ScaleTrait>,
x_field: String,
y_field: String,
flipped: bool,
) -> Self {
Self {
x_scale,
y_scale,
x_field,
y_field,
flipped,
}
}
}
impl CoordinateTrait for Cartesian2D {
fn render_axes(
&self,
svg: &mut String,
theme: &Theme,
panel: &Rect,
x_label: &str,
x_explicit: Option<&[ExplicitTick]>,
y_label: &str,
y_explicit: Option<&[ExplicitTick]>,
) -> Result<(), ChartonError> {
crate::render::cartesian2d_axis_renderer::render_cartesian_axes(
svg, theme, panel, self, x_label, x_explicit, y_label, y_explicit,
)
}
fn transform(&self, x_norm: f64, y_norm: f64, panel: &Rect) -> (f64, f64) {
let (mut x_p, mut y_p) = (x_norm, y_norm);
if self.flipped {
std::mem::swap(&mut x_p, &mut y_p);
}
let final_x = panel.x + (x_p * panel.width);
let final_y = panel.y + ((1.0 - y_p) * panel.height);
(final_x, final_y)
}
fn get_x_arc(&self) -> Arc<dyn ScaleTrait> {
self.x_scale.clone()
}
fn get_y_arc(&self) -> Arc<dyn ScaleTrait> {
self.y_scale.clone()
}
fn get_x_scale(&self) -> &dyn ScaleTrait {
self.x_scale.as_ref()
}
fn get_y_scale(&self) -> &dyn ScaleTrait {
self.y_scale.as_ref()
}
fn get_x_label(&self) -> &str {
&self.x_field
}
fn get_y_label(&self) -> &str {
&self.y_field
}
fn is_flipped(&self) -> bool {
self.flipped
}
fn is_clipped(&self) -> bool {
true
}
fn layout_hints(&self) -> CoordLayout {
CoordLayout {
default_bar_stroke: SingleColor::new("black"),
default_bar_stroke_width: 1.0,
default_bar_width: 0.5,
default_bar_spacing: 0.0,
default_bar_span: 0.7,
needs_interpolation: false,
}
}
}