use colorous for heatmaps

This commit is contained in:
Dustin Carlino 2020-04-27 18:48:19 -07:00
parent 077035aacb
commit 55c8a9d875
6 changed files with 49 additions and 49 deletions

7
Cargo.lock generated
View File

@ -392,6 +392,11 @@ dependencies = [
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "colorous"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "const-random"
version = "0.1.8"
@ -979,6 +984,7 @@ dependencies = [
"built 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"built 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"colorous 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"downcast-rs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ezgui 0.1.0",
"geom 0.1.0",
@ -3823,6 +3829,7 @@ dependencies = [
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62"
"checksum cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400"
"checksum colorous 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebeb47d6d3334179ee49ef9a1f3a03d177450b25705854d92e2e1d128b49c736"
"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a"
"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a"
"checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5"

View File

@ -129,3 +129,7 @@ perl -pi -e 's/WrappedComposite::text_button\(ctx, (.+?), (.+?)\)/Btn::text_fg(\
## Stack overflow
rust-gdb --args ../target/release/game --dev
## Drawing diagrams
draw.io

View File

@ -470,3 +470,9 @@ impl<T> Choice<T> {
}
}
}
impl Choice<String> {
pub fn string(label: &str) -> Choice<String> {
Choice::new(label.to_string(), label.to_string())
}
}

View File

@ -15,6 +15,7 @@ aabb-quadtree = "0.1.0"
abstutil = { path = "../abstutil" }
built = { version = "0.4.0", optional = true, features=["chrono"] }
chrono = "0.4.10"
colorous = "1.0.1"
downcast-rs = "1.1.1"
ezgui = { path = "../ezgui", default-features=false }
geom = { path = "../geom" }

View File

@ -359,43 +359,3 @@ impl ColorScheme {
cs
}
}
// For now, this won't live in ColorScheme, since the scales are independently chooseable.
#[derive(Clone, Copy, PartialEq)]
pub enum HeatmapColors {
FullSpectral,
SingleHue,
}
impl HeatmapColors {
pub fn choices() -> Vec<Choice<HeatmapColors>> {
vec![
Choice::new("full spectral", HeatmapColors::FullSpectral),
Choice::new("single hue", HeatmapColors::SingleHue),
]
}
// This is in order from low density to high.
pub fn colors(self) -> Vec<Color> {
match self {
HeatmapColors::FullSpectral => vec![
hex("#0b2c7a"),
hex("#1e9094"),
hex("#0ec441"),
hex("#7bed00"),
hex("#f7d707"),
hex("#e68e1c"),
hex("#c2523c"),
],
HeatmapColors::SingleHue => vec![
hex("#FFEBD6"),
hex("#F5CBAE"),
hex("#EBA988"),
hex("#E08465"),
hex("#D65D45"),
hex("#CC3527"),
hex("#C40A0A"),
],
}
}
}

View File

@ -1,6 +1,5 @@
use crate::colors::HeatmapColors;
use crate::common::ColorLegend;
use ezgui::{Checkbox, Color, Composite, EventCtx, GeomBatch, Spinner, TextExt, Widget};
use ezgui::{Checkbox, Choice, Color, Composite, EventCtx, GeomBatch, Spinner, TextExt, Widget};
use geom::{Bounds, Histogram, Polygon, Pt2D};
const NEIGHBORS: [[isize; 2]; 9] = [
@ -21,7 +20,7 @@ pub struct HeatmapOptions {
resolution: usize,
radius: usize,
smoothing: bool,
colors: HeatmapColors,
color_scheme: String,
}
impl HeatmapOptions {
@ -30,7 +29,7 @@ impl HeatmapOptions {
resolution: 10,
radius: 3,
smoothing: true,
colors: HeatmapColors::FullSpectral,
color_scheme: "Turbo".to_string(),
}
}
@ -62,7 +61,15 @@ impl HeatmapOptions {
col.push(Widget::row(vec![
"Color scheme".draw_text(ctx).margin(5),
Widget::dropdown(ctx, "Colors", self.colors, HeatmapColors::choices()),
Widget::dropdown(
ctx,
"Color scheme",
self.color_scheme.clone(),
vec!["Turbo", "Inferno", "Warm", "Cool", "Oranges", "Spectral"]
.into_iter()
.map(|x| Choice::string(x))
.collect(),
),
]));
// Legend for the heatmap colors
@ -82,7 +89,7 @@ impl HeatmapOptions {
resolution: c.spinner("resolution"),
radius: c.spinner("radius"),
smoothing: c.is_checked("smoothing"),
colors: c.dropdown_value("Colors"),
color_scheme: c.dropdown_value("Color scheme"),
}
} else {
HeatmapOptions::new()
@ -97,11 +104,27 @@ pub fn make_heatmap(
pts: Vec<Pt2D>,
opts: &HeatmapOptions,
) -> (Vec<Color>, Vec<String>) {
let colors = opts.colors.colors();
// 7 colors, 8 labels
let num_colors = 7;
let gradient = match opts.color_scheme.as_ref() {
"Turbo" => colorous::TURBO,
"Inferno" => colorous::INFERNO,
"Warm" => colorous::WARM,
"Cool" => colorous::COOL,
"Oranges" => colorous::ORANGES,
"Spectral" => colorous::SPECTRAL,
_ => unreachable!(),
};
let colors: Vec<Color> = (0..num_colors)
.map(|i| {
let c = gradient.eval_rational(i, num_colors);
Color::rgb(c.r as usize, c.g as usize, c.b as usize)
})
.collect();
if pts.is_empty() {
let labels = std::iter::repeat("0".to_string())
.take(colors.len() + 1)
.take(num_colors + 1)
.collect();
return (colors, labels);
}
@ -175,7 +198,6 @@ pub fn make_heatmap(
distrib.add(*count as usize);
}
let num_colors = colors.len();
let max_count_per_bucket: Vec<(f64, Color)> = (1..=num_colors)
.map(|i| {
distrib