Skip to main content

iced_plot/
reference_lines.rs

1use crate::{Color, LineStyle, LineType, Size, series::ShapeId, transform::Transform};
2
3/// A vertical line at a fixed x-coordinate.
4#[derive(Debug, Clone)]
5pub struct VLine {
6    /// Unique identifier for the line.
7    pub id: ShapeId,
8    /// The x-coordinate where the vertical line is drawn.
9    pub x: f64,
10    /// How to interpret or convert the x value before drawing.
11    pub transform: Option<Transform>,
12    /// Optional label for the line (appears in legend if provided).
13    pub label: Option<String>,
14    /// Color of the line.
15    pub color: Color,
16    /// Line styling options, including width and pattern (solid, dashed, dotted).
17    pub line_style: LineStyle,
18}
19
20impl VLine {
21    /// Create a new vertical line at the given x-coordinate.
22    pub fn new(x: f64) -> Self {
23        Self {
24            id: ShapeId::new(),
25            x,
26            transform: None,
27            label: None,
28            color: Color::from_rgb(0.5, 0.5, 0.5),
29            line_style: LineStyle::default(),
30        }
31    }
32
33    /// Set the label for this line (will appear in legend).
34    pub fn with_label(mut self, label: impl Into<String>) -> Self {
35        let l = label.into();
36        if !l.is_empty() {
37            self.label = Some(l);
38        }
39        self
40    }
41
42    /// Set the color of the line.
43    pub fn with_color(mut self, color: Color) -> Self {
44        self.color = color;
45        self
46    }
47
48    /// Set how this reference line interprets or converts its x value before drawing.
49    ///
50    /// For normal data values, conversion runs before the plot's x-axis scale.
51    /// `Transform::axes()` uses normalized plot positions instead.
52    pub fn with_transform(mut self, transform: Transform) -> Self {
53        self.transform = Some(transform);
54        self
55    }
56
57    /// Interpret the x position as a normalized plot coordinate.
58    pub fn with_axes_transform(mut self) -> Self {
59        self.transform = Some(Transform::axes());
60        self
61    }
62
63    /// Set the line width in pixels.
64    pub fn with_width(mut self, width: f32) -> Self {
65        self.line_style.width = Size::Pixels(width.max(0.5));
66        self
67    }
68
69    /// Set the line width in world units.
70    pub fn with_width_world(mut self, width: f64) -> Self {
71        self.line_style.width = Size::World(width.max(f64::EPSILON));
72        self
73    }
74
75    /// Set the line style.
76    pub fn with_style(mut self, style: LineStyle) -> Self {
77        let old_width = self.line_style.width;
78        let preserve_width = style.width == LineStyle::default().width;
79        self.line_style = style;
80        if preserve_width {
81            self.line_style.width = old_width;
82        }
83        self
84    }
85
86    /// Set only the line type while preserving the current width.
87    pub fn with_line_type(mut self, line_type: LineType) -> Self {
88        self.line_style.line_type = line_type;
89        self
90    }
91}
92
93/// A horizontal line at a fixed y-coordinate.
94#[derive(Debug, Clone)]
95pub struct HLine {
96    /// Unique identifier for the line.
97    pub id: ShapeId,
98    /// The y-coordinate where the horizontal line is drawn.
99    pub y: f64,
100    /// How to interpret or convert the y value before drawing.
101    pub transform: Option<Transform>,
102    /// Optional label for the line (appears in legend if provided).
103    pub label: Option<String>,
104    /// Color of the line.
105    pub color: Color,
106    /// Line styling options, including width and pattern (solid, dashed, dotted).
107    pub line_style: LineStyle,
108}
109
110impl HLine {
111    /// Create a new horizontal line at the given y-coordinate.
112    pub fn new(y: f64) -> Self {
113        Self {
114            id: ShapeId::new(),
115            y,
116            transform: None,
117            label: None,
118            color: Color::from_rgb(0.5, 0.5, 0.5),
119            line_style: LineStyle::default(),
120        }
121    }
122
123    /// Set the label for this line (will appear in legend).
124    pub fn with_label(mut self, label: impl Into<String>) -> Self {
125        let l = label.into();
126        if !l.is_empty() {
127            self.label = Some(l);
128        }
129        self
130    }
131
132    /// Set the color of the line.
133    pub fn with_color(mut self, color: Color) -> Self {
134        self.color = color;
135        self
136    }
137
138    /// Set how this reference line interprets or converts its y value before drawing.
139    ///
140    /// For normal data values, conversion runs before the plot's y-axis scale.
141    /// `Transform::axes()` uses normalized plot positions instead.
142    pub fn with_transform(mut self, transform: Transform) -> Self {
143        self.transform = Some(transform);
144        self
145    }
146
147    /// Interpret the y position as a normalized plot coordinate.
148    pub fn with_axes_transform(mut self) -> Self {
149        self.transform = Some(Transform::axes());
150        self
151    }
152
153    /// Set the line width in pixels.
154    pub fn with_width(mut self, width: f32) -> Self {
155        self.line_style.width = Size::Pixels(width.max(0.5));
156        self
157    }
158
159    /// Set the line width in world units.
160    pub fn with_width_world(mut self, width: f64) -> Self {
161        self.line_style.width = Size::World(width.max(f64::EPSILON));
162        self
163    }
164
165    /// Set the line style.
166    pub fn with_style(mut self, style: LineStyle) -> Self {
167        let old_width = self.line_style.width;
168        let preserve_width = style.width == LineStyle::default().width;
169        self.line_style = style;
170        if preserve_width {
171            self.line_style.width = old_width;
172        }
173        self
174    }
175
176    /// Set only the line type while preserving the current width.
177    pub fn with_line_type(mut self, line_type: LineType) -> Self {
178        self.line_style.line_type = line_type;
179        self
180    }
181}