mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-01 10:44:56 +03:00
display basic labels on trip stats
This commit is contained in:
parent
393eaff249
commit
5f9cf2accd
@ -462,3 +462,23 @@ impl<'a> Prerender<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct MultiText {
|
||||||
|
list: Vec<(Text, ScreenPt)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiText {
|
||||||
|
pub fn new() -> MultiText {
|
||||||
|
MultiText { list: Vec::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, txt: Text, pt: ScreenPt) {
|
||||||
|
self.list.push((txt, pt));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self, g: &mut GfxCtx) {
|
||||||
|
for (txt, pt) in &self.list {
|
||||||
|
g.draw_text_at_screenspace_topleft(txt, *pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ pub mod world;
|
|||||||
|
|
||||||
pub use crate::canvas::{Canvas, HorizontalAlignment, VerticalAlignment, BOTTOM_LEFT, CENTERED};
|
pub use crate::canvas::{Canvas, HorizontalAlignment, VerticalAlignment, BOTTOM_LEFT, CENTERED};
|
||||||
pub use crate::color::Color;
|
pub use crate::color::Color;
|
||||||
pub use crate::drawing::{Drawable, GeomBatch, GfxCtx, Prerender};
|
pub use crate::drawing::{Drawable, GeomBatch, GfxCtx, MultiText, Prerender};
|
||||||
pub use crate::event::{hotkey, lctrl, Event, Key, MultiKey};
|
pub use crate::event::{hotkey, lctrl, Event, Key, MultiKey};
|
||||||
pub use crate::event_ctx::EventCtx;
|
pub use crate::event_ctx::EventCtx;
|
||||||
pub use crate::input::UserInput;
|
pub use crate::input::UserInput;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use crate::common::ColorLegend;
|
use crate::common::ColorLegend;
|
||||||
use crate::game::{State, Transition};
|
use crate::game::{State, Transition};
|
||||||
use crate::ui::UI;
|
use crate::ui::UI;
|
||||||
use ezgui::{hotkey, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, ModalMenu, Text};
|
use ezgui::{
|
||||||
|
ScreenPt, hotkey, Color, Drawable, EventCtx, GeomBatch, GfxCtx, Key, Line, ModalMenu, MultiText, Text,
|
||||||
|
};
|
||||||
use geom::{Distance, Duration, PolyLine, Polygon, Pt2D};
|
use geom::{Distance, Duration, PolyLine, Polygon, Pt2D};
|
||||||
use sim::TripMode;
|
use sim::TripMode;
|
||||||
|
|
||||||
@ -77,6 +79,7 @@ pub struct ShowStats {
|
|||||||
menu: ModalMenu,
|
menu: ModalMenu,
|
||||||
draw: Drawable,
|
draw: Drawable,
|
||||||
legend: ColorLegend,
|
legend: ColorLegend,
|
||||||
|
labels: MultiText,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State for ShowStats {
|
impl State for ShowStats {
|
||||||
@ -95,12 +98,14 @@ impl State for ShowStats {
|
|||||||
g.fork_screenspace();
|
g.fork_screenspace();
|
||||||
g.redraw(&self.draw);
|
g.redraw(&self.draw);
|
||||||
g.unfork();
|
g.unfork();
|
||||||
|
self.labels.draw(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShowStats {
|
impl ShowStats {
|
||||||
pub fn new(stats: &TripStats, ui: &UI, ctx: &mut EventCtx) -> ShowStats {
|
pub fn new(stats: &TripStats, ui: &UI, ctx: &mut EventCtx) -> ShowStats {
|
||||||
let mut batch = GeomBatch::new();
|
let mut batch = GeomBatch::new();
|
||||||
|
let mut labels = MultiText::new();
|
||||||
|
|
||||||
let x1 = 0.2 * ctx.canvas.window_width;
|
let x1 = 0.2 * ctx.canvas.window_width;
|
||||||
let x2 = 0.8 * ctx.canvas.window_width;
|
let x2 = 0.8 * ctx.canvas.window_width;
|
||||||
@ -118,25 +123,29 @@ impl ShowStats {
|
|||||||
let lines: Vec<(&str, Color, Box<dyn Fn(&StateAtTime) -> usize>)> = vec![
|
let lines: Vec<(&str, Color, Box<dyn Fn(&StateAtTime) -> usize>)> = vec![
|
||||||
(
|
(
|
||||||
"walking",
|
"walking",
|
||||||
ui.cs.get("unzoomed pedestrian").alpha(1.0),
|
ui.cs.get("unzoomed pedestrian"),
|
||||||
Box::new(|s| s.finished_walk_trips),
|
Box::new(|s| s.finished_walk_trips),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"biking",
|
"biking",
|
||||||
ui.cs.get("unzoomed bike").alpha(1.0),
|
ui.cs.get("unzoomed bike"),
|
||||||
Box::new(|s| s.finished_bike_trips),
|
Box::new(|s| s.finished_bike_trips),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"transit",
|
"transit",
|
||||||
ui.cs.get("unzoomed bus").alpha(1.0),
|
ui.cs.get("unzoomed bus"),
|
||||||
Box::new(|s| s.finished_transit_trips),
|
Box::new(|s| s.finished_transit_trips),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"driving",
|
"driving",
|
||||||
ui.cs.get("unzoomed car").alpha(1.0),
|
ui.cs.get("unzoomed car"),
|
||||||
Box::new(|s| s.finished_drive_trips),
|
Box::new(|s| s.finished_drive_trips),
|
||||||
),
|
),
|
||||||
("aborted", Color::PURPLE, Box::new(|s| s.aborted_trips)),
|
(
|
||||||
|
"aborted",
|
||||||
|
Color::PURPLE.alpha(0.5),
|
||||||
|
Box::new(|s| s.aborted_trips),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
let legend = ColorLegend::new(
|
let legend = ColorLegend::new(
|
||||||
"finished trips",
|
"finished trips",
|
||||||
@ -145,11 +154,28 @@ impl ShowStats {
|
|||||||
.map(|(name, color, _)| (*name, *color))
|
.map(|(name, color, _)| (*name, *color))
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
let max_y = stats.samples.iter().map(|s|
|
||||||
|
lines.iter().map(|(_, _, getter)| getter(s)).max().unwrap()
|
||||||
|
).max().unwrap();
|
||||||
|
// Y-axis labels
|
||||||
|
for i in 0..=5 {
|
||||||
|
let percent = (i as f64) / 5.0;
|
||||||
|
labels.add(Text::from(Line(((percent * (max_y as f64)) as usize).to_string())), ScreenPt::new(x1, y2 - percent * (y2 - y1)));
|
||||||
|
}
|
||||||
|
// X-axis labels (currently nonlinear!)
|
||||||
|
{
|
||||||
|
let num_pts = stats.samples.len().min(5);
|
||||||
|
for i in 0..num_pts {
|
||||||
|
let percent_x = (i as f64) / ((num_pts - 1) as f64);
|
||||||
|
let t = stats.samples[(percent_x * ((stats.samples.len() - 1) as f64)) as usize].time;
|
||||||
|
labels.add(Text::from(Line(t.to_string())), ScreenPt::new(x1 + percent_x * (x2 - x1), y2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (_, color, getter) in lines {
|
for (_, color, getter) in lines {
|
||||||
if stats.samples.is_empty() {
|
if stats.samples.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let max_y = stats.samples.iter().map(&getter).max().unwrap();
|
|
||||||
let mut pts = Vec::new();
|
let mut pts = Vec::new();
|
||||||
if max_y == 0 {
|
if max_y == 0 {
|
||||||
pts.push(Pt2D::new(x1, y2));
|
pts.push(Pt2D::new(x1, y2));
|
||||||
@ -184,6 +210,7 @@ impl ShowStats {
|
|||||||
menu: ModalMenu::new("Trip Stats", vec![vec![(hotkey(Key::Escape), "quit")]], ctx)
|
menu: ModalMenu::new("Trip Stats", vec![vec![(hotkey(Key::Escape), "quit")]], ctx)
|
||||||
.set_prompt(ctx, txt),
|
.set_prompt(ctx, txt),
|
||||||
draw: ctx.prerender.upload(batch),
|
draw: ctx.prerender.upload(batch),
|
||||||
|
labels,
|
||||||
legend,
|
legend,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user