1#[cfg(feature = "serde")]
2pub mod config;
3pub mod elements;
4pub mod presets;
5
6pub use elements::{ElementGeom, ElementLine, ElementRect, ElementText};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum AxisSide {
11 Top,
12 Bottom,
13 Left,
14 Right,
15}
16
17#[derive(Clone, Debug, PartialEq)]
19pub enum LegendPosition {
20 Right,
21 Left,
22 Top,
23 Bottom,
24 None,
25 Inside(f64, f64),
28}
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum LegendCorner {
34 TopLeft,
35 TopRight,
36 BottomLeft,
37 BottomRight,
38}
39
40impl LegendCorner {
41 pub const ALL: [LegendCorner; 4] = [
43 LegendCorner::BottomRight,
44 LegendCorner::BottomLeft,
45 LegendCorner::TopRight,
46 LegendCorner::TopLeft,
47 ];
48
49 pub fn inside(self) -> LegendPosition {
51 match self {
52 LegendCorner::TopLeft => LegendPosition::Inside(0.0, 1.0),
53 LegendCorner::TopRight => LegendPosition::Inside(1.0, 1.0),
54 LegendCorner::BottomLeft => LegendPosition::Inside(0.0, 0.0),
55 LegendCorner::BottomRight => LegendPosition::Inside(1.0, 0.0),
56 }
57 }
58
59 pub fn name(self) -> &'static str {
61 match self {
62 LegendCorner::TopLeft => "top-left",
63 LegendCorner::TopRight => "top-right",
64 LegendCorner::BottomLeft => "bottom-left",
65 LegendCorner::BottomRight => "bottom-right",
66 }
67 }
68}
69
70#[derive(Clone, Copy, Debug, Default, PartialEq)]
73pub enum TitlePosition {
74 #[default]
75 Panel,
76 Plot,
77}
78
79#[derive(Clone, Copy, Debug, Default, PartialEq)]
81pub enum TagPosition {
82 #[default]
83 TopLeft,
84 TopRight,
85 BottomLeft,
86 BottomRight,
87}
88
89#[derive(Clone, Copy, Debug, PartialEq)]
91pub enum LegendDirection {
92 Vertical,
93 Horizontal,
94}
95
96#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
100pub enum AxisLabelFit {
101 Clip,
104 Shift,
109 #[default]
115 Reserve,
116}
117
118#[derive(Clone, Debug)]
120pub struct Margin {
121 pub top: f64,
122 pub right: f64,
123 pub bottom: f64,
124 pub left: f64,
125}
126
127impl Margin {
128 pub fn auto(values: &[f64]) -> Margin {
133 let (t, r, b, l) = match *values {
134 [] => (0.0, 0.0, 0.0, 0.0),
135 [a] => (a, a, a, a),
136 [v, h] => (v, h, v, h),
137 [t, h, b] => (t, h, b, h),
138 [t, r, b, l, ..] => (t, r, b, l),
139 };
140 Margin {
141 top: t,
142 right: r,
143 bottom: b,
144 left: l,
145 }
146 }
147
148 pub fn part(
151 self,
152 top: Option<f64>,
153 right: Option<f64>,
154 bottom: Option<f64>,
155 left: Option<f64>,
156 ) -> Margin {
157 Margin {
158 top: top.unwrap_or(self.top),
159 right: right.unwrap_or(self.right),
160 bottom: bottom.unwrap_or(self.bottom),
161 left: left.unwrap_or(self.left),
162 }
163 }
164}
165
166impl Default for Margin {
167 fn default() -> Self {
168 Margin {
169 top: 10.0,
170 right: 10.0,
171 bottom: 10.0,
172 left: 10.0,
173 }
174 }
175}
176
177#[derive(Clone, Debug)]
179pub struct Theme {
180 pub text: ElementText,
182 pub title: ElementText,
183 pub axis_text_x: ElementText,
184 pub axis_text_y: ElementText,
185 pub axis_title_x: ElementText,
186 pub axis_title_y: ElementText,
187 pub axis_line: ElementLine,
188 pub axis_ticks: ElementLine,
189 pub panel_background: ElementRect,
190 pub panel_grid_major: ElementLine,
191 pub panel_grid_minor: ElementLine,
192 pub plot_background: ElementRect,
193 pub legend_position: LegendPosition,
194 pub plot_margin: Margin,
195
196 pub subtitle: ElementText,
198 pub caption: ElementText,
199 pub legend_title: ElementText,
200 pub legend_text: ElementText,
201 pub strip_text: ElementText,
202
203 pub axis_line_x: Option<ElementLine>,
205 pub axis_line_y: Option<ElementLine>,
206 pub axis_ticks_x: Option<ElementLine>,
207 pub axis_ticks_y: Option<ElementLine>,
208 pub axis_line_x_top: Option<ElementLine>,
212 pub axis_line_x_bottom: Option<ElementLine>,
213 pub axis_line_y_left: Option<ElementLine>,
214 pub axis_line_y_right: Option<ElementLine>,
215 pub axis_ticks_x_top: Option<ElementLine>,
216 pub axis_ticks_x_bottom: Option<ElementLine>,
217 pub axis_ticks_y_left: Option<ElementLine>,
218 pub axis_ticks_y_right: Option<ElementLine>,
219 pub panel_grid_major_x: Option<ElementLine>,
220 pub panel_grid_major_y: Option<ElementLine>,
221 pub panel_grid_minor_x: Option<ElementLine>,
222 pub panel_grid_minor_y: Option<ElementLine>,
223
224 pub panel_border: ElementLine,
226 pub legend_background: ElementRect,
227 pub legend_key: ElementRect,
228 pub strip_background: ElementRect,
229
230 pub axis_ticks_length: f64,
232 pub axis_text_x_dodge: usize,
235 pub legend_key_width: f64,
236 pub legend_key_height: f64,
237 pub legend_spacing: f64,
238 pub legend_ticks_length: f64,
240 pub caption_position: Option<TitlePosition>,
243 pub legend_location_plot: bool,
246 pub axis_ticks_length_x: Option<f64>,
249 pub axis_ticks_length_y: Option<f64>,
250 pub legend_key_spacing_x: Option<f64>,
254 pub legend_key_spacing_y: Option<f64>,
255 pub legend_box_spacing: Option<f64>,
259 pub legend_box_just: f64,
263 pub rich_text: bool,
267 pub tag_location_panel: bool,
270 pub strip_placement_outside: bool,
273 pub strip_switch_pad: f64,
275 pub legend_margin: Margin,
276 pub panel_spacing: f64,
277 pub panel_spacing_x: Option<f64>,
278 pub panel_spacing_y: Option<f64>,
279
280 pub primary: Option<(u8, u8, u8)>,
285
286 pub aspect_ratio: Option<f64>,
289 pub panel_ontop: bool,
291 pub axis_minor_ticks: bool,
293 pub title_position: TitlePosition,
296 pub tag_position: TagPosition,
298 pub legend_direction: Option<LegendDirection>,
300 pub calendar_month_border: ElementLine,
302 pub legend_bar_border: Option<ElementLine>,
306 pub geom: ElementGeom,
309
310 pub axis_text_x_fit: AxisLabelFit,
313 pub axis_text_x_check_overlap: bool,
316 pub axis_text_x_top: Option<ElementText>,
319 pub axis_text_y_right: Option<ElementText>,
322 pub strip_text_x: Option<ElementText>,
326 pub strip_background_x: Option<ElementRect>,
327 pub strip_text_y: Option<ElementText>,
330 pub strip_background_y: Option<ElementRect>,
331}
332
333impl Theme {
334 pub fn legend_key_gap_y(&self) -> f64 {
336 self.legend_key_spacing_y.unwrap_or(0.0).max(0.0)
337 }
338
339 pub fn legend_margin_outer(&self) -> Margin {
342 let mut m = self.legend_margin.clone();
343 if let Some(g) = self.legend_box_spacing {
344 let g = g.max(0.0);
345 match self.legend_position {
346 LegendPosition::Right => m.left = g,
347 LegendPosition::Left => m.right = g,
348 LegendPosition::Top => m.bottom = g,
349 LegendPosition::Bottom => m.top = g,
350 LegendPosition::None | LegendPosition::Inside(..) => {}
351 }
352 }
353 m
354 }
355
356 pub fn ticks_len_x(&self) -> f64 {
358 self.axis_ticks_length_x.unwrap_or(self.axis_ticks_length)
359 }
360
361 pub fn ticks_len_y(&self) -> f64 {
363 self.axis_ticks_length_y.unwrap_or(self.axis_ticks_length)
364 }
365
366 pub fn hide_y_guides(&mut self) {
370 self.axis_text_y.visible = false;
371 self.axis_title_y.visible = false;
372 let hidden = |base: &ElementLine| ElementLine {
373 visible: false,
374 ..base.clone()
375 };
376 self.axis_line_y = Some(hidden(self.axis_line_y.as_ref().unwrap_or(&self.axis_line)));
377 self.axis_ticks_y = Some(hidden(
378 self.axis_ticks_y.as_ref().unwrap_or(&self.axis_ticks),
379 ));
380 self.panel_grid_major_y = Some(hidden(
381 self.panel_grid_major_y
382 .as_ref()
383 .unwrap_or(&self.panel_grid_major),
384 ));
385 self.panel_grid_minor_y = Some(hidden(
386 self.panel_grid_minor_y
387 .as_ref()
388 .unwrap_or(&self.panel_grid_minor),
389 ));
390 }
391
392 pub fn hide_position_guides(&mut self) {
396 for t in [
397 &mut self.axis_text_x,
398 &mut self.axis_text_y,
399 &mut self.axis_title_x,
400 &mut self.axis_title_y,
401 ] {
402 t.visible = false;
403 }
404 for l in [
405 &mut self.axis_line,
406 &mut self.axis_ticks,
407 &mut self.panel_grid_major,
408 &mut self.panel_grid_minor,
409 ] {
410 l.visible = false;
411 }
412 for l in [
413 &mut self.axis_line_x,
414 &mut self.axis_line_y,
415 &mut self.axis_ticks_x,
416 &mut self.axis_ticks_y,
417 &mut self.panel_grid_major_x,
418 &mut self.panel_grid_major_y,
419 &mut self.panel_grid_minor_x,
420 &mut self.panel_grid_minor_y,
421 ]
422 .into_iter()
423 .flatten()
424 {
425 l.visible = false;
426 }
427 }
428
429 pub fn primary_or(&self, fallback: (u8, u8, u8)) -> (u8, u8, u8) {
432 self.primary.unwrap_or(fallback)
433 }
434
435 pub fn with_primary(mut self, color: (u8, u8, u8)) -> Self {
437 self.primary = Some(color);
438 self
439 }
440
441 pub fn set_geom(mut self, el: ElementGeom) -> Self {
443 self.geom = el;
444 self
445 }
446
447 pub fn with_ink_paper(mut self, ink: (u8, u8, u8), paper: (u8, u8, u8)) -> Self {
450 self.geom.ink = Some(ink);
451 self.geom.paper = Some(paper);
452 self
453 }
454
455 pub fn resolve_inheritance(&mut self) {
461 let root = self.text.clone();
462 let def = ElementText::default();
463 let children: [&mut ElementText; 10] = [
464 &mut self.title,
465 &mut self.subtitle,
466 &mut self.caption,
467 &mut self.axis_text_x,
468 &mut self.axis_text_y,
469 &mut self.axis_title_x,
470 &mut self.axis_title_y,
471 &mut self.legend_title,
472 &mut self.legend_text,
473 &mut self.strip_text,
474 ];
475 for el in children {
476 if el.family == def.family {
477 el.family = root.family.clone();
478 }
479 if el.color == def.color {
480 el.color = root.color;
481 }
482 }
483 }
484
485 pub fn get_axis_line_x(&self) -> &ElementLine {
488 self.axis_line_x.as_ref().unwrap_or(&self.axis_line)
489 }
490
491 pub fn get_axis_line_y(&self) -> &ElementLine {
492 self.axis_line_y.as_ref().unwrap_or(&self.axis_line)
493 }
494
495 pub fn get_axis_ticks_x(&self) -> &ElementLine {
496 self.axis_ticks_x.as_ref().unwrap_or(&self.axis_ticks)
497 }
498
499 pub fn get_axis_ticks_y(&self) -> &ElementLine {
500 self.axis_ticks_y.as_ref().unwrap_or(&self.axis_ticks)
501 }
502
503 pub fn axis_line_at(&self, side: AxisSide) -> &ElementLine {
506 let own = match side {
507 AxisSide::Top => &self.axis_line_x_top,
508 AxisSide::Bottom => &self.axis_line_x_bottom,
509 AxisSide::Left => &self.axis_line_y_left,
510 AxisSide::Right => &self.axis_line_y_right,
511 };
512 own.as_ref().unwrap_or(match side {
513 AxisSide::Top | AxisSide::Bottom => self.get_axis_line_x(),
514 AxisSide::Left | AxisSide::Right => self.get_axis_line_y(),
515 })
516 }
517
518 pub fn axis_ticks_at(&self, side: AxisSide) -> &ElementLine {
521 let own = match side {
522 AxisSide::Top => &self.axis_ticks_x_top,
523 AxisSide::Bottom => &self.axis_ticks_x_bottom,
524 AxisSide::Left => &self.axis_ticks_y_left,
525 AxisSide::Right => &self.axis_ticks_y_right,
526 };
527 own.as_ref().unwrap_or(match side {
528 AxisSide::Top | AxisSide::Bottom => self.get_axis_ticks_x(),
529 AxisSide::Left | AxisSide::Right => self.get_axis_ticks_y(),
530 })
531 }
532
533 pub fn get_panel_grid_major_x(&self) -> &ElementLine {
534 self.panel_grid_major_x
535 .as_ref()
536 .unwrap_or(&self.panel_grid_major)
537 }
538
539 pub fn get_panel_grid_major_y(&self) -> &ElementLine {
540 self.panel_grid_major_y
541 .as_ref()
542 .unwrap_or(&self.panel_grid_major)
543 }
544
545 pub fn get_panel_grid_minor_x(&self) -> &ElementLine {
546 self.panel_grid_minor_x
547 .as_ref()
548 .unwrap_or(&self.panel_grid_minor)
549 }
550
551 pub fn get_panel_grid_minor_y(&self) -> &ElementLine {
552 self.panel_grid_minor_y
553 .as_ref()
554 .unwrap_or(&self.panel_grid_minor)
555 }
556
557 pub fn get_panel_spacing_x(&self) -> f64 {
558 self.panel_spacing_x.unwrap_or(self.panel_spacing)
559 }
560
561 pub fn get_panel_spacing_y(&self) -> f64 {
562 self.panel_spacing_y.unwrap_or(self.panel_spacing)
563 }
564
565 pub fn set_axis_text_x(mut self, el: ElementText) -> Self {
568 self.axis_text_x = el;
569 self
570 }
571
572 pub fn set_axis_text_y(mut self, el: ElementText) -> Self {
573 self.axis_text_y = el;
574 self
575 }
576
577 pub fn set_axis_title_x(mut self, el: ElementText) -> Self {
578 self.axis_title_x = el;
579 self
580 }
581
582 pub fn set_axis_title_y(mut self, el: ElementText) -> Self {
583 self.axis_title_y = el;
584 self
585 }
586
587 pub fn set_axis_line(mut self, el: ElementLine) -> Self {
588 self.axis_line = el;
589 self
590 }
591
592 pub fn set_axis_ticks(mut self, el: ElementLine) -> Self {
593 self.axis_ticks = el;
594 self
595 }
596
597 pub fn set_panel_background(mut self, el: ElementRect) -> Self {
598 self.panel_background = el;
599 self
600 }
601
602 pub fn set_panel_grid_major(mut self, el: ElementLine) -> Self {
603 self.panel_grid_major = el;
604 self
605 }
606
607 pub fn set_panel_grid_minor(mut self, el: ElementLine) -> Self {
608 self.panel_grid_minor = el;
609 self
610 }
611
612 pub fn set_plot_background(mut self, el: ElementRect) -> Self {
613 self.plot_background = el;
614 self
615 }
616
617 pub fn set_legend_position(mut self, pos: LegendPosition) -> Self {
618 self.legend_position = pos;
619 self
620 }
621
622 pub fn set_plot_margin(mut self, margin: Margin) -> Self {
623 self.plot_margin = margin;
624 self
625 }
626
627 pub fn set_title(mut self, el: ElementText) -> Self {
628 self.title = el;
629 self
630 }
631
632 pub fn set_text(mut self, el: ElementText) -> Self {
633 self.text = el;
634 self
635 }
636
637 pub fn set_subtitle(mut self, el: ElementText) -> Self {
640 self.subtitle = el;
641 self
642 }
643
644 pub fn set_caption(mut self, el: ElementText) -> Self {
645 self.caption = el;
646 self
647 }
648
649 pub fn set_legend_title(mut self, el: ElementText) -> Self {
650 self.legend_title = el;
651 self
652 }
653
654 pub fn set_legend_text(mut self, el: ElementText) -> Self {
655 self.legend_text = el;
656 self
657 }
658
659 pub fn set_strip_text(mut self, el: ElementText) -> Self {
660 self.strip_text = el;
661 self
662 }
663
664 pub fn set_axis_line_x(mut self, el: Option<ElementLine>) -> Self {
665 self.axis_line_x = el;
666 self
667 }
668
669 pub fn set_axis_line_y(mut self, el: Option<ElementLine>) -> Self {
670 self.axis_line_y = el;
671 self
672 }
673
674 pub fn set_axis_ticks_x(mut self, el: Option<ElementLine>) -> Self {
675 self.axis_ticks_x = el;
676 self
677 }
678
679 pub fn set_axis_ticks_y(mut self, el: Option<ElementLine>) -> Self {
680 self.axis_ticks_y = el;
681 self
682 }
683
684 pub fn set_panel_grid_major_x(mut self, el: Option<ElementLine>) -> Self {
685 self.panel_grid_major_x = el;
686 self
687 }
688
689 pub fn set_panel_grid_major_y(mut self, el: Option<ElementLine>) -> Self {
690 self.panel_grid_major_y = el;
691 self
692 }
693
694 pub fn set_panel_grid_minor_x(mut self, el: Option<ElementLine>) -> Self {
695 self.panel_grid_minor_x = el;
696 self
697 }
698
699 pub fn set_panel_grid_minor_y(mut self, el: Option<ElementLine>) -> Self {
700 self.panel_grid_minor_y = el;
701 self
702 }
703
704 pub fn set_panel_border(mut self, el: ElementLine) -> Self {
705 self.panel_border = el;
706 self
707 }
708
709 pub fn legend_bar_border_line(&self) -> ElementLine {
712 self.legend_bar_border.clone().unwrap_or(ElementLine {
713 color: self.legend_key.color.unwrap_or((50, 50, 50)),
714 width: 0.5,
715 visible: true,
716 linetype: crate::render::backend::Linetype::Solid,
717 })
718 }
719
720 pub fn set_calendar_month_border(mut self, el: ElementLine) -> Self {
721 self.calendar_month_border = el;
722 self
723 }
724
725 pub fn set_legend_bar_border(mut self, el: Option<ElementLine>) -> Self {
726 self.legend_bar_border = el;
727 self
728 }
729
730 pub fn set_legend_background(mut self, el: ElementRect) -> Self {
731 self.legend_background = el;
732 self
733 }
734
735 pub fn set_legend_key(mut self, el: ElementRect) -> Self {
736 self.legend_key = el;
737 self
738 }
739
740 pub fn set_strip_background(mut self, el: ElementRect) -> Self {
741 self.strip_background = el;
742 self
743 }
744
745 pub fn set_axis_ticks_length(mut self, val: f64) -> Self {
746 self.axis_ticks_length = val;
747 self
748 }
749
750 pub fn set_legend_key_width(mut self, val: f64) -> Self {
751 self.legend_key_width = val;
752 self
753 }
754
755 pub fn set_legend_key_height(mut self, val: f64) -> Self {
756 self.legend_key_height = val;
757 self
758 }
759
760 pub fn set_legend_spacing(mut self, val: f64) -> Self {
761 self.legend_spacing = val;
762 self
763 }
764
765 pub fn set_legend_margin(mut self, margin: Margin) -> Self {
766 self.legend_margin = margin;
767 self
768 }
769
770 pub fn set_panel_spacing(mut self, val: f64) -> Self {
771 self.panel_spacing = val;
772 self
773 }
774
775 pub fn set_panel_spacing_x(mut self, val: Option<f64>) -> Self {
776 self.panel_spacing_x = val;
777 self
778 }
779
780 pub fn set_panel_spacing_y(mut self, val: Option<f64>) -> Self {
781 self.panel_spacing_y = val;
782 self
783 }
784
785 pub fn update(mut self, upd: ThemeUpdate) -> Self {
788 if let Some(v) = upd.text {
789 self.text = v;
790 }
791 if let Some(v) = upd.title {
792 self.title = v;
793 }
794 if let Some(v) = upd.subtitle {
795 self.subtitle = v;
796 }
797 if let Some(v) = upd.caption {
798 self.caption = v;
799 }
800 if let Some(v) = upd.axis_text_x {
801 self.axis_text_x = v;
802 }
803 if let Some(v) = upd.axis_text_y {
804 self.axis_text_y = v;
805 }
806 if let Some(v) = upd.axis_title_x {
807 self.axis_title_x = v;
808 }
809 if let Some(v) = upd.axis_title_y {
810 self.axis_title_y = v;
811 }
812 if let Some(v) = upd.axis_line {
813 self.axis_line = v;
814 }
815 if let Some(v) = upd.axis_ticks {
816 self.axis_ticks = v;
817 }
818 if let Some(v) = upd.panel_background {
819 self.panel_background = v;
820 }
821 if let Some(v) = upd.panel_grid_major {
822 self.panel_grid_major = v;
823 }
824 if let Some(v) = upd.panel_grid_minor {
825 self.panel_grid_minor = v;
826 }
827 if let Some(v) = upd.panel_border {
828 self.panel_border = v;
829 }
830 if let Some(v) = upd.calendar_month_border {
831 self.calendar_month_border = v;
832 }
833 if let Some(v) = upd.legend_bar_border {
834 self.legend_bar_border = Some(v);
835 }
836 if let Some(v) = upd.plot_background {
837 self.plot_background = v;
838 }
839 if let Some(v) = upd.legend_position {
840 self.legend_position = v;
841 }
842 if let Some(v) = upd.legend_title {
843 self.legend_title = v;
844 }
845 if let Some(v) = upd.legend_text {
846 self.legend_text = v;
847 }
848 if let Some(v) = upd.legend_background {
849 self.legend_background = v;
850 }
851 if let Some(v) = upd.strip_text {
852 self.strip_text = v;
853 }
854 if let Some(v) = upd.strip_background {
855 self.strip_background = v;
856 }
857 if let Some(v) = upd.plot_margin {
858 self.plot_margin = v;
859 }
860 if let Some(v) = upd.geom {
861 self.geom = v;
862 }
863 for (v, slot) in [
864 (upd.axis_line_x, &mut self.axis_line_x),
865 (upd.axis_line_y, &mut self.axis_line_y),
866 (upd.axis_ticks_x, &mut self.axis_ticks_x),
867 (upd.axis_ticks_y, &mut self.axis_ticks_y),
868 ] {
869 if v.is_some() {
870 *slot = v;
871 }
872 }
873 self
874 }
875}
876
877#[derive(Clone, Debug, Default)]
880pub struct ThemeUpdate {
881 pub text: Option<ElementText>,
882 pub title: Option<ElementText>,
883 pub subtitle: Option<ElementText>,
884 pub caption: Option<ElementText>,
885 pub axis_text_x: Option<ElementText>,
886 pub axis_text_y: Option<ElementText>,
887 pub axis_title_x: Option<ElementText>,
888 pub axis_title_y: Option<ElementText>,
889 pub axis_line: Option<ElementLine>,
890 pub axis_ticks: Option<ElementLine>,
891 pub axis_line_x: Option<ElementLine>,
893 pub axis_line_y: Option<ElementLine>,
894 pub axis_ticks_x: Option<ElementLine>,
895 pub axis_ticks_y: Option<ElementLine>,
896 pub panel_background: Option<ElementRect>,
897 pub panel_grid_major: Option<ElementLine>,
898 pub panel_grid_minor: Option<ElementLine>,
899 pub panel_border: Option<ElementLine>,
900 pub calendar_month_border: Option<ElementLine>,
901 pub legend_bar_border: Option<ElementLine>,
902 pub plot_background: Option<ElementRect>,
903 pub legend_position: Option<LegendPosition>,
904 pub legend_title: Option<ElementText>,
905 pub legend_text: Option<ElementText>,
906 pub legend_background: Option<ElementRect>,
907 pub strip_text: Option<ElementText>,
908 pub strip_background: Option<ElementRect>,
909 pub plot_margin: Option<Margin>,
910 pub geom: Option<ElementGeom>,
912}
913
914impl Default for Theme {
915 fn default() -> Self {
916 presets::theme_gray()
917 }
918}
919
920pub fn theme_sub_axis_x(
923 text: Option<ElementText>,
924 title: Option<ElementText>,
925 line: Option<ElementLine>,
926 ticks: Option<ElementLine>,
927) -> ThemeUpdate {
928 ThemeUpdate {
929 axis_text_x: text,
930 axis_title_x: title,
931 axis_line_x: line,
932 axis_ticks_x: ticks,
933 ..Default::default()
934 }
935}
936
937pub fn theme_sub_axis_y(
939 text: Option<ElementText>,
940 title: Option<ElementText>,
941 line: Option<ElementLine>,
942 ticks: Option<ElementLine>,
943) -> ThemeUpdate {
944 ThemeUpdate {
945 axis_text_y: text,
946 axis_title_y: title,
947 axis_line_y: line,
948 axis_ticks_y: ticks,
949 ..Default::default()
950 }
951}
952
953pub fn theme_sub_legend(
956 title: Option<ElementText>,
957 text: Option<ElementText>,
958 background: Option<ElementRect>,
959 position: Option<LegendPosition>,
960) -> ThemeUpdate {
961 ThemeUpdate {
962 legend_title: title,
963 legend_text: text,
964 legend_background: background,
965 legend_position: position,
966 ..Default::default()
967 }
968}
969
970pub fn theme_sub_panel(
973 background: Option<ElementRect>,
974 border: Option<ElementLine>,
975 grid_major: Option<ElementLine>,
976 grid_minor: Option<ElementLine>,
977) -> ThemeUpdate {
978 ThemeUpdate {
979 panel_background: background,
980 panel_border: border,
981 panel_grid_major: grid_major,
982 panel_grid_minor: grid_minor,
983 ..Default::default()
984 }
985}
986
987pub fn theme_sub_strip(text: Option<ElementText>, background: Option<ElementRect>) -> ThemeUpdate {
989 ThemeUpdate {
990 strip_text: text,
991 strip_background: background,
992 ..Default::default()
993 }
994}
995
996pub fn theme_sub_plot(
999 title: Option<ElementText>,
1000 subtitle: Option<ElementText>,
1001 caption: Option<ElementText>,
1002 background: Option<ElementRect>,
1003 margin: Option<Margin>,
1004) -> ThemeUpdate {
1005 ThemeUpdate {
1006 title,
1007 subtitle,
1008 caption,
1009 plot_background: background,
1010 plot_margin: margin,
1011 ..Default::default()
1012 }
1013}