Skip to content

Commit c8af8ab

Browse files
committed
bar chart
1 parent 6144063 commit c8af8ab

File tree

2 files changed

+236
-227
lines changed

2 files changed

+236
-227
lines changed

src/bar_chart.rs

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
use bevy::prelude::*;
2+
3+
use crate::{Delta, TapDeltas};
4+
5+
pub const BINS: usize = 16;
6+
const BAR_HEIGHT_MULTIPLIER: f32 = 4000.0;
7+
8+
pub struct BarChartPlugin;
9+
impl Plugin for BarChartPlugin {
10+
fn build(&self, app: &mut App) {
11+
app.insert_resource(HideBarChart(false))
12+
.add_systems(Startup, setup)
13+
.add_systems(Update, (update_bins, hide_bar_chart));
14+
}
15+
}
16+
17+
#[derive(Component)]
18+
struct BarChart;
19+
#[derive(Resource)]
20+
pub struct HideBarChart(pub bool);
21+
#[derive(Component)]
22+
struct BinIndex(usize);
23+
24+
#[derive(Component)]
25+
struct BinBar;
26+
27+
fn setup(mut commands: Commands) {
28+
commands
29+
.spawn((
30+
BarChart,
31+
Visibility::Visible,
32+
Node {
33+
width: Val::Percent(100.0),
34+
height: Val::Percent(100.0),
35+
justify_self: JustifySelf::Center,
36+
justify_content: JustifyContent::Center,
37+
align_items: AlignItems::Center,
38+
..default()
39+
},
40+
))
41+
.with_children(|commands| {
42+
commands
43+
.spawn(Node {
44+
display: Display::Flex,
45+
justify_self: JustifySelf::Center,
46+
flex_direction: FlexDirection::Row,
47+
width: Val::Percent(80.0),
48+
height: Val::Percent(100.0),
49+
..Default::default()
50+
})
51+
.with_children(|commands| {
52+
for (f, height, label) in [
53+
(0.0, 4.0, "0"),
54+
(1.0, 3.0, "1/60"),
55+
(1.5, 2.0, "1.5/60"),
56+
(2.0, 1.0, "2/60"),
57+
] {
58+
commands.spawn((
59+
Node {
60+
position_type: PositionType::Absolute,
61+
width: Val::Percent(100.0),
62+
height: Val::Px(f / 60.0 * BAR_HEIGHT_MULTIPLIER + height / 2.0),
63+
bottom: Val::Percent(50.0),
64+
border: UiRect {
65+
top: Val::Px(height),
66+
..default()
67+
},
68+
..default()
69+
},
70+
BorderColor(Color::BLACK),
71+
));
72+
commands.spawn((
73+
Node {
74+
position_type: PositionType::Absolute,
75+
width: Val::Percent(100.0),
76+
height: Val::Px(f / 60.0 * BAR_HEIGHT_MULTIPLIER + height / 2.0),
77+
top: Val::Percent(50.0),
78+
border: UiRect {
79+
bottom: Val::Px(height),
80+
..default()
81+
},
82+
..default()
83+
},
84+
BorderColor(Color::BLACK),
85+
));
86+
87+
commands
88+
.spawn((
89+
Node {
90+
position_type: PositionType::Absolute,
91+
left: Val::Px(-12.0),
92+
height: Val::Px(f / 60.0 * BAR_HEIGHT_MULTIPLIER),
93+
width: Val::Percent(100.0),
94+
bottom: Val::Percent(50.0),
95+
..default()
96+
},
97+
// BackgroundColor(Color::linear_rgba(0.0, 1.0, 0.0, 0.3)),
98+
))
99+
.with_children(|commands| {
100+
commands.spawn((
101+
Node {
102+
position_type: PositionType::Absolute,
103+
right: Val::Percent(100.0),
104+
bottom: Val::Percent(100.0),
105+
..default()
106+
},
107+
Text::new(label),
108+
TextFont {
109+
font_size: 10.3,
110+
..Default::default()
111+
},
112+
));
113+
});
114+
}
115+
116+
for i in 0..BINS {
117+
commands
118+
.spawn(Node {
119+
margin: UiRect {
120+
left: Val::Px(4.0),
121+
right: Val::Px(4.0),
122+
..default()
123+
},
124+
flex_grow: 1.0,
125+
flex_basis: Val::Px(0.0),
126+
justify_content: JustifyContent::Center,
127+
justify_self: JustifySelf::Center,
128+
align_items: AlignItems::Center,
129+
..default()
130+
})
131+
.with_children(|commands| {
132+
commands
133+
.spawn((
134+
Node {
135+
width: Val::Percent(100.0),
136+
height: Val::Percent(100.0),
137+
justify_content: JustifyContent::Center,
138+
justify_self: JustifySelf::Center,
139+
align_items: AlignItems::Center,
140+
..default()
141+
},
142+
// BackgroundColor(Color::linear_rgba(0.0, 1.0, 0.0, 0.3)),
143+
))
144+
.with_children(|commands| {
145+
commands.spawn((
146+
BinBar,
147+
BinIndex(i),
148+
Visibility::Inherited,
149+
Node {
150+
position_type: PositionType::Absolute,
151+
width: Val::Percent(100.0),
152+
height: Val::Px(100.0),
153+
top: Val::Percent(50.0),
154+
bottom: Val::DEFAULT,
155+
justify_content: JustifyContent::Center,
156+
align_items: AlignItems::Center,
157+
..default()
158+
},
159+
BackgroundColor(Color::linear_rgb(0.0, 0.0, 1.0)),
160+
));
161+
commands.spawn((
162+
BinIndex(i),
163+
Text::new("1.23"),
164+
TextFont {
165+
font_size: 10.3,
166+
..Default::default()
167+
},
168+
));
169+
});
170+
});
171+
}
172+
});
173+
});
174+
}
175+
176+
fn update_bins(
177+
mut query_bar: Query<
178+
(&BinIndex, &mut Node, &mut BackgroundColor, &mut Visibility),
179+
With<BinBar>,
180+
>,
181+
mut query_text: Query<(&BinIndex, &mut Text)>,
182+
tap_deltas: Res<TapDeltas>,
183+
) {
184+
if tap_deltas.is_changed() {
185+
for (BinIndex(index), mut node, mut color, mut visibility) in &mut query_bar {
186+
if let Some(Delta { delta, .. }) = tap_deltas.0.get(*index) {
187+
let height = delta.abs() as f32 * BAR_HEIGHT_MULTIPLIER;
188+
node.height = Val::Px(height);
189+
node.position_type = PositionType::Absolute;
190+
191+
if *delta >= 0.0 {
192+
color.0 = Color::linear_rgba(1.0, 0.0, 0.0, 0.6);
193+
node.top = Val::DEFAULT;
194+
node.bottom = Val::Percent(50.0);
195+
} else {
196+
color.0 = Color::linear_rgba(0.0, 0.0, 1.0, 0.6);
197+
node.bottom = Val::DEFAULT;
198+
node.top = Val::Percent(50.0);
199+
}
200+
201+
*visibility = Visibility::Inherited;
202+
} else {
203+
*visibility = Visibility::Hidden;
204+
}
205+
}
206+
207+
for (BinIndex(index), mut text) in &mut query_text {
208+
if let Some(Delta {
209+
delta, division, ..
210+
}) = tap_deltas.0.get(*index)
211+
{
212+
text.0 = format!("[{}]{:+.1}", division, delta * 1000.0);
213+
} else {
214+
text.0 = "".to_string();
215+
}
216+
}
217+
}
218+
}
219+
220+
fn hide_bar_chart(
221+
mut bar_chart: Query<&mut Visibility, With<BarChart>>,
222+
hide_bar_chart: Res<HideBarChart>,
223+
) {
224+
if hide_bar_chart.is_changed() {
225+
for mut visibility in &mut bar_chart {
226+
if hide_bar_chart.0 {
227+
*visibility = Visibility::Hidden;
228+
} else {
229+
*visibility = Visibility::Visible;
230+
}
231+
}
232+
}
233+
}

0 commit comments

Comments
 (0)