mirror of
https://github.com/a-b-street/abstreet.git
synced 2025-01-02 03:18:55 +03:00
one last pass for polishing all layers. layout and text tweaks
This commit is contained in:
parent
d2c674eb9a
commit
0dddd1d6c1
@ -276,7 +276,7 @@ impl<'a> ColorNetwork<'a> {
|
||||
.push(color.alpha(0.4), self.map.get_pl(pl).polygon.clone());
|
||||
}
|
||||
|
||||
pub fn road_percentiles(&mut self, counter: Counter<RoadID>, scale: &ColorScale) {
|
||||
pub fn ranked_roads(&mut self, counter: Counter<RoadID>, scale: &ColorScale) {
|
||||
let roads = counter.sorted_asc();
|
||||
let len = roads.len() as f64;
|
||||
for (idx, list) in roads.into_iter().enumerate() {
|
||||
@ -286,11 +286,7 @@ impl<'a> ColorNetwork<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn intersection_percentiles(
|
||||
&mut self,
|
||||
counter: Counter<IntersectionID>,
|
||||
scale: &ColorScale,
|
||||
) {
|
||||
pub fn ranked_intersections(&mut self, counter: Counter<IntersectionID>, scale: &ColorScale) {
|
||||
let intersections = counter.sorted_asc();
|
||||
let len = intersections.len() as f64;
|
||||
for (idx, list) in intersections.into_iter().enumerate() {
|
||||
|
@ -3,7 +3,7 @@ use crate::common::{ColorLegend, ColorNetwork};
|
||||
use crate::layer::{Layer, LayerOutcome};
|
||||
use ezgui::{
|
||||
hotkey, Btn, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Key,
|
||||
TextExt, VerticalAlignment, Widget,
|
||||
Line, Text, TextExt, VerticalAlignment, Widget,
|
||||
};
|
||||
use geom::{ArrowCap, Distance, PolyLine};
|
||||
|
||||
@ -102,7 +102,11 @@ impl Elevation {
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
format!("Steepest road: {:.0}%", max * 100.0).draw_text(ctx),
|
||||
Text::from_multiline(vec![
|
||||
Line(format!("Steepest road: {:.0}% grade", max * 100.0)),
|
||||
Line("Note: elevation data is currently wrong!").secondary(),
|
||||
])
|
||||
.draw(ctx),
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_red, vec!["flat", "steep"]),
|
||||
])
|
||||
.padding(5)
|
||||
|
@ -108,14 +108,25 @@ impl BikeNetwork {
|
||||
]),
|
||||
Text::from_multiline(vec![
|
||||
Line(format!("{} lanes", num_lanes)),
|
||||
Line(format!("total distance of {}", total_dist)),
|
||||
Line(format!(
|
||||
"total distance of {}",
|
||||
total_dist.describe_rounded()
|
||||
)),
|
||||
])
|
||||
.draw(ctx)
|
||||
.margin_below(10),
|
||||
Line("Throughput on bike lanes").draw(ctx),
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_green, vec!["0%ile", "100%ile"]),
|
||||
ColorLegend::gradient(
|
||||
ctx,
|
||||
&app.cs.good_to_bad_green,
|
||||
vec!["lowest count", "highest"],
|
||||
),
|
||||
Line("Throughput on unprotected roads").draw(ctx),
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_red, vec!["0%ile", "100%ile"]),
|
||||
ColorLegend::gradient(
|
||||
ctx,
|
||||
&app.cs.good_to_bad_red,
|
||||
vec!["lowest count", "highest"],
|
||||
),
|
||||
])
|
||||
.padding(5)
|
||||
.bg(app.cs.panel_bg),
|
||||
@ -124,10 +135,10 @@ impl BikeNetwork {
|
||||
.build(ctx);
|
||||
|
||||
let mut colorer = ColorNetwork::new(app);
|
||||
colorer.road_percentiles(on_bike_lanes, &app.cs.good_to_bad_green);
|
||||
colorer.road_percentiles(off_bike_lanes, &app.cs.good_to_bad_red);
|
||||
colorer.intersection_percentiles(intersections_on, &app.cs.good_to_bad_green);
|
||||
colorer.intersection_percentiles(intersections_off, &app.cs.good_to_bad_red);
|
||||
colorer.ranked_roads(on_bike_lanes, &app.cs.good_to_bad_green);
|
||||
colorer.ranked_roads(off_bike_lanes, &app.cs.good_to_bad_red);
|
||||
colorer.ranked_intersections(intersections_on, &app.cs.good_to_bad_green);
|
||||
colorer.ranked_intersections(intersections_off, &app.cs.good_to_bad_red);
|
||||
let (unzoomed, zoomed) = colorer.build(ctx);
|
||||
|
||||
BikeNetwork {
|
||||
|
@ -174,31 +174,31 @@ impl Occupancy {
|
||||
100.0 * (has_car as f64) / (total_ppl as f64)
|
||||
}
|
||||
)),
|
||||
Line(""),
|
||||
Line(format!(
|
||||
"{} public spots filled",
|
||||
prettyprint_usize(filled_spots.len())
|
||||
"{} / {} public spots filled",
|
||||
prettyprint_usize(filled_spots.len()),
|
||||
prettyprint_usize(filled_spots.len() + avail_spots.len())
|
||||
)),
|
||||
Line(format!(
|
||||
"{} public spots available ",
|
||||
prettyprint_usize(avail_spots.len())
|
||||
)),
|
||||
Line(""),
|
||||
Line(format!(
|
||||
"{} private spots filled",
|
||||
prettyprint_usize(filled_private_spots)
|
||||
)),
|
||||
Line(format!(
|
||||
"{} private spots available ",
|
||||
prettyprint_usize(avail_private_spots)
|
||||
"{} / {} private spots filled",
|
||||
prettyprint_usize(filled_private_spots),
|
||||
prettyprint_usize(filled_private_spots + avail_private_spots)
|
||||
)),
|
||||
])
|
||||
.draw(ctx)
|
||||
.margin_below(10),
|
||||
Checkbox::text(ctx, "On-street spots", None, onstreet).margin_below(5),
|
||||
Checkbox::text(ctx, "Public garages", None, garages).margin_below(5),
|
||||
Checkbox::text(ctx, "Parking lots", None, lots).margin_below(10),
|
||||
Checkbox::text(ctx, "Private buildings", None, private_bldgs).margin_below(10),
|
||||
Widget::row(vec![
|
||||
Checkbox::text(ctx, "On-street spots", None, onstreet).margin_right(15),
|
||||
Checkbox::text(ctx, "Parking lots", None, lots),
|
||||
])
|
||||
.evenly_spaced()
|
||||
.margin_below(10),
|
||||
Widget::row(vec![
|
||||
Checkbox::text(ctx, "Public garages", None, garages).margin_right(15),
|
||||
Checkbox::text(ctx, "Private buildings", None, private_bldgs),
|
||||
])
|
||||
.evenly_spaced()
|
||||
.margin_below(10),
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_red, vec!["0%", "100%"]),
|
||||
])
|
||||
.padding(5)
|
||||
|
@ -4,7 +4,7 @@ use crate::layer::{Layer, LayerOutcome};
|
||||
use abstutil::Counter;
|
||||
use ezgui::{
|
||||
hotkey, Btn, Checkbox, Color, Composite, Drawable, EventCtx, GeomBatch, GfxCtx,
|
||||
HorizontalAlignment, Key, Outcome, TextExt, VerticalAlignment, Widget,
|
||||
HorizontalAlignment, Key, Line, Outcome, Text, TextExt, VerticalAlignment, Widget,
|
||||
};
|
||||
use geom::{Distance, Duration, Polygon, Time};
|
||||
use map_model::{IntersectionID, Map, Traversable};
|
||||
@ -74,8 +74,17 @@ impl Backpressure {
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
// TODO Explain
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_red, vec!["0%ile", "100%ile"]),
|
||||
Text::from(
|
||||
Line("This counts all active trips passing through a road in the future")
|
||||
.secondary(),
|
||||
)
|
||||
.wrap_to_pct(ctx, 15)
|
||||
.draw(ctx),
|
||||
ColorLegend::gradient(
|
||||
ctx,
|
||||
&app.cs.good_to_bad_red,
|
||||
vec!["lowest count", "highest"],
|
||||
),
|
||||
])
|
||||
.padding(5)
|
||||
.bg(app.cs.panel_bg),
|
||||
@ -84,8 +93,8 @@ impl Backpressure {
|
||||
.build(ctx);
|
||||
|
||||
let mut colorer = ColorNetwork::new(app);
|
||||
colorer.road_percentiles(cnt_per_r, &app.cs.good_to_bad_red);
|
||||
colorer.intersection_percentiles(cnt_per_i, &app.cs.good_to_bad_red);
|
||||
colorer.ranked_roads(cnt_per_r, &app.cs.good_to_bad_red);
|
||||
colorer.ranked_intersections(cnt_per_i, &app.cs.good_to_bad_red);
|
||||
let (unzoomed, zoomed) = colorer.build(ctx);
|
||||
|
||||
Backpressure {
|
||||
@ -167,13 +176,19 @@ impl Throughput {
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
// TODO Explain. What roads see the most movement?
|
||||
Text::from(Line("This counts all people crossing since midnight").secondary())
|
||||
.wrap_to_pct(ctx, 15)
|
||||
.draw(ctx),
|
||||
if app.has_prebaked().is_some() {
|
||||
Checkbox::text(ctx, "Compare before edits", None, false).margin_below(5)
|
||||
} else {
|
||||
Widget::nothing()
|
||||
},
|
||||
ColorLegend::gradient(ctx, &app.cs.good_to_bad_red, vec!["0%ile", "100%ile"]),
|
||||
ColorLegend::gradient(
|
||||
ctx,
|
||||
&app.cs.good_to_bad_red,
|
||||
vec!["lowest count", "highest"],
|
||||
),
|
||||
])
|
||||
.padding(5)
|
||||
.bg(app.cs.panel_bg),
|
||||
@ -183,11 +198,11 @@ impl Throughput {
|
||||
|
||||
let mut colorer = ColorNetwork::new(app);
|
||||
let stats = &app.primary.sim.get_analytics();
|
||||
colorer.road_percentiles(
|
||||
colorer.ranked_roads(
|
||||
stats.road_thruput.all_total_counts(),
|
||||
&app.cs.good_to_bad_red,
|
||||
);
|
||||
colorer.intersection_percentiles(
|
||||
colorer.ranked_intersections(
|
||||
stats.intersection_thruput.all_total_counts(),
|
||||
&app.cs.good_to_bad_red,
|
||||
);
|
||||
@ -256,13 +271,13 @@ impl Throughput {
|
||||
Widget::row(vec![
|
||||
Widget::draw_svg(ctx, "../data/system/assets/tools/layers.svg")
|
||||
.margin_right(10),
|
||||
"Throughput (percent change)".draw_text(ctx),
|
||||
"Relative Throughput".draw_text(ctx),
|
||||
Btn::plaintext("X")
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
Checkbox::text(ctx, "Compare before edits", None, true).margin_below(5),
|
||||
scale.make_legend(ctx, vec!["less", "-50%", "0%", "50%", "more"]),
|
||||
scale.make_legend(ctx, vec!["less traffic", "same", "more"]),
|
||||
])
|
||||
.padding(5)
|
||||
.bg(app.cs.panel_bg),
|
||||
@ -503,15 +518,13 @@ impl TrafficJams {
|
||||
);
|
||||
let mut zoomed = GeomBatch::new();
|
||||
let mut cnt = 0;
|
||||
// TODO Maybe look for intersections with delay > 5m, then expand out while roads have
|
||||
// delay of at least 1m?
|
||||
for (epicenter, boundary) in cluster_jams(
|
||||
&app.primary.map,
|
||||
app.primary.sim.delayed_intersections(Duration::minutes(5)),
|
||||
) {
|
||||
cnt += 1;
|
||||
unzoomed.push(Color::RED, boundary.to_outline(Distance::meters(5.0)));
|
||||
unzoomed.push(Color::RED.alpha(0.7), boundary.clone());
|
||||
unzoomed.push(Color::RED.alpha(0.5), boundary.clone());
|
||||
unzoomed.push(Color::WHITE, epicenter.clone());
|
||||
|
||||
zoomed.push(
|
||||
@ -532,6 +545,11 @@ impl TrafficJams {
|
||||
.build(ctx, "close", hotkey(Key::Escape))
|
||||
.align_right(),
|
||||
]),
|
||||
Text::from(
|
||||
Line("A jam starts when delay exceeds 5 mins, then spreads out").secondary(),
|
||||
)
|
||||
.wrap_to_pct(ctx, 15)
|
||||
.draw(ctx),
|
||||
format!("{} jams detected", cnt).draw_text(ctx),
|
||||
])
|
||||
.padding(5)
|
||||
@ -574,12 +592,7 @@ fn cluster_jams(map: &Map, problems: Vec<(IntersectionID, Time)>) -> Vec<(Polygo
|
||||
.map(|jam| {
|
||||
(
|
||||
map.get_i(jam.epicenter).polygon.clone(),
|
||||
Polygon::convex_hull(
|
||||
jam.members
|
||||
.into_iter()
|
||||
.map(|i| map.get_i(i).polygon.clone())
|
||||
.collect(),
|
||||
),
|
||||
Polygon::convex_hull(jam.all_polygons(map)),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
@ -595,4 +608,12 @@ impl Jam {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn all_polygons(self, map: &Map) -> Vec<Polygon> {
|
||||
let mut polygons = Vec::new();
|
||||
for i in self.members {
|
||||
polygons.push(map.get_i(i).polygon.clone());
|
||||
}
|
||||
polygons
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user