Skip to main content

charming/component/
toolbox.rs

1use crate::{datatype::CompositeValue, element::Orient};
2use charming_macros::CharmingSetters;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
6#[serde(rename_all = "snake_case")]
7pub enum SaveAsImageType {
8    Png,
9    Jpg,
10    Svg,
11}
12
13#[serde_with::apply(
14  Option => #[serde(skip_serializing_if = "Option::is_none")],
15  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
16)]
17#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct SaveAsImage {
20    show: Option<bool>,
21    #[serde(rename = "type")]
22    type_: Option<SaveAsImageType>,
23    name: Option<String>,
24    background_color: Option<String>,
25}
26
27#[serde_with::apply(
28  Option => #[serde(skip_serializing_if = "Option::is_none")],
29  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
30)]
31#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
32#[serde(rename_all = "camelCase")]
33pub struct Restore {
34    show: Option<bool>,
35    title: Option<String>,
36}
37
38#[serde_with::apply(
39  Option => #[serde(skip_serializing_if = "Option::is_none")],
40  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
41)]
42#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
43#[serde(rename_all = "camelCase")]
44pub struct DataView {
45    show: Option<bool>,
46    title: Option<String>,
47    read_only: Option<bool>,
48}
49
50#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
51#[serde(rename_all = "snake_case")]
52pub enum MagicTypeType {
53    /// For line charts.
54    Line,
55    /// For bar charts.
56    Bar,
57    /// For stacked charts.
58    Stack,
59}
60
61impl From<&str> for MagicTypeType {
62    fn from(s: &str) -> Self {
63        match s {
64            "line" => Self::Line,
65            "bar" => Self::Bar,
66            "stack" => Self::Stack,
67            _ => panic!("Invalid magic type type: {s}"),
68        }
69    }
70}
71
72#[serde_with::apply(
73  Option => #[serde(skip_serializing_if = "Option::is_none")],
74  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
75)]
76#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
77#[serde(rename_all = "camelCase")]
78pub struct MagicType {
79    type_: Option<Vec<MagicTypeType>>,
80    title: Option<String>,
81}
82
83#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
84#[serde(rename_all = "camelCase")]
85pub enum BrushType {
86    Rect,
87    Polygon,
88    LineX,
89    LineY,
90    Keep,
91    Clear,
92}
93
94#[serde_with::apply(
95  Option => #[serde(skip_serializing_if = "Option::is_none")],
96  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
97)]
98#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
99#[serde(rename_all = "camelCase")]
100pub struct Brush {
101    #[serde(rename = "type")]
102    #[charming_set_vec]
103    type_: Vec<BrushType>,
104}
105
106#[serde_with::apply(
107  Option => #[serde(skip_serializing_if = "Option::is_none")],
108  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
109)]
110#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
111#[serde(rename_all = "camelCase")]
112pub struct ToolboxDataZoom {
113    y_axis_index: Option<CompositeValue>,
114}
115
116#[serde_with::apply(
117  Option => #[serde(skip_serializing_if = "Option::is_none")],
118  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
119)]
120#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
121#[serde(rename_all = "camelCase")]
122pub struct Feature {
123    save_as_image: Option<SaveAsImage>,
124    restore: Option<Restore>,
125    data_view: Option<DataView>,
126    magic_type: Option<MagicType>,
127    data_zoom: Option<ToolboxDataZoom>,
128    brush: Option<Brush>,
129}
130
131#[serde_with::apply(
132  Option => #[serde(skip_serializing_if = "Option::is_none")],
133  Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
134)]
135#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
136#[serde(rename_all = "camelCase")]
137pub struct Toolbox {
138    show: Option<bool>,
139    feature: Option<Feature>,
140    orient: Option<Orient>,
141    left: Option<CompositeValue>,
142    top: Option<CompositeValue>,
143    right: Option<CompositeValue>,
144    bottom: Option<CompositeValue>,
145}
146
147impl Toolbox {
148    pub fn save_as_image_type(&self) -> Option<&SaveAsImageType> {
149        self.feature
150            .as_ref()
151            .and_then(|f| f.save_as_image.as_ref())
152            .and_then(|s| s.type_.as_ref())
153    }
154}