1use serde::{Deserialize, Serialize};
2
3use super::source::CacheConfig;
4use super::style::{FontsSpec, GridSpec, LegendSpec};
5use super::transform::TransformSpec;
6
7#[derive(Debug, Clone, Deserialize, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct ChartSpec {
12 pub version: u32,
13 pub title: Option<String>,
14 pub data: DataRef,
15 pub transform: Option<TransformSpec>,
16 pub visualize: VisualizeSpec,
17 pub layout: Option<LayoutSpec>,
18 pub style: Option<StyleRefOrInline>,
19 pub params: Option<Vec<super::params::ParamDef>>,
20}
21
22#[derive(Debug, Clone, Deserialize, Serialize)]
25#[serde(untagged)]
26pub enum DataRef {
27 Named(String),
28 Inline(InlineData),
29}
30
31#[derive(Debug, Clone, Deserialize, Serialize)]
32#[serde(rename_all = "camelCase")]
33pub struct InlineData {
34 pub provider: String,
35 pub rows: Option<Vec<serde_json::Value>>,
36 pub url: Option<String>,
37 pub endpoint: Option<String>,
38 pub cache: Option<CacheConfig>,
39}
40
41#[derive(Debug, Clone, Deserialize, Serialize)]
44#[serde(untagged)]
45pub enum StyleRefOrInline {
46 Named(String),
47 Inline(Box<ChartStyleSpec>),
48}
49
50#[derive(Debug, Clone, Deserialize, Serialize)]
53#[serde(rename_all = "camelCase")]
54pub struct VisualizeSpec {
55 #[serde(rename = "type")]
56 pub chart_type: String,
57 pub mode: Option<ChartMode>,
58 pub orientation: Option<Orientation>,
59 pub columns: Option<FieldRef>,
60 pub rows: Option<FieldRef>,
61 pub marks: Option<MarksSpec>,
62 pub axes: Option<AxesSpec>,
63 pub annotations: Option<Vec<AnnotationSpec>>,
64 pub style: Option<ChartStyleSpec>,
65 pub value: Option<String>,
67 pub label: Option<String>,
68 pub format: Option<String>,
69 pub compare_with: Option<String>,
70 pub invert_trend: Option<bool>,
71 pub data_labels: Option<DataLabelsSpec>,
72}
73
74#[derive(Debug, Clone, Deserialize, Serialize)]
77#[serde(rename_all = "lowercase")]
78pub enum ChartMode {
79 Stacked,
80 Grouped,
81 Normalized,
82}
83
84#[derive(Debug, Clone, Deserialize, Serialize)]
87#[serde(rename_all = "lowercase")]
88pub enum Orientation {
89 Vertical,
90 Horizontal,
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize)]
96#[serde(untagged)]
97pub enum FieldRef {
98 Simple(String),
99 Detailed(Box<FieldSpec>),
100 Multiple(Vec<FieldRefItem>),
101}
102
103#[derive(Debug, Clone, Deserialize, Serialize)]
105#[serde(untagged)]
106pub enum FieldRefItem {
107 Simple(String),
108 Detailed(Box<FieldSpec>),
109}
110
111#[derive(Debug, Clone, Deserialize, Serialize)]
112#[serde(rename_all = "camelCase")]
113pub struct FieldSpec {
114 pub field: String,
115 pub mark: Option<String>,
116 pub axis: Option<String>,
117 pub label: Option<String>,
118 pub color: Option<String>,
119 pub format: Option<String>,
120 pub data_labels: Option<DataLabelsSpec>,
121 pub line_style: Option<String>,
123 pub upper: Option<String>,
125 pub lower: Option<String>,
127 pub opacity: Option<f64>,
129}
130
131#[derive(Debug, Clone, Deserialize, Serialize)]
134#[serde(rename_all = "camelCase")]
135pub struct DataLabelsSpec {
136 pub show: Option<bool>,
137 pub position: Option<String>,
138 pub format: Option<String>,
139 pub color: Option<String>,
140 pub font_size: Option<f64>,
141}
142
143#[derive(Debug, Clone, Deserialize, Serialize)]
146#[serde(rename_all = "camelCase")]
147pub struct MarksSpec {
148 pub color: Option<MarkEncoding>,
149 pub size: Option<MarkEncoding>,
150 pub shape: Option<MarkEncoding>,
151 pub text: Option<MarkEncoding>,
152}
153
154#[derive(Debug, Clone, Deserialize, Serialize)]
155#[serde(untagged)]
156pub enum MarkEncoding {
157 Simple(String),
158 Detailed(MarkEncodingSpec),
159}
160
161#[derive(Debug, Clone, Deserialize, Serialize)]
162#[serde(rename_all = "camelCase")]
163pub struct MarkEncodingSpec {
164 pub field: String,
165 pub label: Option<String>,
166 pub format: Option<String>,
167}
168
169#[derive(Debug, Clone, Deserialize, Serialize)]
172#[serde(rename_all = "camelCase")]
173pub struct AxesSpec {
174 #[serde(alias = "columns", alias = "bottom")]
175 pub x: Option<AxisSpec>,
176 #[serde(alias = "rows")]
177 pub left: Option<AxisSpec>,
178 pub right: Option<AxisSpec>,
179}
180
181#[derive(Debug, Clone, Deserialize, Serialize)]
182#[serde(rename_all = "camelCase")]
183pub struct AxisSpec {
184 pub label: Option<String>,
185 pub format: Option<String>,
186 pub min: Option<f64>,
187 pub max: Option<f64>,
188 pub nice: Option<bool>,
189}
190
191#[derive(Debug, Clone, Deserialize, Serialize)]
194#[serde(rename_all = "camelCase")]
195pub struct AnnotationSpec {
196 #[serde(rename = "type")]
197 pub annotation_type: String,
198 pub axis: Option<String>,
199 pub value: Option<serde_json::Value>,
200 pub from: Option<serde_json::Value>,
201 pub to: Option<serde_json::Value>,
202 pub orientation: Option<String>,
203 pub label: Option<String>,
204 pub label_position: Option<String>,
205 pub color: Option<String>,
206 pub stroke_width: Option<f64>,
207 pub dash_array: Option<String>,
208 pub opacity: Option<f64>,
209 pub stroke_color: Option<String>,
210 pub style: Option<String>,
212}
213
214#[derive(Debug, Clone, Deserialize, Serialize)]
217#[serde(rename_all = "camelCase")]
218pub struct ChartStyleSpec {
219 pub height: Option<f64>,
220 pub width: Option<f64>,
221 pub colors: Option<Vec<String>>,
230 pub grid: Option<GridSpec>,
231 pub show_dots: Option<bool>,
232 pub stroke_width: Option<f64>,
233 pub curve_type: Option<String>,
234 pub fill_opacity: Option<f64>,
235 pub fonts: Option<FontsSpec>,
236 pub legend: Option<LegendSpec>,
237}
238
239#[derive(Debug, Clone, Deserialize, Serialize)]
242#[serde(rename_all = "camelCase")]
243pub struct LayoutSpec {
244 pub col_span: Option<u32>,
245}