Skip to main content

poincare_lib/
graph_spec.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{AxisConfig, CurveInterpolation, Domain, PlotStyle, Resolution};
4
5/// Canonical library-owned graph document model.
6///
7/// This is the declarative layer that higher-level clients should build and edit.
8/// Later phases can compile this into concrete `PlotObject`s / `GraphScene`.
9#[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/// Declarative plot entry owned by `poincare-lib`.
31#[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/// Canonical plot-definition enum for reusable graphing and analysis layers.
42#[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}