use std::error::Error;
use plotters::{
backend::DrawingBackend,
prelude::{RGBColor, BLACK},
};
use crate::{
drawing_coords::DrawingCoords,
linear_model::draw_points,
plot_options::PlotOptions,
plottable::{Plottable, PlottableValues},
};
#[derive(Clone, Debug)]
pub struct Points {
pub x: Vec<f64>,
pub y: Vec<f64>,
pub size: u32,
pub color: RGBColor,
pub force_fit_all: bool,
pub legend: bool,
pub label: String,
}
impl Default for Points {
fn default() -> Self {
Self {
x: Vec::new(),
y: Vec::new(),
size: 2,
color: BLACK,
force_fit_all: true,
legend: false,
label: "".to_string(),
}
}
}
impl<B: DrawingBackend> Plottable<B> for Points
where
B::ErrorType: 'static,
{
fn plot(
&self,
plot_options: &PlotOptions,
drawing_coords: &DrawingCoords,
) -> Result<PlottableValues, Box<dyn Error>> {
let mut xs = self.x.clone();
let mut ys = self.y.clone();
if plot_options.x_log {
for x in xs.iter_mut() {
*x = x.abs().log10();
}
}
if plot_options.y_log {
for y in ys.iter_mut() {
*y = y.abs().log10();
}
}
let coords = draw_points(&xs, &ys, &drawing_coords)?;
Ok(PlottableValues {
points: vec![(
coords,
self.size,
self.color,
if self.legend {
Some(self.label.clone())
} else {
None
},
)],
..Default::default()
})
}
fn force_fit(&self) -> bool {
self.force_fit_all
}
fn get_x(&self) -> Vec<f64> {
self.x.clone()
}
fn get_y(&self) -> Vec<f64> {
self.y.clone()
}
fn get_legend(&self) -> bool {
self.legend
}
}