1use fission_core::{Action, ActionId};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
5pub enum ChartTooltipTrigger {
6 None,
7 Item,
8 Axis,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum ChartSelectionMode {
13 None,
14 Single,
15 Multiple,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
19pub enum ChartBrushType {
20 Rect,
21 Horizontal,
22 Vertical,
23 Polygon,
24}
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
27pub enum ChartLegendSelectionMode {
28 Static,
29 Toggle,
30 Single,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
34pub enum ChartEmphasisFocus {
35 None,
36 Series,
37 Data,
38 Adjacent,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
42pub enum ChartToolAction {
43 Restore,
44 SaveImage,
45 DataZoom,
46 Brush,
47}
48
49#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
50pub struct ChartEmphasis {
51 pub enabled: bool,
52 pub focus: ChartEmphasisFocus,
53 pub scale: f32,
54}
55
56impl Default for ChartEmphasis {
57 fn default() -> Self {
58 Self {
59 enabled: false,
60 focus: ChartEmphasisFocus::None,
61 scale: 1.08,
62 }
63 }
64}
65
66impl ChartEmphasis {
67 pub fn series() -> Self {
68 Self {
69 enabled: true,
70 focus: ChartEmphasisFocus::Series,
71 ..Self::default()
72 }
73 }
74
75 pub fn data() -> Self {
76 Self {
77 enabled: true,
78 focus: ChartEmphasisFocus::Data,
79 ..Self::default()
80 }
81 }
82
83 pub fn scale(mut self, scale: f32) -> Self {
84 self.scale = scale;
85 self
86 }
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90pub struct ChartBrush {
91 pub enabled: bool,
92 pub brush_type: ChartBrushType,
93 pub preview_rect: Option<(f32, f32, f32, f32)>,
94}
95
96impl Default for ChartBrush {
97 fn default() -> Self {
98 Self {
99 enabled: false,
100 brush_type: ChartBrushType::Rect,
101 preview_rect: None,
102 }
103 }
104}
105
106impl ChartBrush {
107 pub fn rect() -> Self {
108 Self {
109 enabled: true,
110 brush_type: ChartBrushType::Rect,
111 preview_rect: None,
112 }
113 }
114
115 pub fn horizontal() -> Self {
116 Self {
117 enabled: true,
118 brush_type: ChartBrushType::Horizontal,
119 preview_rect: None,
120 }
121 }
122
123 pub fn vertical() -> Self {
124 Self {
125 enabled: true,
126 brush_type: ChartBrushType::Vertical,
127 preview_rect: None,
128 }
129 }
130
131 pub fn preview_rect(mut self, x: f32, y: f32, width: f32, height: f32) -> Self {
132 self.preview_rect = Some((x, y, width, height));
133 self
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
138pub struct ChartInteraction {
139 pub enabled: bool,
140 pub tooltip_trigger: ChartTooltipTrigger,
141 pub selection_mode: ChartSelectionMode,
142 pub legend_selection: ChartLegendSelectionMode,
143 pub brush: Option<ChartBrush>,
144 pub emphasis: ChartEmphasis,
145 pub toolbox_actions: Vec<ChartToolAction>,
146 pub emit_events: bool,
147 pub keyboard_focus: bool,
148}
149
150impl Default for ChartInteraction {
151 fn default() -> Self {
152 Self {
153 enabled: false,
154 tooltip_trigger: ChartTooltipTrigger::None,
155 selection_mode: ChartSelectionMode::None,
156 legend_selection: ChartLegendSelectionMode::Static,
157 brush: None,
158 emphasis: ChartEmphasis::default(),
159 toolbox_actions: Vec::new(),
160 emit_events: false,
161 keyboard_focus: false,
162 }
163 }
164}
165
166impl ChartInteraction {
167 pub fn new() -> Self {
168 Self::default()
169 }
170
171 pub fn tooltips(trigger: ChartTooltipTrigger) -> Self {
172 Self {
173 enabled: trigger != ChartTooltipTrigger::None,
174 tooltip_trigger: trigger,
175 ..Self::default()
176 }
177 }
178
179 pub fn enabled(mut self, enabled: bool) -> Self {
180 self.enabled = enabled;
181 self
182 }
183
184 pub fn tooltip_trigger(mut self, trigger: ChartTooltipTrigger) -> Self {
185 self.tooltip_trigger = trigger;
186 self.enabled |= trigger != ChartTooltipTrigger::None;
187 self
188 }
189
190 pub fn selection_mode(mut self, mode: ChartSelectionMode) -> Self {
191 self.selection_mode = mode;
192 self.enabled |= mode != ChartSelectionMode::None;
193 self
194 }
195
196 pub fn brush(mut self, brush: ChartBrush) -> Self {
197 self.brush = Some(brush);
198 self.enabled = true;
199 self
200 }
201
202 pub fn legend_selection(mut self, mode: ChartLegendSelectionMode) -> Self {
203 self.legend_selection = mode;
204 self.enabled |= mode != ChartLegendSelectionMode::Static;
205 self
206 }
207
208 pub fn emphasis(mut self, emphasis: ChartEmphasis) -> Self {
209 self.enabled |= emphasis.enabled;
210 self.emphasis = emphasis;
211 self
212 }
213
214 pub fn toolbox_actions(mut self, actions: Vec<ChartToolAction>) -> Self {
215 self.enabled |= !actions.is_empty();
216 self.toolbox_actions = actions;
217 self
218 }
219
220 pub fn emit_events(mut self, emit: bool) -> Self {
221 self.emit_events = emit;
222 self.enabled |= emit;
223 self
224 }
225
226 pub fn keyboard_focus(mut self, focusable: bool) -> Self {
227 self.keyboard_focus = focusable;
228 self.enabled |= focusable;
229 self
230 }
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
234pub enum ChartInteractionKind {
235 Hover,
236 Press,
237 Release,
238 Scroll,
239 Key,
240}
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
243pub enum ChartHitKind {
244 SeriesItem,
245 PlotArea,
246}
247
248#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
249pub struct ChartHit {
250 pub kind: ChartHitKind,
251 pub series_index: Option<usize>,
252 pub series_name: Option<String>,
253 pub data_index: Option<usize>,
254 pub value_x: Option<f32>,
255 pub value_y: Option<f32>,
256}
257
258impl ChartHit {
259 pub fn plot_area() -> Self {
260 Self {
261 kind: ChartHitKind::PlotArea,
262 series_index: None,
263 series_name: None,
264 data_index: None,
265 value_x: None,
266 value_y: None,
267 }
268 }
269
270 pub fn series_item(
271 series_index: usize,
272 series_name: impl Into<String>,
273 data_index: usize,
274 value_x: Option<f32>,
275 value_y: Option<f32>,
276 ) -> Self {
277 Self {
278 kind: ChartHitKind::SeriesItem,
279 series_index: Some(series_index),
280 series_name: Some(series_name.into()),
281 data_index: Some(data_index),
282 value_x,
283 value_y,
284 }
285 }
286}
287
288#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
289pub struct ChartInteractionEvent {
290 pub chart_id: Option<String>,
291 pub kind: ChartInteractionKind,
292 pub local_x: f32,
293 pub local_y: f32,
294 pub modifiers: u8,
295 pub hit: Option<ChartHit>,
296}
297
298impl Action for ChartInteractionEvent {
299 fn static_id() -> ActionId {
300 ActionId::from_name("fission_charts::ChartInteractionEvent")
301 }
302}