mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
making the histogram more clear about same trips
This commit is contained in:
parent
da92518d62
commit
800008dc03
@ -6,16 +6,16 @@ a5e849fa8883569519976ebfef3ae269 data/system/night_colors.json
|
||||
a673b8d627cdcb58791d4c1fb9d28574 data/system/maps/caphill.bin
|
||||
d8bbb98f4d4674fbea4d2879829c3756 data/system/maps/montlake.bin
|
||||
a0fb461cefa6ab26082bd0d1a56073be data/system/maps/23rd.bin
|
||||
c1f770d7a77bd009cec2595137321b85 data/system/synthetic_maps/signal_double.json
|
||||
bfdbd18dd24a125d6f42f5b812be583f data/system/synthetic_maps/signal_single.json
|
||||
7707b64b382c09a9635993856be6571c data/system/synthetic_maps/signal_fan_in.json
|
||||
204aaa2615e42d2a4b173141360f41d4 data/system/synthetic_maps/signal_double.json
|
||||
363c7fcb79a9b76a721b54c9eaad9bad data/system/synthetic_maps/signal_single.json
|
||||
c7216021e149874c605d9941bce0d850 data/system/synthetic_maps/signal_fan_in.json
|
||||
170bc2dd2ff2af864bd593e54963b1dc data/system/scenarios/ballard/weekday.bin
|
||||
bfb6c5abe4b9de1f9b254c0c2a5cdf52 data/system/scenarios/23rd/weekday.bin
|
||||
f9f0a109966db097617a13122ecaa6f3 data/system/scenarios/downtown/weekday.bin
|
||||
dd54763cfda7fce4c401ae122c6daf57 data/system/scenarios/huge_seattle/weekday.bin
|
||||
47dea892a1c4331da02494d15ce02a02 data/system/scenarios/caphill/weekday.bin
|
||||
7d6a8e8f5d716ce8674ed63d27f2da51 data/system/scenarios/montlake/weekday.bin
|
||||
692ce00b68b552eb05921dcf9d978a53 data/system/prebaked_results/23rd/weekday.bin
|
||||
9b03eee27c1a20f941848360ff4e6425 data/system/prebaked_results/signal_single/tutorial lvl1.bin
|
||||
fd451f62137814d9c91f38cc2e2bea62 data/system/prebaked_results/signal_single/tutorial lvl2.bin
|
||||
ffaca90577fa26563bc3dcca09842ed5 data/system/prebaked_results/montlake/weekday.bin
|
||||
8bf8ddb00479aa0dea08bfa3eeb0978b data/system/prebaked_results/23rd/weekday.bin
|
||||
1cca5ea035284433ddf0ba357df919ce data/system/prebaked_results/signal_single/tutorial lvl1.bin
|
||||
bff631e1d02bc82d5e5ab8d58c71f186 data/system/prebaked_results/signal_single/tutorial lvl2.bin
|
||||
12b02b6543d44a5e5b6f73295034a743 data/system/prebaked_results/montlake/weekday.bin
|
||||
|
@ -817,7 +817,8 @@ impl Composite {
|
||||
}
|
||||
|
||||
pub fn align_above(&mut self, ctx: &mut EventCtx, other: &Composite) {
|
||||
self.vert = VerticalAlignment::TopAt(other.top_level.rect.y1);
|
||||
// Small padding
|
||||
self.vert = VerticalAlignment::TopAt(other.top_level.rect.y1 - 5.0);
|
||||
self.recompute_layout(ctx);
|
||||
}
|
||||
}
|
||||
|
@ -24,37 +24,16 @@ impl Histogram {
|
||||
let width = 0.25 * ctx.canvas.window_width;
|
||||
let height = 0.3 * ctx.canvas.window_height;
|
||||
|
||||
// TODO Generic "bucket into 10 groups, give (min, max, count)"
|
||||
let min_x = unsorted_dts.iter().min().cloned().unwrap_or(Duration::ZERO);
|
||||
let max_x = unsorted_dts.iter().max().cloned().unwrap_or(Duration::ZERO);
|
||||
|
||||
let num_buckets = 10;
|
||||
let bucket_size = (max_x - min_x) / (num_buckets as f64);
|
||||
// lower, upper, count
|
||||
let mut bars: Vec<(Duration, Duration, usize)> = (0..num_buckets)
|
||||
.map(|idx| {
|
||||
let i = idx as f64;
|
||||
(min_x + bucket_size * i, min_x + bucket_size * (i + 1.0), 0)
|
||||
})
|
||||
.collect();
|
||||
for dt in unsorted_dts {
|
||||
// TODO Could sort them and do this more efficiently.
|
||||
if dt == max_x {
|
||||
// Most bars represent [low, high) except the last
|
||||
bars[num_buckets - 1].2 += 1;
|
||||
} else {
|
||||
let bin = ((dt - min_x) / bucket_size).floor() as usize;
|
||||
bars[bin].2 += 1;
|
||||
}
|
||||
}
|
||||
let (min_x, max_x, bars) = bucketize(unsorted_dts, num_buckets);
|
||||
|
||||
let min_y = 0;
|
||||
let max_y = bars.iter().map(|(_, _, cnt)| *cnt).max().unwrap();
|
||||
let mut outlines = Vec::new();
|
||||
for (idx, (min, max, cnt)) in bars.into_iter().enumerate() {
|
||||
let color = if max < Duration::ZERO {
|
||||
let color = if min < Duration::ZERO {
|
||||
Color::RED
|
||||
} else if min < Duration::ZERO {
|
||||
} else if min == Duration::ZERO && max == Duration::ZERO {
|
||||
Color::YELLOW
|
||||
} else {
|
||||
Color::GREEN
|
||||
@ -156,3 +135,62 @@ impl Widget for Histogram {
|
||||
self.top_left = top_left;
|
||||
}
|
||||
}
|
||||
|
||||
// min, max, bars
|
||||
// TODO This has bugs. Perfect surface area to unit test.
|
||||
fn bucketize(
|
||||
unsorted_dts: Vec<Duration>,
|
||||
num_buckets: usize,
|
||||
) -> (Duration, Duration, Vec<(Duration, Duration, usize)>) {
|
||||
assert!(num_buckets >= 3);
|
||||
if unsorted_dts.is_empty() {
|
||||
return (
|
||||
Duration::ZERO,
|
||||
Duration::ZERO,
|
||||
vec![(Duration::ZERO, Duration::ZERO, 0)],
|
||||
);
|
||||
}
|
||||
|
||||
let min_x = *unsorted_dts.iter().min().unwrap();
|
||||
let max_x = *unsorted_dts.iter().max().unwrap();
|
||||
|
||||
let bucket_size = (max_x - min_x) / ((num_buckets - 3) as f64);
|
||||
// lower, upper, count
|
||||
let mut bars: Vec<(Duration, Duration, usize)> = Vec::new();
|
||||
let mut min = min_x;
|
||||
while min < max_x {
|
||||
let max = min + bucket_size;
|
||||
if min < Duration::ZERO && max > Duration::ZERO {
|
||||
bars.push((min, Duration::ZERO, 0));
|
||||
bars.push((Duration::ZERO, Duration::ZERO, 0));
|
||||
bars.push((Duration::ZERO, max, 0));
|
||||
} else {
|
||||
bars.push((min, max, 0));
|
||||
}
|
||||
|
||||
min = max;
|
||||
}
|
||||
if bars.is_empty() {
|
||||
assert_eq!(min, max_x);
|
||||
bars.push((Duration::ZERO, Duration::ZERO, 0));
|
||||
} else {
|
||||
//assert_eq!(bars.len(), num_buckets);
|
||||
}
|
||||
|
||||
for dt in unsorted_dts {
|
||||
// TODO Could sort them and do this more efficiently.
|
||||
let mut ok = false;
|
||||
for (min, max, count) in bars.iter_mut() {
|
||||
if (dt >= *min && dt < *max) || (*min == *max && dt == *min) {
|
||||
*count += 1;
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Most bars represent [low, high) except the last and the [0, 0] one
|
||||
if !ok {
|
||||
bars.last_mut().unwrap().2 += 1;
|
||||
}
|
||||
}
|
||||
(min_x, max_x, bars)
|
||||
}
|
||||
|
@ -542,8 +542,10 @@ impl Overlays {
|
||||
ManagedWidget::draw_text(ctx, {
|
||||
let mut txt = Text::from(Line("Are finished trips "));
|
||||
txt.append(Line("faster").fg(Color::GREEN));
|
||||
txt.append(Line(" or "));
|
||||
txt.append(Line(", "));
|
||||
txt.append(Line("slower").fg(Color::RED));
|
||||
txt.append(Line(", or "));
|
||||
txt.append(Line("the same").fg(Color::YELLOW));
|
||||
txt.append(Line("?"));
|
||||
txt
|
||||
}),
|
||||
|
@ -74,7 +74,7 @@ fn make_top_center(ctx: &mut EventCtx, ui: &UI, mode: GameplayMode) -> WrappedCo
|
||||
.get_analytics()
|
||||
.all_finished_trips(ui.primary.sim.time());
|
||||
let (baseline, _, _) = ui.prebaked().all_finished_trips(ui.primary.sim.time());
|
||||
txt.add(Line("Average trip time: "));
|
||||
txt.add(Line("Average trip time: ").size(20));
|
||||
if now.count() > 0 && baseline.count() > 0 {
|
||||
txt.append_all(cmp_duration_shorter(
|
||||
now.select(Statistic::Mean),
|
||||
@ -91,10 +91,19 @@ fn make_top_center(ctx: &mut EventCtx, ui: &UI, mode: GameplayMode) -> WrappedCo
|
||||
vec![
|
||||
ManagedWidget::row(vec![
|
||||
ManagedWidget::draw_text(ctx, txt).margin(5),
|
||||
WrappedComposite::text_button(ctx, "details", None).margin(5),
|
||||
])
|
||||
.centered(),
|
||||
ManagedWidget::draw_text(ctx, Text::from(Line(format!("Goal: {} faster", GOAL)))),
|
||||
WrappedComposite::nice_text_button(
|
||||
ctx,
|
||||
Text::from(Line("details").size(20)),
|
||||
None,
|
||||
"details",
|
||||
)
|
||||
.align_right(),
|
||||
]),
|
||||
ManagedWidget::draw_text(
|
||||
ctx,
|
||||
Text::from(Line(format!("Goal: {} faster", GOAL)).size(20)),
|
||||
)
|
||||
.margin(5),
|
||||
],
|
||||
)
|
||||
.cb(
|
||||
|
Loading…
Reference in New Issue
Block a user