use crate::plots::traits::PlotConfig;
use crate::render::{Color, MarkerStyle};
#[derive(Debug, Clone)]
pub struct ScatterConfig {
pub marker: MarkerStyle,
pub size: f32,
pub color: Option<Color>,
pub alpha: f32,
pub edge_color: Option<Color>,
pub edge_width: f32,
pub show_edge: bool,
}
impl Default for ScatterConfig {
fn default() -> Self {
Self {
marker: MarkerStyle::Circle,
size: 6.0,
color: None,
alpha: 1.0,
edge_color: None,
edge_width: 0.5,
show_edge: true,
}
}
}
impl PlotConfig for ScatterConfig {}
impl ScatterConfig {
pub fn new() -> Self {
Self::default()
}
pub fn marker(mut self, marker: MarkerStyle) -> Self {
self.marker = marker;
self
}
pub fn size(mut self, size: f32) -> Self {
self.size = size.max(0.1);
self
}
pub fn color(mut self, color: Color) -> Self {
self.color = Some(color);
self
}
pub fn alpha(mut self, alpha: f32) -> Self {
self.alpha = alpha.clamp(0.0, 1.0);
self
}
pub fn edge_color(mut self, color: Color) -> Self {
self.edge_color = Some(color);
self
}
pub fn edge_width(mut self, width: f32) -> Self {
self.edge_width = width.max(0.0);
self
}
pub fn show_edge(mut self, show: bool) -> Self {
self.show_edge = show;
self
}
pub fn s(self, size: f32) -> Self {
self.size(size)
}
pub fn c(self, color: Color) -> Self {
self.color(color)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = ScatterConfig::default();
assert!(matches!(config.marker, MarkerStyle::Circle));
assert!((config.size - 6.0).abs() < f32::EPSILON);
assert!(config.color.is_none());
assert!((config.alpha - 1.0).abs() < f32::EPSILON);
assert!(config.show_edge);
}
#[test]
fn test_builder_methods() {
let config = ScatterConfig::new()
.marker(MarkerStyle::Square)
.size(12.0)
.color(Color::BLUE)
.alpha(0.8)
.edge_color(Color::BLACK)
.edge_width(1.5);
assert!(matches!(config.marker, MarkerStyle::Square));
assert!((config.size - 12.0).abs() < f32::EPSILON);
assert_eq!(config.color, Some(Color::BLUE));
assert!((config.alpha - 0.8).abs() < f32::EPSILON);
assert_eq!(config.edge_color, Some(Color::BLACK));
assert!((config.edge_width - 1.5).abs() < f32::EPSILON);
}
#[test]
fn test_size_clamping() {
let config = ScatterConfig::new().size(-5.0);
assert!((config.size - 0.1).abs() < f32::EPSILON);
}
#[test]
fn test_matplotlib_aliases() {
let config = ScatterConfig::new().s(10.0).c(Color::GREEN);
assert!((config.size - 10.0).abs() < f32::EPSILON);
assert_eq!(config.color, Some(Color::GREEN));
}
}