()
| 22 | } |
| 23 | |
| 24 | fn new() -> PlotWidget { |
| 25 | let cols = 40; |
| 26 | let rows = 30; |
| 27 | let mut positions = Vec::with_capacity(cols * rows); |
| 28 | let mut values = Vec::with_capacity(cols * rows); |
| 29 | |
| 30 | for y in 0..rows { |
| 31 | for x in 0..cols { |
| 32 | let nx = x as f64 / (cols - 1) as f64; |
| 33 | let ny = y as f64 / (rows - 1) as f64; |
| 34 | let value = heat_value(nx, ny); |
| 35 | positions.push([x as f64, y as f64]); |
| 36 | values.push(value); |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | let (min_value, max_value) = values.iter().fold((f64::MAX, f64::MIN), |acc, v| { |
| 41 | (acc.0.min(*v), acc.1.max(*v)) |
| 42 | }); |
| 43 | let span = (max_value - min_value).max(1e-12); |
| 44 | let colors = values |
| 45 | .iter() |
| 46 | .map(|v| heat_color((v - min_value) / span)) |
| 47 | .collect::<Vec<Color>>(); |
| 48 | |
| 49 | let heatmap = Series::markers_only(positions, MarkerStyle::new_world(0.9, MarkerType::Square)) |
| 50 | .with_label("heatmap") |
| 51 | .with_point_colors(colors); |
| 52 | |
| 53 | PlotWidgetBuilder::new() |
| 54 | .add_series(heatmap) |
| 55 | .with_x_label("X") |
| 56 | .with_y_label("Y") |
| 57 | .with_tick_label_size(12.0) |
| 58 | .with_axis_label_size(18.0) |
| 59 | .with_data_aspect(1.0) // keep the pixels square |
| 60 | .with_hover_highlight_provider(move |_ctx, point| { |
| 61 | // point.mask_padding = Some(1.0); |
| 62 | let nx = point.x / (cols - 1) as f64; |
| 63 | let ny = point.y / (rows - 1) as f64; |
| 64 | let value = heat_value(nx, ny); |
| 65 | Some(format!( |
| 66 | "cell: ({:.0}, {:.0})\nvalue: {:.3}", |
| 67 | point.x, point.y, value |
| 68 | )) |
| 69 | }) |
| 70 | .with_cursor_overlay(true) |
| 71 | .build() |
| 72 | .unwrap() |
| 73 | } |
| 74 | |
| 75 | fn heat_value(nx: f64, ny: f64) -> f64 { |
| 76 | let gx = (nx - 0.35) / 0.18; |
nothing calls this directly
no test coverage detected