1use serde::{Deserialize, Serialize};
2
3use crate::{AxisConfig, CurveInterpolation, Domain, PlotStyle, Resolution};
4
5#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct GraphSpec {
11 pub axis_config: AxisConfig,
12 pub plots: Vec<PlotSpec>,
13}
14
15impl GraphSpec {
16 pub fn new() -> Self {
17 Self {
18 axis_config: AxisConfig::default(),
19 plots: Vec::new(),
20 }
21 }
22}
23
24impl Default for GraphSpec {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30#[derive(Clone, Debug, Serialize, Deserialize)]
32pub struct PlotSpec {
33 pub name: String,
34 pub visible: bool,
35 pub domain: Domain,
36 pub resolution: Resolution,
37 pub style: PlotStyle,
38 pub definition: PlotDefinition,
39}
40
41#[derive(Clone, Debug, Serialize, Deserialize)]
43pub enum PlotDefinition {
44 ContouredSurface {
45 contour_values: Vec<f32>,
46 contour_style: PlotStyle,
47 },
48 SphericalHarmonic,
49 HelixCurve,
50 ScatterCloud,
51 VectorField,
52 GridSurface,
53 Streamlines {
54 seeds: Vec<[f32; 3]>,
55 },
56 VolumeRender {
57 resolution: [u32; 3],
58 },
59 Isosurface {
60 isovalues: Vec<f64>,
61 resolution: [u32; 3],
62 },
63 ExprCartesian {
64 expression: String,
65 parameters: Vec<(String, f64)>,
66 },
67 ExprCurve {
68 expression: String,
69 parameters: Vec<(String, f64)>,
70 t_range: (f64, f64),
71 },
72 ExprCartesianLine {
73 dep_var: String,
74 ind_var: String,
75 expression: String,
76 parameters: Vec<(String, f64)>,
77 },
78 ExprSpherical {
79 expression: String,
80 parameters: Vec<(String, f64)>,
81 },
82 ExprCylindrical {
83 expression: String,
84 parameters: Vec<(String, f64)>,
85 },
86 ExprPolar {
87 expression: String,
88 parameters: Vec<(String, f64)>,
89 },
90 ExprParametricSurface {
91 expression: String,
92 parameters: Vec<(String, f64)>,
93 },
94 ImportedTable {
95 definition: TableImportDefinition,
96 },
97 ScalarSlice {
98 expression: String,
99 parameters: Vec<(String, f64)>,
100 axis: SliceAxis,
101 position: f64,
102 contour_values: Vec<f32>,
103 contour_style: PlotStyle,
104 },
105 VectorSlice {
106 expression: String,
107 parameters: Vec<(String, f64)>,
108 axis: SliceAxis,
109 position: f64,
110 },
111 GradientField {
112 expression: String,
113 parameters: Vec<(String, f64)>,
114 },
115 DivergenceField {
116 expression: String,
117 parameters: Vec<(String, f64)>,
118 vol_resolution: [u32; 3],
119 },
120 CurlField {
121 expression: String,
122 parameters: Vec<(String, f64)>,
123 },
124 PointAnnotations {
125 points: Vec<PointAnnotation>,
126 show_labels: bool,
127 },
128 ArrowAnnotations {
129 arrows: Vec<ArrowAnnotation>,
130 show_labels: bool,
131 },
132 DerivedPolylineGroups {
133 groups: Vec<Vec<[f32; 3]>>,
134 },
135 InterpolatedCurve {
136 points: Vec<[f32; 3]>,
137 interpolation: CurveInterpolation,
138 },
139 ExprVectorField {
140 expression: String,
141 parameters: Vec<(String, f64)>,
142 },
143 ExprVolume {
144 expression: String,
145 parameters: Vec<(String, f64)>,
146 vol_resolution: [u32; 3],
147 },
148 ExprIsosurface {
149 expression: String,
150 parameters: Vec<(String, f64)>,
151 isovalues: Vec<f64>,
152 iso_colours: Vec<[f32; 4]>,
153 vol_resolution: [u32; 3],
154 },
155 ExprStreamlines {
156 expression: String,
157 parameters: Vec<(String, f64)>,
158 seed_mode: SeedMode,
159 step_size: f32,
160 max_steps: u32,
161 },
162}
163
164#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
165pub enum SliceAxis {
166 X,
167 Y,
168 Z,
169}
170
171impl SliceAxis {
172 pub const ALL: [Self; 3] = [Self::X, Self::Y, Self::Z];
173
174 pub fn label(self) -> &'static str {
175 match self {
176 Self::X => "X",
177 Self::Y => "Y",
178 Self::Z => "Z",
179 }
180 }
181}
182
183#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
184pub struct PointAnnotation {
185 pub position: [f32; 3],
186 pub label: String,
187}
188
189#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
190pub struct ArrowAnnotation {
191 pub origin: [f32; 3],
192 pub vector: [f32; 3],
193 pub label: String,
194}
195
196#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
197pub enum SeedMode {
198 Grid {
199 nx: u32,
200 ny: u32,
201 nz: u32,
202 },
203 Plane {
204 axis: usize,
205 offset: f32,
206 },
207 ManualCsv {
208 csv_text: String,
209 },
210}
211
212impl Default for SeedMode {
213 fn default() -> Self {
214 Self::Grid {
215 nx: 3,
216 ny: 3,
217 nz: 3,
218 }
219 }
220}
221
222#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
223pub enum TableDelimiter {
224 Comma,
225 Semicolon,
226 Tab,
227 Space,
228 Pipe,
229}
230
231#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
232pub enum TablePlotTarget {
233 SurfaceGrid,
234 Curve,
235 Scatter,
236 VectorField,
237}
238
239#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
240pub struct TableImportDefinition {
241 pub source_path: Option<String>,
242 pub raw_text: String,
243 pub delimiter: TableDelimiter,
244 pub header_row: bool,
245 pub target: TablePlotTarget,
246 pub mapping: TableColumnMapping,
247}
248
249#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
250pub enum OptionalColumn {
251 None,
252 Column(usize),
253}
254
255#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
256pub enum TableColumnMapping {
257 SurfaceGrid {
258 x: usize,
259 y: usize,
260 z: usize,
261 },
262 Curve {
263 x: usize,
264 y: usize,
265 z: OptionalColumn,
266 label: OptionalColumn,
267 group: OptionalColumn,
268 },
269 Scatter {
270 x: usize,
271 y: usize,
272 z: OptionalColumn,
273 scalar: OptionalColumn,
274 label: OptionalColumn,
275 group: OptionalColumn,
276 },
277 VectorField {
278 x: usize,
279 y: usize,
280 z: OptionalColumn,
281 vx: usize,
282 vy: usize,
283 vz: OptionalColumn,
284 scalar: OptionalColumn,
285 label: OptionalColumn,
286 group: OptionalColumn,
287 },
288}