plotkit_core/charts/line.rs
1//! Line chart builder methods.
2//!
3//! This module extends [`LineArtist`] with a fluent API for configuring
4//! line chart properties. Since [`Axes::plot`] returns `Result<&mut LineArtist>`,
5//! these builder methods can be chained directly on the return value:
6//!
7//! ```ignore
8//! ax.plot(&x, &y)?
9//! .color(Color::rgb(0.2, 0.4, 0.8))
10//! .width(2.0)
11//! .style(LineStyle::Dashed)
12//! .label("Series A")
13//! .alpha(0.9);
14//! ```
15
16use crate::artist::LineArtist;
17use crate::decimate::DecimateMethod;
18use crate::primitives::Color;
19use crate::theme::LineStyle;
20
21impl LineArtist {
22 /// Sets the line color.
23 ///
24 /// Accepts any [`Color`] value, which can be constructed from RGB components,
25 /// hex strings, or named color constants.
26 ///
27 /// # Examples
28 ///
29 /// ```ignore
30 /// artist.color(Color::rgb(1.0, 0.0, 0.0)); // red
31 /// ```
32 pub fn color(&mut self, color: Color) -> &mut Self {
33 self.color = color;
34 self
35 }
36
37 /// Sets the line width in pixels.
38 ///
39 /// A width of `1.0` is the default hairline width. Values below `1.0` may
40 /// produce sub-pixel rendering depending on the backend.
41 ///
42 /// # Examples
43 ///
44 /// ```ignore
45 /// artist.width(2.5);
46 /// ```
47 pub fn width(&mut self, width: f64) -> &mut Self {
48 self.width = width;
49 self
50 }
51
52 /// Sets the line style (solid, dashed, dotted, dash-dot).
53 ///
54 /// The [`LineStyle`] enum defines the available stroke patterns. The default
55 /// is [`LineStyle::Solid`].
56 ///
57 /// # Examples
58 ///
59 /// ```ignore
60 /// artist.style(LineStyle::Dashed);
61 /// ```
62 pub fn style(&mut self, style: LineStyle) -> &mut Self {
63 self.style = style;
64 self
65 }
66
67 /// Sets the legend label for this line.
68 ///
69 /// When a label is set, the line will appear in the legend if one is
70 /// displayed on the axes. Pass an empty string or omit this call to
71 /// exclude the line from the legend.
72 ///
73 /// # Examples
74 ///
75 /// ```ignore
76 /// artist.label("Temperature");
77 /// ```
78 pub fn label(&mut self, label: &str) -> &mut Self {
79 self.label = Some(label.to_string());
80 self
81 }
82
83 /// Sets the opacity (0.0 = fully transparent, 1.0 = fully opaque).
84 ///
85 /// The value is clamped to the `[0.0, 1.0]` range. The default opacity
86 /// is `1.0`.
87 ///
88 /// # Examples
89 ///
90 /// ```ignore
91 /// artist.alpha(0.5); // 50% transparent
92 /// ```
93 pub fn alpha(&mut self, alpha: f64) -> &mut Self {
94 self.alpha = alpha.clamp(0.0, 1.0);
95 self
96 }
97
98 /// Enables LTTB decimation with the given point threshold.
99 ///
100 /// When the data series length exceeds `threshold`, the rendering
101 /// pipeline downsamples the data using the Largest Triangle Three
102 /// Buckets algorithm before drawing. This dramatically improves
103 /// rendering performance for large datasets (100k+ points) with
104 /// negligible visual impact.
105 ///
106 /// # Examples
107 ///
108 /// ```ignore
109 /// ax.plot(&x, &y)?.decimate(1000);
110 /// ```
111 pub fn decimate(&mut self, threshold: usize) -> &mut Self {
112 self.decimate = Some((threshold, DecimateMethod::Lttb));
113 self
114 }
115
116 /// Enables decimation with a specific method and point threshold.
117 ///
118 /// Available methods:
119 /// - [`DecimateMethod::Lttb`] — best visual fidelity (default)
120 /// - [`DecimateMethod::MinMax`] — fastest, preserves peaks/troughs
121 ///
122 /// # Examples
123 ///
124 /// ```ignore
125 /// ax.plot(&x, &y)?.decimate_with(1000, DecimateMethod::MinMax);
126 /// ```
127 pub fn decimate_with(&mut self, threshold: usize, method: DecimateMethod) -> &mut Self {
128 self.decimate = Some((threshold, method));
129 self
130 }
131}