1use serde::{Deserialize, Serialize};
6
7use crate::namespaces;
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(rename = "chartSpace")]
12pub struct ChartSpace {
13 #[serde(rename = "@xmlns:c")]
14 pub xmlns_c: String,
15
16 #[serde(rename = "@xmlns:a")]
17 pub xmlns_a: String,
18
19 #[serde(rename = "@xmlns:r")]
20 pub xmlns_r: String,
21
22 #[serde(rename = "c:chart")]
23 pub chart: Chart,
24}
25
26impl Default for ChartSpace {
27 fn default() -> Self {
28 Self {
29 xmlns_c: namespaces::DRAWING_ML_CHART.to_string(),
30 xmlns_a: namespaces::DRAWING_ML.to_string(),
31 xmlns_r: namespaces::RELATIONSHIPS.to_string(),
32 chart: Chart::default(),
33 }
34 }
35}
36
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
39pub struct Chart {
40 #[serde(rename = "c:title", skip_serializing_if = "Option::is_none")]
41 pub title: Option<ChartTitle>,
42
43 #[serde(rename = "c:view3D", skip_serializing_if = "Option::is_none")]
44 pub view_3d: Option<View3D>,
45
46 #[serde(rename = "c:plotArea")]
47 pub plot_area: PlotArea,
48
49 #[serde(rename = "c:legend", skip_serializing_if = "Option::is_none")]
50 pub legend: Option<Legend>,
51
52 #[serde(rename = "c:plotVisOnly", skip_serializing_if = "Option::is_none")]
53 pub plot_vis_only: Option<BoolVal>,
54}
55
56#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58pub struct ChartTitle {
59 #[serde(rename = "c:tx")]
60 pub tx: TitleTx,
61}
62
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
65pub struct TitleTx {
66 #[serde(rename = "c:rich")]
67 pub rich: RichText,
68}
69
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72pub struct RichText {
73 #[serde(rename = "a:bodyPr")]
74 pub body_pr: BodyPr,
75
76 #[serde(rename = "a:p")]
77 pub paragraphs: Vec<Paragraph>,
78}
79
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82pub struct BodyPr {}
83
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
86pub struct Paragraph {
87 #[serde(rename = "a:r", default)]
88 pub runs: Vec<Run>,
89}
90
91#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
93pub struct Run {
94 #[serde(rename = "a:t")]
95 pub t: String,
96}
97
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
100pub struct PlotArea {
101 #[serde(rename = "c:layout", skip_serializing_if = "Option::is_none")]
102 pub layout: Option<Layout>,
103
104 #[serde(rename = "c:barChart", skip_serializing_if = "Option::is_none")]
105 pub bar_chart: Option<BarChart>,
106
107 #[serde(rename = "c:bar3DChart", skip_serializing_if = "Option::is_none")]
108 pub bar_3d_chart: Option<Bar3DChart>,
109
110 #[serde(rename = "c:lineChart", skip_serializing_if = "Option::is_none")]
111 pub line_chart: Option<LineChart>,
112
113 #[serde(rename = "c:line3DChart", skip_serializing_if = "Option::is_none")]
114 pub line_3d_chart: Option<Line3DChart>,
115
116 #[serde(rename = "c:pieChart", skip_serializing_if = "Option::is_none")]
117 pub pie_chart: Option<PieChart>,
118
119 #[serde(rename = "c:pie3DChart", skip_serializing_if = "Option::is_none")]
120 pub pie_3d_chart: Option<Pie3DChart>,
121
122 #[serde(rename = "c:doughnutChart", skip_serializing_if = "Option::is_none")]
123 pub doughnut_chart: Option<DoughnutChart>,
124
125 #[serde(rename = "c:areaChart", skip_serializing_if = "Option::is_none")]
126 pub area_chart: Option<AreaChart>,
127
128 #[serde(rename = "c:area3DChart", skip_serializing_if = "Option::is_none")]
129 pub area_3d_chart: Option<Area3DChart>,
130
131 #[serde(rename = "c:scatterChart", skip_serializing_if = "Option::is_none")]
132 pub scatter_chart: Option<ScatterChart>,
133
134 #[serde(rename = "c:bubbleChart", skip_serializing_if = "Option::is_none")]
135 pub bubble_chart: Option<BubbleChart>,
136
137 #[serde(rename = "c:radarChart", skip_serializing_if = "Option::is_none")]
138 pub radar_chart: Option<RadarChart>,
139
140 #[serde(rename = "c:stockChart", skip_serializing_if = "Option::is_none")]
141 pub stock_chart: Option<StockChart>,
142
143 #[serde(rename = "c:surfaceChart", skip_serializing_if = "Option::is_none")]
144 pub surface_chart: Option<SurfaceChart>,
145
146 #[serde(rename = "c:surface3DChart", skip_serializing_if = "Option::is_none")]
147 pub surface_3d_chart: Option<Surface3DChart>,
148
149 #[serde(rename = "c:catAx", skip_serializing_if = "Option::is_none")]
150 pub cat_ax: Option<CatAx>,
151
152 #[serde(rename = "c:valAx", skip_serializing_if = "Option::is_none")]
153 pub val_ax: Option<ValAx>,
154
155 #[serde(rename = "c:serAx", skip_serializing_if = "Option::is_none")]
156 pub ser_ax: Option<SerAx>,
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
161pub struct Layout {}
162
163#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
165pub struct BarChart {
166 #[serde(rename = "c:barDir")]
167 pub bar_dir: StringVal,
168
169 #[serde(rename = "c:grouping")]
170 pub grouping: StringVal,
171
172 #[serde(rename = "c:ser", default)]
173 pub series: Vec<Series>,
174
175 #[serde(rename = "c:axId", default)]
176 pub ax_ids: Vec<UintVal>,
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181pub struct Bar3DChart {
182 #[serde(rename = "c:barDir")]
183 pub bar_dir: StringVal,
184
185 #[serde(rename = "c:grouping")]
186 pub grouping: StringVal,
187
188 #[serde(rename = "c:ser", default)]
189 pub series: Vec<Series>,
190
191 #[serde(rename = "c:axId", default)]
192 pub ax_ids: Vec<UintVal>,
193}
194
195#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
197pub struct LineChart {
198 #[serde(rename = "c:grouping")]
199 pub grouping: StringVal,
200
201 #[serde(rename = "c:ser", default)]
202 pub series: Vec<Series>,
203
204 #[serde(rename = "c:axId", default)]
205 pub ax_ids: Vec<UintVal>,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
210pub struct Line3DChart {
211 #[serde(rename = "c:grouping")]
212 pub grouping: StringVal,
213
214 #[serde(rename = "c:ser", default)]
215 pub series: Vec<Series>,
216
217 #[serde(rename = "c:axId", default)]
218 pub ax_ids: Vec<UintVal>,
219}
220
221#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
223pub struct PieChart {
224 #[serde(rename = "c:ser", default)]
225 pub series: Vec<Series>,
226}
227
228#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
230pub struct Pie3DChart {
231 #[serde(rename = "c:ser", default)]
232 pub series: Vec<Series>,
233}
234
235#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
237pub struct DoughnutChart {
238 #[serde(rename = "c:ser", default)]
239 pub series: Vec<Series>,
240
241 #[serde(rename = "c:holeSize", skip_serializing_if = "Option::is_none")]
242 pub hole_size: Option<UintVal>,
243}
244
245#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
247pub struct AreaChart {
248 #[serde(rename = "c:grouping")]
249 pub grouping: StringVal,
250
251 #[serde(rename = "c:ser", default)]
252 pub series: Vec<Series>,
253
254 #[serde(rename = "c:axId", default)]
255 pub ax_ids: Vec<UintVal>,
256}
257
258#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
260pub struct Area3DChart {
261 #[serde(rename = "c:grouping")]
262 pub grouping: StringVal,
263
264 #[serde(rename = "c:ser", default)]
265 pub series: Vec<Series>,
266
267 #[serde(rename = "c:axId", default)]
268 pub ax_ids: Vec<UintVal>,
269}
270
271#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
273pub struct ScatterChart {
274 #[serde(rename = "c:scatterStyle")]
275 pub scatter_style: StringVal,
276
277 #[serde(rename = "c:ser", default)]
278 pub series: Vec<ScatterSeries>,
279
280 #[serde(rename = "c:axId", default)]
281 pub ax_ids: Vec<UintVal>,
282}
283
284#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
286pub struct ScatterSeries {
287 #[serde(rename = "c:idx")]
288 pub idx: UintVal,
289
290 #[serde(rename = "c:order")]
291 pub order: UintVal,
292
293 #[serde(rename = "c:tx", skip_serializing_if = "Option::is_none")]
294 pub tx: Option<SeriesText>,
295
296 #[serde(rename = "c:xVal", skip_serializing_if = "Option::is_none")]
297 pub x_val: Option<CategoryRef>,
298
299 #[serde(rename = "c:yVal", skip_serializing_if = "Option::is_none")]
300 pub y_val: Option<ValueRef>,
301}
302
303#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
305pub struct BubbleChart {
306 #[serde(rename = "c:ser", default)]
307 pub series: Vec<BubbleSeries>,
308
309 #[serde(rename = "c:axId", default)]
310 pub ax_ids: Vec<UintVal>,
311}
312
313#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
315pub struct BubbleSeries {
316 #[serde(rename = "c:idx")]
317 pub idx: UintVal,
318
319 #[serde(rename = "c:order")]
320 pub order: UintVal,
321
322 #[serde(rename = "c:tx", skip_serializing_if = "Option::is_none")]
323 pub tx: Option<SeriesText>,
324
325 #[serde(rename = "c:xVal", skip_serializing_if = "Option::is_none")]
326 pub x_val: Option<CategoryRef>,
327
328 #[serde(rename = "c:yVal", skip_serializing_if = "Option::is_none")]
329 pub y_val: Option<ValueRef>,
330
331 #[serde(rename = "c:bubbleSize", skip_serializing_if = "Option::is_none")]
332 pub bubble_size: Option<ValueRef>,
333}
334
335#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
337pub struct RadarChart {
338 #[serde(rename = "c:radarStyle")]
339 pub radar_style: StringVal,
340
341 #[serde(rename = "c:ser", default)]
342 pub series: Vec<Series>,
343
344 #[serde(rename = "c:axId", default)]
345 pub ax_ids: Vec<UintVal>,
346}
347
348#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
350pub struct StockChart {
351 #[serde(rename = "c:ser", default)]
352 pub series: Vec<Series>,
353
354 #[serde(rename = "c:axId", default)]
355 pub ax_ids: Vec<UintVal>,
356}
357
358#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
360pub struct SurfaceChart {
361 #[serde(rename = "c:wireframe", skip_serializing_if = "Option::is_none")]
362 pub wireframe: Option<BoolVal>,
363
364 #[serde(rename = "c:ser", default)]
365 pub series: Vec<Series>,
366
367 #[serde(rename = "c:axId", default)]
368 pub ax_ids: Vec<UintVal>,
369}
370
371#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
373pub struct Surface3DChart {
374 #[serde(rename = "c:wireframe", skip_serializing_if = "Option::is_none")]
375 pub wireframe: Option<BoolVal>,
376
377 #[serde(rename = "c:ser", default)]
378 pub series: Vec<Series>,
379
380 #[serde(rename = "c:axId", default)]
381 pub ax_ids: Vec<UintVal>,
382}
383
384#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
386pub struct Series {
387 #[serde(rename = "c:idx")]
388 pub idx: UintVal,
389
390 #[serde(rename = "c:order")]
391 pub order: UintVal,
392
393 #[serde(rename = "c:tx", skip_serializing_if = "Option::is_none")]
394 pub tx: Option<SeriesText>,
395
396 #[serde(rename = "c:cat", skip_serializing_if = "Option::is_none")]
397 pub cat: Option<CategoryRef>,
398
399 #[serde(rename = "c:val", skip_serializing_if = "Option::is_none")]
400 pub val: Option<ValueRef>,
401}
402
403#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
405pub struct SeriesText {
406 #[serde(rename = "c:strRef", skip_serializing_if = "Option::is_none")]
407 pub str_ref: Option<StrRef>,
408
409 #[serde(rename = "c:v", skip_serializing_if = "Option::is_none")]
410 pub v: Option<String>,
411}
412
413#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
415pub struct StrRef {
416 #[serde(rename = "c:f")]
417 pub f: String,
418}
419
420#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
422pub struct CategoryRef {
423 #[serde(rename = "c:strRef", skip_serializing_if = "Option::is_none")]
424 pub str_ref: Option<StrRef>,
425
426 #[serde(rename = "c:numRef", skip_serializing_if = "Option::is_none")]
427 pub num_ref: Option<NumRef>,
428}
429
430#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
432pub struct ValueRef {
433 #[serde(rename = "c:numRef", skip_serializing_if = "Option::is_none")]
434 pub num_ref: Option<NumRef>,
435}
436
437#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
439pub struct NumRef {
440 #[serde(rename = "c:f")]
441 pub f: String,
442}
443
444#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
446pub struct Legend {
447 #[serde(rename = "c:legendPos")]
448 pub legend_pos: StringVal,
449}
450
451#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
453pub struct CatAx {
454 #[serde(rename = "c:axId")]
455 pub ax_id: UintVal,
456
457 #[serde(rename = "c:scaling")]
458 pub scaling: Scaling,
459
460 #[serde(rename = "c:delete")]
461 pub delete: BoolVal,
462
463 #[serde(rename = "c:axPos")]
464 pub ax_pos: StringVal,
465
466 #[serde(rename = "c:crossAx")]
467 pub cross_ax: UintVal,
468}
469
470#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
472pub struct ValAx {
473 #[serde(rename = "c:axId")]
474 pub ax_id: UintVal,
475
476 #[serde(rename = "c:scaling")]
477 pub scaling: Scaling,
478
479 #[serde(rename = "c:delete")]
480 pub delete: BoolVal,
481
482 #[serde(rename = "c:axPos")]
483 pub ax_pos: StringVal,
484
485 #[serde(rename = "c:crossAx")]
486 pub cross_ax: UintVal,
487}
488
489#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
491pub struct SerAx {
492 #[serde(rename = "c:axId")]
493 pub ax_id: UintVal,
494
495 #[serde(rename = "c:scaling")]
496 pub scaling: Scaling,
497
498 #[serde(rename = "c:delete")]
499 pub delete: BoolVal,
500
501 #[serde(rename = "c:axPos")]
502 pub ax_pos: StringVal,
503
504 #[serde(rename = "c:crossAx")]
505 pub cross_ax: UintVal,
506}
507
508#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
510pub struct View3D {
511 #[serde(rename = "c:rotX", skip_serializing_if = "Option::is_none")]
512 pub rot_x: Option<IntVal>,
513
514 #[serde(rename = "c:rotY", skip_serializing_if = "Option::is_none")]
515 pub rot_y: Option<IntVal>,
516
517 #[serde(rename = "c:depthPercent", skip_serializing_if = "Option::is_none")]
518 pub depth_percent: Option<UintVal>,
519
520 #[serde(rename = "c:rAngAx", skip_serializing_if = "Option::is_none")]
521 pub r_ang_ax: Option<BoolVal>,
522
523 #[serde(rename = "c:perspective", skip_serializing_if = "Option::is_none")]
524 pub perspective: Option<UintVal>,
525}
526
527#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
529pub struct Scaling {
530 #[serde(rename = "c:orientation")]
531 pub orientation: StringVal,
532}
533
534#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
536pub struct StringVal {
537 #[serde(rename = "@val")]
538 pub val: String,
539}
540
541#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
543pub struct UintVal {
544 #[serde(rename = "@val")]
545 pub val: u32,
546}
547
548#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
550pub struct IntVal {
551 #[serde(rename = "@val")]
552 pub val: i32,
553}
554
555#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
557pub struct BoolVal {
558 #[serde(rename = "@val")]
559 pub val: bool,
560}
561
562#[cfg(test)]
563mod tests {
564 use super::*;
565
566 #[test]
567 fn test_chart_space_default() {
568 let cs = ChartSpace::default();
569 assert_eq!(cs.xmlns_c, namespaces::DRAWING_ML_CHART);
570 assert_eq!(cs.xmlns_a, namespaces::DRAWING_ML);
571 assert_eq!(cs.xmlns_r, namespaces::RELATIONSHIPS);
572 }
573
574 #[test]
575 fn test_string_val_serialize() {
576 let sv = StringVal {
577 val: "col".to_string(),
578 };
579 let xml = quick_xml::se::to_string(&sv).unwrap();
580 assert!(xml.contains("val=\"col\""));
581 }
582
583 #[test]
584 fn test_uint_val_serialize() {
585 let uv = UintVal { val: 42 };
586 let xml = quick_xml::se::to_string(&uv).unwrap();
587 assert!(xml.contains("val=\"42\""));
588 }
589
590 #[test]
591 fn test_int_val_serialize() {
592 let iv = IntVal { val: -15 };
593 let xml = quick_xml::se::to_string(&iv).unwrap();
594 assert!(xml.contains("val=\"-15\""));
595 }
596
597 #[test]
598 fn test_bool_val_serialize() {
599 let bv = BoolVal { val: true };
600 let xml = quick_xml::se::to_string(&bv).unwrap();
601 assert!(xml.contains("val=\"true\""));
602 }
603
604 #[test]
605 fn test_series_serialize() {
606 let series = Series {
607 idx: UintVal { val: 0 },
608 order: UintVal { val: 0 },
609 tx: Some(SeriesText {
610 str_ref: None,
611 v: Some("Sales".to_string()),
612 }),
613 cat: Some(CategoryRef {
614 str_ref: Some(StrRef {
615 f: "Sheet1!$A$2:$A$6".to_string(),
616 }),
617 num_ref: None,
618 }),
619 val: Some(ValueRef {
620 num_ref: Some(NumRef {
621 f: "Sheet1!$B$2:$B$6".to_string(),
622 }),
623 }),
624 };
625 let xml = quick_xml::se::to_string(&series).unwrap();
626 assert!(xml.contains("Sheet1!$A$2:$A$6"));
627 assert!(xml.contains("Sheet1!$B$2:$B$6"));
628 }
629
630 #[test]
631 fn test_bar_chart_serialize() {
632 let bar = BarChart {
633 bar_dir: StringVal {
634 val: "col".to_string(),
635 },
636 grouping: StringVal {
637 val: "clustered".to_string(),
638 },
639 series: vec![],
640 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
641 };
642 let xml = quick_xml::se::to_string(&bar).unwrap();
643 assert!(xml.contains("col"));
644 assert!(xml.contains("clustered"));
645 }
646
647 #[test]
648 fn test_bar_3d_chart_serialize() {
649 let bar = Bar3DChart {
650 bar_dir: StringVal {
651 val: "col".to_string(),
652 },
653 grouping: StringVal {
654 val: "clustered".to_string(),
655 },
656 series: vec![],
657 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
658 };
659 let xml = quick_xml::se::to_string(&bar).unwrap();
660 assert!(xml.contains("col"));
661 assert!(xml.contains("clustered"));
662 }
663
664 #[test]
665 fn test_area_chart_serialize() {
666 let area = AreaChart {
667 grouping: StringVal {
668 val: "standard".to_string(),
669 },
670 series: vec![],
671 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
672 };
673 let xml = quick_xml::se::to_string(&area).unwrap();
674 assert!(xml.contains("standard"));
675 }
676
677 #[test]
678 fn test_scatter_chart_serialize() {
679 let scatter = ScatterChart {
680 scatter_style: StringVal {
681 val: "lineMarker".to_string(),
682 },
683 series: vec![ScatterSeries {
684 idx: UintVal { val: 0 },
685 order: UintVal { val: 0 },
686 tx: None,
687 x_val: Some(CategoryRef {
688 str_ref: None,
689 num_ref: Some(NumRef {
690 f: "Sheet1!$A$2:$A$6".to_string(),
691 }),
692 }),
693 y_val: Some(ValueRef {
694 num_ref: Some(NumRef {
695 f: "Sheet1!$B$2:$B$6".to_string(),
696 }),
697 }),
698 }],
699 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
700 };
701 let xml = quick_xml::se::to_string(&scatter).unwrap();
702 assert!(xml.contains("lineMarker"));
703 assert!(xml.contains("Sheet1!$A$2:$A$6"));
704 assert!(xml.contains("Sheet1!$B$2:$B$6"));
705 }
706
707 #[test]
708 fn test_bubble_chart_serialize() {
709 let bubble = BubbleChart {
710 series: vec![BubbleSeries {
711 idx: UintVal { val: 0 },
712 order: UintVal { val: 0 },
713 tx: None,
714 x_val: None,
715 y_val: None,
716 bubble_size: Some(ValueRef {
717 num_ref: Some(NumRef {
718 f: "Sheet1!$C$2:$C$6".to_string(),
719 }),
720 }),
721 }],
722 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
723 };
724 let xml = quick_xml::se::to_string(&bubble).unwrap();
725 assert!(xml.contains("Sheet1!$C$2:$C$6"));
726 }
727
728 #[test]
729 fn test_radar_chart_serialize() {
730 let radar = RadarChart {
731 radar_style: StringVal {
732 val: "marker".to_string(),
733 },
734 series: vec![],
735 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }],
736 };
737 let xml = quick_xml::se::to_string(&radar).unwrap();
738 assert!(xml.contains("marker"));
739 }
740
741 #[test]
742 fn test_surface_chart_serialize() {
743 let surface = SurfaceChart {
744 wireframe: Some(BoolVal { val: true }),
745 series: vec![],
746 ax_ids: vec![UintVal { val: 1 }, UintVal { val: 2 }, UintVal { val: 3 }],
747 };
748 let xml = quick_xml::se::to_string(&surface).unwrap();
749 assert!(xml.contains("val=\"true\""));
750 }
751
752 #[test]
753 fn test_view_3d_serialize() {
754 let view = View3D {
755 rot_x: Some(IntVal { val: 15 }),
756 rot_y: Some(IntVal { val: 20 }),
757 depth_percent: Some(UintVal { val: 150 }),
758 r_ang_ax: Some(BoolVal { val: true }),
759 perspective: Some(UintVal { val: 30 }),
760 };
761 let xml = quick_xml::se::to_string(&view).unwrap();
762 assert!(xml.contains("val=\"15\""));
763 assert!(xml.contains("val=\"20\""));
764 assert!(xml.contains("val=\"150\""));
765 }
766
767 #[test]
768 fn test_ser_ax_serialize() {
769 let ser_ax = SerAx {
770 ax_id: UintVal { val: 3 },
771 scaling: Scaling {
772 orientation: StringVal {
773 val: "minMax".to_string(),
774 },
775 },
776 delete: BoolVal { val: false },
777 ax_pos: StringVal {
778 val: "b".to_string(),
779 },
780 cross_ax: UintVal { val: 1 },
781 };
782 let xml = quick_xml::se::to_string(&ser_ax).unwrap();
783 assert!(xml.contains("val=\"3\""));
784 assert!(xml.contains("minMax"));
785 }
786
787 #[test]
788 fn test_legend_serialize() {
789 let legend = Legend {
790 legend_pos: StringVal {
791 val: "b".to_string(),
792 },
793 };
794 let xml = quick_xml::se::to_string(&legend).unwrap();
795 assert!(xml.contains("val=\"b\""));
796 }
797
798 #[test]
799 fn test_chart_title_serialize() {
800 let title = ChartTitle {
801 tx: TitleTx {
802 rich: RichText {
803 body_pr: BodyPr {},
804 paragraphs: vec![Paragraph {
805 runs: vec![Run {
806 t: "My Chart".to_string(),
807 }],
808 }],
809 },
810 },
811 };
812 let xml = quick_xml::se::to_string(&title).unwrap();
813 assert!(xml.contains("My Chart"));
814 }
815
816 #[test]
817 fn test_num_ref_serialize() {
818 let num_ref = NumRef {
819 f: "Sheet1!$B$1:$B$5".to_string(),
820 };
821 let xml = quick_xml::se::to_string(&num_ref).unwrap();
822 assert!(xml.contains("Sheet1!$B$1:$B$5"));
823 }
824
825 #[test]
826 fn test_str_ref_serialize() {
827 let str_ref = StrRef {
828 f: "Sheet1!$A$1".to_string(),
829 };
830 let xml = quick_xml::se::to_string(&str_ref).unwrap();
831 assert!(xml.contains("Sheet1!$A$1"));
832 }
833
834 #[test]
835 fn test_plot_area_default_all_none() {
836 let pa = PlotArea::default();
837 assert!(pa.layout.is_none());
838 assert!(pa.bar_chart.is_none());
839 assert!(pa.bar_3d_chart.is_none());
840 assert!(pa.line_chart.is_none());
841 assert!(pa.line_3d_chart.is_none());
842 assert!(pa.pie_chart.is_none());
843 assert!(pa.pie_3d_chart.is_none());
844 assert!(pa.doughnut_chart.is_none());
845 assert!(pa.area_chart.is_none());
846 assert!(pa.area_3d_chart.is_none());
847 assert!(pa.scatter_chart.is_none());
848 assert!(pa.bubble_chart.is_none());
849 assert!(pa.radar_chart.is_none());
850 assert!(pa.stock_chart.is_none());
851 assert!(pa.surface_chart.is_none());
852 assert!(pa.surface_3d_chart.is_none());
853 assert!(pa.cat_ax.is_none());
854 assert!(pa.val_ax.is_none());
855 assert!(pa.ser_ax.is_none());
856 }
857
858 #[test]
859 fn test_chart_with_view_3d() {
860 let chart = Chart {
861 title: None,
862 view_3d: Some(View3D {
863 rot_x: Some(IntVal { val: 15 }),
864 rot_y: Some(IntVal { val: 20 }),
865 depth_percent: None,
866 r_ang_ax: Some(BoolVal { val: true }),
867 perspective: None,
868 }),
869 plot_area: PlotArea::default(),
870 legend: None,
871 plot_vis_only: None,
872 };
873 let xml = quick_xml::se::to_string(&chart).unwrap();
874 assert!(xml.contains("val=\"15\""));
875 assert!(xml.contains("val=\"20\""));
876 }
877
878 #[test]
879 fn test_doughnut_chart_serialize() {
880 let doughnut = DoughnutChart {
881 series: vec![],
882 hole_size: Some(UintVal { val: 50 }),
883 };
884 let xml = quick_xml::se::to_string(&doughnut).unwrap();
885 assert!(xml.contains("val=\"50\""));
886 }
887}