1use esoc_gfx::canvas::Canvas;
5use esoc_gfx::transform::CoordinateTransform;
6
7use crate::theme::Theme;
8
9#[derive(Clone, Copy, Debug)]
11pub struct DataBounds {
12 pub x_min: f64,
14 pub x_max: f64,
16 pub y_min: f64,
18 pub y_max: f64,
20}
21
22impl DataBounds {
23 pub fn new(x_min: f64, x_max: f64, y_min: f64, y_max: f64) -> Self {
25 Self {
26 x_min,
27 x_max,
28 y_min,
29 y_max,
30 }
31 }
32
33 pub fn union(self, other: Self) -> Self {
35 Self {
36 x_min: self.x_min.min(other.x_min),
37 x_max: self.x_max.max(other.x_max),
38 y_min: self.y_min.min(other.y_min),
39 y_max: self.y_max.max(other.y_max),
40 }
41 }
42
43 pub fn pad(self, fraction: f64) -> Self {
45 let x_pad = (self.x_max - self.x_min) * fraction;
46 let y_pad = (self.y_max - self.y_min) * fraction;
47 Self {
48 x_min: self.x_min - x_pad,
49 x_max: self.x_max + x_pad,
50 y_min: self.y_min - y_pad,
51 y_max: self.y_max + y_pad,
52 }
53 }
54}
55
56pub trait SeriesRenderer {
58 fn data_bounds(&self) -> DataBounds;
60
61 fn render(
63 &self,
64 canvas: &mut Canvas,
65 transform: &CoordinateTransform,
66 theme: &Theme,
67 series_index: usize,
68 );
69
70 fn label(&self) -> Option<&str>;
72}