egui_charts/config/tooltip.rs
1//! Tooltip configuration for data display on hover.
2//!
3//! Provides three tooltip variants:
4//! - **Floating**: Classic tooltip popup that follows the cursor
5//! - **Tracking**: Fixed horizontal bar at the top of the chart showing OHLC data
6//! - **Magnifier**: Circular zoom lens for detailed data inspection on dense charts
7
8use crate::tokens::DESIGN_TOKENS;
9use egui::Color32;
10
11/// Tooltip display mode
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
13pub enum TooltipMode {
14 /// Floating tooltip that follows cursor position
15 /// Shows OHLC, volume, and change info in a popup near the mouse
16 #[default]
17 Floating,
18
19 /// Tracking tooltip - fixed position bar at top of chart
20 /// Shows: O: xxx H: xxx L: xxx C: xxx Vol: xxx (+x.xx%)
21 /// Updates as cursor moves horizontally across the chart
22 Tracking,
23
24 /// Magnifier tooltip - circular zoom lens following cursor
25 /// Shows magnified view of candles/data under the cursor
26 /// Useful for detailed analysis on dense charts
27 Magnifier,
28}
29
30impl std::fmt::Display for TooltipMode {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 match self {
33 TooltipMode::Floating => write!(f, "Floating"),
34 TooltipMode::Tracking => write!(f, "Tracking"),
35 TooltipMode::Magnifier => write!(f, "Magnifier"),
36 }
37 }
38}
39
40/// Tooltip configuration options
41#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
42#[non_exhaustive]
43pub struct TooltipOptions {
44 /// Whether the hover readout is drawn at all.
45 ///
46 /// When `false` the chart still shows the crosshair but suppresses the
47 /// OHLC/value readout, matching charting UIs that let users toggle the
48 /// data tooltip independently of the crosshair.
49 pub enabled: bool,
50
51 /// Show values only while the primary pointer is held. Touch waits for a long press.
52 pub on_long_press: bool,
53
54 /// Tooltip display mode
55 pub mode: TooltipMode,
56
57 /// Show OHLC values (Open, High, Low, Close)
58 pub show_ohlc: bool,
59
60 /// Show volume
61 pub show_volume: bool,
62
63 /// Include volume study plot details in held values, in addition to total volume.
64 /// Other study values and hover readouts retain their existing visibility.
65 #[serde(default)]
66 pub show_volume_details: bool,
67
68 /// Show price change (absolute and percentage)
69 pub show_change: bool,
70
71 /// Show ts
72 pub show_time: bool,
73
74 /// Show indicator values (if indicators are present)
75 pub show_indicators: bool,
76
77 /// Magnifier zoom level (2.0 = 2x zoom, 3.0 = 3x zoom), drawn within 0.1 to 100 (NaN as 0.1)
78 /// Only applies when mode is Magnifier
79 pub magnifier_zoom: f32,
80
81 /// Magnifier lens diameter in pixels, drawn no larger than the plot's smaller side
82 /// Only applies when mode is Magnifier
83 pub magnifier_size: f32,
84
85 /// Background color for floating tooltip (`Color32::PLACEHOLDER`: active theme)
86 pub background_color: Color32,
87
88 /// Text color for tooltip content (`Color32::PLACEHOLDER`: active theme)
89 pub text_color: Color32,
90
91 /// Border color for the floating tooltip of a rising bar (`Color32::PLACEHOLDER`: active theme)
92 pub border_color_bullish: Color32,
93
94 /// Border color for the floating tooltip of a falling bar (`Color32::PLACEHOLDER`: active theme)
95 pub border_color_bearish: Color32,
96
97 /// Font size for tooltip text
98 pub font_size: f32,
99
100 /// Most decimals for price values. The floating tooltip shows fewer for prices whose
101 /// magnitude needs fewer; the tracking bar shows this many, at most 4.
102 pub price_precision: usize,
103
104 /// Tracking bar height (for Tracking mode)
105 pub tracking_bar_height: f32,
106
107 /// Tracking bar background color (`Color32::PLACEHOLDER`: active theme)
108 pub tracking_bar_background: Color32,
109}
110
111impl Default for TooltipOptions {
112 fn default() -> Self {
113 Self {
114 enabled: true,
115 on_long_press: false,
116 mode: TooltipMode::Floating,
117 show_ohlc: true,
118 show_volume: true,
119 show_volume_details: false,
120 show_change: true,
121 show_time: true,
122 show_indicators: true,
123 magnifier_zoom: 2.0,
124 magnifier_size: 120.0,
125 background_color: Color32::PLACEHOLDER,
126 text_color: Color32::PLACEHOLDER,
127 border_color_bullish: Color32::PLACEHOLDER,
128 border_color_bearish: Color32::PLACEHOLDER,
129 font_size: 11.0,
130 price_precision: 8,
131 tracking_bar_height: 24.0,
132 tracking_bar_background: Color32::PLACEHOLDER,
133 }
134 }
135}
136
137impl TooltipOptions {
138 /// These options with `Color32::PLACEHOLDER` colours taken from the theme applied to
139 /// `ctx`, or from the dark tokens when none has been applied.
140 pub(crate) fn resolved(&self, ctx: &egui::Context) -> Self {
141 let theme = crate::theme::applied_theme(ctx);
142 let chart = theme.as_ref().map(|theme| theme.chart);
143 let border = theme.map(|theme| theme.ui.border);
144 let tokens = &DESIGN_TOKENS.semantic;
145 let or = |color: Color32, themed: Option<Color32>, fallback: Color32| {
146 if color == Color32::PLACEHOLDER {
147 themed.unwrap_or(fallback)
148 } else {
149 color
150 }
151 };
152 Self {
153 background_color: or(
154 self.background_color,
155 chart.map(|c| c.bg_tooltip),
156 tokens.extended.chart_tooltip_bg,
157 ),
158 text_color: or(
159 self.text_color,
160 chart.map(|c| c.axis_text),
161 tokens.extended.chart_text,
162 ),
163 border_color_bullish: or(self.border_color_bullish, border, tokens.ui.border_dark),
164 border_color_bearish: or(self.border_color_bearish, border, tokens.ui.border_dark),
165 tracking_bar_background: or(
166 self.tracking_bar_background,
167 chart.map(|c| c.bg),
168 tokens.chart.bg,
169 ),
170 ..self.clone()
171 }
172 }
173
174 /// Create tooltip options with floating mode
175 pub fn floating() -> Self {
176 Self {
177 mode: TooltipMode::Floating,
178 ..Default::default()
179 }
180 }
181
182 /// Create tooltip options with tracking mode
183 pub fn tracking() -> Self {
184 Self {
185 mode: TooltipMode::Tracking,
186 ..Default::default()
187 }
188 }
189
190 /// Create tooltip options with magnifier mode
191 pub fn magnifier() -> Self {
192 Self {
193 mode: TooltipMode::Magnifier,
194 ..Default::default()
195 }
196 }
197
198 /// Create magnifier with custom zoom level
199 pub fn magnifier_with_zoom(zoom: f32) -> Self {
200 Self {
201 mode: TooltipMode::Magnifier,
202 magnifier_zoom: zoom,
203 ..Default::default()
204 }
205 }
206
207 /// Set tooltip mode
208 pub fn with_mode(mut self, mode: TooltipMode) -> Self {
209 self.mode = mode;
210 self
211 }
212
213 /// Enable or disable the hover readout.
214 pub fn with_enabled(mut self, enabled: bool) -> Self {
215 self.enabled = enabled;
216 self
217 }
218
219 /// Enable/disable OHLC display
220 pub fn with_ohlc(mut self, show: bool) -> Self {
221 self.show_ohlc = show;
222 self
223 }
224
225 /// Enable/disable volume display
226 pub fn with_volume(mut self, show: bool) -> Self {
227 self.show_volume = show;
228 self
229 }
230
231 /// Enable/disable change display
232 pub fn with_change(mut self, show: bool) -> Self {
233 self.show_change = show;
234 self
235 }
236
237 /// Set magnifier zoom level
238 pub fn with_magnifier_zoom(mut self, zoom: f32) -> Self {
239 self.magnifier_zoom = zoom;
240 self
241 }
242
243 /// Set magnifier size
244 pub fn with_magnifier_size(mut self, size: f32) -> Self {
245 self.magnifier_size = size;
246 self
247 }
248
249 /// Set price precision
250 pub fn with_precision(mut self, precision: usize) -> Self {
251 self.price_precision = precision;
252 self
253 }
254}