ezel 0.0.1

A good plotting library
Documentation
// https://github.com/has2k1/plotnine/blob/main/plotnine/themes/__init__.py

#[derive(Clone)]
pub struct XY<T> {
    pub x: T,
    pub y: T,
}

#[derive(Clone)]
pub struct XYZ<T> {
    pub x: T,
    pub y: T,
    pub z: T,
}

#[derive(Clone)]
pub struct Theme {
    pub root_padding: f64, // padding top=bottom=left=right
    pub cartesian2: Cartesian2Theme,
    pub grid: GridTheme,
    // pub cartesian3: Cartesian3Theme,
    // pub legend: LegendTheme,
    // pub color_bar: ColorBarTheme,
    // marker_shape: MakerShape,
    // marker_siez: f64,
    // stroke_color: Color,
    // stroke_thickness: f64,
    // glow_color: Color,
    // glow_thickness: f64,
}

#[derive(Clone)]
pub struct GridTheme {
    pub row_padding: f64, // spacing between rows
    pub col_padding: f64, // spacing between cols
}

#[derive(Clone)]
pub struct LegendTheme {
    pub is_frame_visible: bool,
    // padding: ,
    // patch_color: Color,
}

#[derive(Clone)]
// https://github.com/JuliaPlots/Makie.jl/blob/master/src/themes/theme_ggplot2.jl
pub struct Cartesian2Theme {
    pub background: Option<Color>,
    pub x_axis: AxisTheme,
    pub y_axis: AxisTheme,
    pub draw_top_spine: bool,
    pub draw_bottom_spine: bool,
    pub draw_left_spine: bool,
    pub draw_right_spine: bool,
    // background_color: Color,
    pub grid_line: XY<Option<GuideLineTheme>>,
    // minor_grid_color: XY<Color>,
    // is_minor_grid_visible: XY<bool>,
    // is_minor_tick_visible: XY<bool>,
    // tick_color: XY<Color>,
    // tick_label_color: XY<Color>,
    // tick_size: XY<f64>,
    // tick_width: XY<f64>,
    // grid_width: XY<f64>,
    // label_padding: XY<f64>,
}

#[derive(Clone)]
pub struct GuideLineTheme {
    pub width: f64,
    pub color: Color,
}

#[derive(Clone)]
pub struct AxisTheme {
    pub title: LabelTheme,
    pub title_padding: f64,
    pub spine_color: Color,
    pub label: LabelTheme,
    pub label_padding: f64,
    pub tick_label: LabelTheme,
    pub tick_label_padding: f64,
    pub mark_length: f64,
    pub mark_thickness: f64,
    pub mark_color: Color,
    pub auto_limit_margin: f64,
}

impl AxisTheme {
    pub fn tick_label_offset(&self) -> f64 {
        self.mark_length + self.tick_label_padding
    }
    pub fn x_label_offset(&self) -> f64 {
        if self.tick_label.size > 0.0 {
            self.tick_label_offset() + self.tick_label.size + self.label_padding
        } else {
            self.mark_length + self.label_padding
        }
    }
    pub fn y_label_offset(&self, tick_label_width: f64) -> f64 {
        if self.tick_label.size > 0.0 {
            self.tick_label_offset() + tick_label_width + self.label_padding
        } else {
            self.mark_length + self.label_padding
        }
    }
    pub fn x_total_offset(&self, has_label: bool) -> f64 {
        let mut offset: f64 = 0.0;
        if self.tick_label.size > 0.0 {
            offset = offset.max(self.tick_label_offset() + self.tick_label.size);
        }
        if has_label {
            offset = offset.max(self.x_label_offset() + self.label.size);
        }
        offset
    }
    pub fn y_total_offset(&self, has_label: bool, tick_label_width: f64) -> f64 {
        let mut offset: f64 = 0.0;
        if self.tick_label.size > 0.0 {
            offset = offset.max(self.tick_label_offset() + self.tick_label.size);
        }
        if has_label {
            offset = offset.max(self.y_label_offset(tick_label_width) + self.label.size);
        }
        offset
    }
}

#[derive(Clone)]
pub struct LabelTheme {
    pub family: &'static str,
    pub size: f64,
    pub color: Color,
}

#[derive(Clone)]
pub struct Cartesian3Theme {
    // grid_color: XYZ<Color>,
    // is_spine_visible: XYZ<bool>,
    // panel_color: XYZ<Color>,
    // tick_label_color: XYZ<Color>,
}

#[derive(Clone)]
pub struct ColorBarTheme {
    // tick_color: Color,
    // tick_align: f64,
    // tick_label_color: Color,
    // spine_width: f64,
    // tick_label_padding: f64,
}

pub const MAKIE_AXIS_THEME: AxisTheme = AxisTheme {
    title: LabelTheme {
        family: "DejaVu Sans",
        size: 16.0,
        color: Color::BLACK,
    },
    title_padding: 4.0,
    spine_color: Color::BLACK,
    label: LabelTheme {
        family: "DejaVu Sans",
        size: 16.0,
        color: Color::BLACK,
    },
    label_padding: 3.0,
    mark_length: 6.0,
    mark_thickness: 1.0,
    mark_color: Color::BLACK,
    tick_label: LabelTheme {
        family: "DejaVu Sans",
        size: 16.0,
        color: Color::BLACK,
    },
    tick_label_padding: 2.0,
    auto_limit_margin: 0.05,
};

pub const MAKIE: Theme = Theme {
    root_padding: 16.0,
    cartesian2: Cartesian2Theme {
        x_axis: MAKIE_AXIS_THEME,
        y_axis: MAKIE_AXIS_THEME,
        background: Some(Color::WHITE),
        draw_top_spine: false,
        draw_bottom_spine: false,
        draw_left_spine: false,
        draw_right_spine: false,
        grid_line: XY {
            x: Some(GuideLineTheme {
                width: 1.0,
                color: Color::rgba8(0, 0, 0, 30),
            }),
            y: Some(GuideLineTheme {
                width: 1.0,
                color: Color::rgba8(0, 0, 0, 30),
            }),
        },
    },
    grid: GridTheme {
        row_padding: 24.0,
        col_padding: 24.0,
    },
};

// const Ggplot2: Theme = Theme {};

// TODO: 'theme_538'
// TODO: 'theme_bw'
// TODO: 'theme_classic',
// TODO: 'theme_dark'
// TODO: 'theme_gray'
// TODO: 'theme_grey',
// TODO: 'theme_light'
// TODO: 'theme_linedraw',
// TODO: 'theme_matplotlib'
// TODO: 'theme_minimal',
// TODO: 'theme_seaborn'
// TODO: 'theme_void'
// TODO: 'theme_xkcd'
// TODO: 'theme_tufte',
// TODO: 'theme_get'
// TODO: 'theme_set'
// TODO: 'theme_update',

use piet::Color;