use plotters::{backend::DrawingBackend, coord::Shift, drawing::DrawingArea};
use crate::plot_options::PlotOptions;
#[derive(Copy, Clone, Debug)]
pub struct DrawingCoords {
pub chart_left: f64,
pub chart_right: f64,
pub chart_top: f64,
pub chart_bottom: f64,
pub chart_width: f64,
pub chart_height: f64,
pub x_min: f64,
pub x_max: f64,
pub x_space: f64,
pub y_min: f64,
pub y_max: f64,
pub y_space: f64,
}
pub fn drawing_coords<
'a,
'b,
B: DrawingBackend,
I1: IntoIterator<Item = &'a f64>,
I2: IntoIterator<Item = &'b f64>,
>(
x_data: I1,
y_data: I2,
root: &DrawingArea<B, Shift>,
options: &PlotOptions,
) -> DrawingCoords {
let x = x_data.into_iter().cloned().collect::<Vec<_>>();
let x_min = options
.x_min
.map(|x| if options.x_log { x.abs().log10() } else { x })
.unwrap_or(
x.iter()
.filter(|x| x.is_finite())
.cloned()
.min_by(|f1, f2| f1.partial_cmp(f2).unwrap())
.unwrap_or(0.0),
);
let x_max = options
.x_max
.map(|x| if options.x_log { x.abs().log10() } else { x })
.unwrap_or(
x.iter()
.filter(|x| x.is_finite())
.cloned()
.max_by(|f1, f2| f1.partial_cmp(f2).unwrap())
.unwrap_or(0.0),
);
let x_space = (x_max - x_min).abs() * options.x_plot_scalar;
let y = y_data.into_iter().cloned().collect::<Vec<_>>();
let y_min = options
.y_min
.map(|y| if options.y_log { y.abs().log10() } else { y })
.unwrap_or(
y.iter()
.filter(|y| y.is_finite())
.cloned()
.min_by(|f1, f2| f1.partial_cmp(f2).unwrap())
.unwrap_or(0.0),
);
let y_max = options
.y_max
.map(|y| if options.y_log { y.abs().log10() } else { y })
.unwrap_or(
y.iter()
.filter(|y| y.is_finite())
.cloned()
.max_by(|f1, f2| f1.partial_cmp(f2).unwrap())
.unwrap_or(0.0),
);
let y_space = (y_max - y_min).abs() * options.y_plot_scalar;
let (root_width, root_height) = root.dim_in_pixel();
let top = if options.title.is_empty() {
0.0
} else {
(root_height as f64) * options.graph_title_space_top
} + ((root_height as f64) * options.graph_space_top);
let bottom = (root_height as f64) - ((root_height as f64) * options.graph_label_bottom);
let left = (root_width as f64) * options.graph_label_left;
let right = (root_width as f64) - ((root_width as f64) * options.graph_space_right);
DrawingCoords {
chart_top: top,
chart_left: left,
chart_right: right,
chart_bottom: bottom,
chart_height: root_height as f64,
chart_width: root_width as f64,
x_min,
x_max,
x_space,
y_min,
y_max,
y_space,
}
}