making the histogram more clear about same trips

This commit is contained in:
Dustin Carlino 2020-01-30 15:33:27 -08:00
parent da92518d62
commit 800008dc03
5 changed files with 88 additions and 38 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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)
}

View File

@ -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
}),

View File

@ -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(