oino_ui/widgets/
barchart.rs1use serde::{Deserialize, Serialize};
4
5use crate::layout::Direction;
6use crate::node::{ActionId, Common, IntoNode, Node};
7use crate::style::Style;
8use crate::text::Line;
9
10#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct Bar {
14 pub value: u64,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
18 pub label: Option<Line>,
19 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub text_value: Option<String>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
24 pub style: Option<Style>,
25 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub value_style: Option<Style>,
28}
29
30impl Bar {
31 #[must_use]
33 pub fn new(value: u64) -> Self {
34 Self {
35 value,
36 label: None,
37 text_value: None,
38 style: None,
39 value_style: None,
40 }
41 }
42
43 #[must_use]
45 pub fn label(mut self, label: impl Into<Line>) -> Self {
46 self.label = Some(label.into());
47 self
48 }
49
50 #[must_use]
52 pub fn text_value(mut self, text: impl Into<String>) -> Self {
53 self.text_value = Some(text.into());
54 self
55 }
56
57 #[must_use]
59 pub fn style(mut self, style: Style) -> Self {
60 self.style = Some(style);
61 self
62 }
63
64 #[must_use]
66 pub fn value_style(mut self, style: Style) -> Self {
67 self.value_style = Some(style);
68 self
69 }
70}
71
72#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct BarGroup {
76 #[serde(default, skip_serializing_if = "Option::is_none")]
78 pub label: Option<Line>,
79 pub bars: Vec<Bar>,
81}
82
83impl BarGroup {
84 #[must_use]
86 pub fn new(bars: impl IntoIterator<Item = Bar>) -> Self {
87 Self {
88 label: None,
89 bars: bars.into_iter().collect(),
90 }
91 }
92
93 #[must_use]
95 pub fn label(mut self, label: impl Into<Line>) -> Self {
96 self.label = Some(label.into());
97 self
98 }
99}
100
101#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct BarChart {
105 #[serde(flatten)]
107 pub common: Common,
108 pub data: Vec<BarGroup>,
110 #[serde(default, skip_serializing_if = "Option::is_none")]
112 pub bar_width: Option<u16>,
113 #[serde(default, skip_serializing_if = "Option::is_none")]
115 pub bar_gap: Option<u16>,
116 #[serde(default, skip_serializing_if = "Option::is_none")]
118 pub group_gap: Option<u16>,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub direction: Option<Direction>,
122 #[serde(default, skip_serializing_if = "Option::is_none")]
124 pub max: Option<u64>,
125 #[serde(default, skip_serializing_if = "Option::is_none")]
127 pub bar_style: Option<Style>,
128 #[serde(default, skip_serializing_if = "Option::is_none")]
130 pub value_style: Option<Style>,
131 #[serde(default, skip_serializing_if = "Option::is_none")]
133 pub label_style: Option<Style>,
134 #[serde(default, skip_serializing_if = "Option::is_none")]
136 pub on_select: Option<ActionId>,
137}
138
139impl BarChart {
140 #[must_use]
142 pub fn new(data: impl IntoIterator<Item = BarGroup>) -> Self {
143 Self {
144 data: data.into_iter().collect(),
145 ..Self::default()
146 }
147 }
148
149 #[must_use]
151 pub fn from_pairs(pairs: impl IntoIterator<Item = (impl Into<Line>, u64)>) -> Self {
152 Self::new(vec![BarGroup::new(
153 pairs
154 .into_iter()
155 .map(|(label, value)| Bar::new(value).label(label)),
156 )])
157 }
158
159 #[must_use]
161 pub fn bar_width(mut self, width: u16) -> Self {
162 self.bar_width = Some(width);
163 self
164 }
165
166 #[must_use]
168 pub fn bar_gap(mut self, gap: u16) -> Self {
169 self.bar_gap = Some(gap);
170 self
171 }
172
173 #[must_use]
175 pub fn group_gap(mut self, gap: u16) -> Self {
176 self.group_gap = Some(gap);
177 self
178 }
179
180 #[must_use]
182 pub fn direction(mut self, direction: Direction) -> Self {
183 self.direction = Some(direction);
184 self
185 }
186
187 #[must_use]
189 pub fn max(mut self, max: u64) -> Self {
190 self.max = Some(max);
191 self
192 }
193
194 #[must_use]
196 pub fn bar_style(mut self, style: Style) -> Self {
197 self.bar_style = Some(style);
198 self
199 }
200
201 #[must_use]
203 pub fn value_style(mut self, style: Style) -> Self {
204 self.value_style = Some(style);
205 self
206 }
207
208 #[must_use]
210 pub fn label_style(mut self, style: Style) -> Self {
211 self.label_style = Some(style);
212 self
213 }
214
215 #[must_use]
217 pub fn on_select(mut self, action: impl Into<ActionId>) -> Self {
218 self.on_select = Some(action.into());
219 self
220 }
221}
222
223impl IntoNode for BarChart {}
224impl From<BarChart> for Node {
225 fn from(c: BarChart) -> Self {
226 Node::BarChart(c)
227 }
228}