| 67 | } |
| 68 | |
| 69 | fn graph(&mut self, ui: &mut egui::Ui) -> egui::Response { |
| 70 | use egui::*; |
| 71 | |
| 72 | ui.label("egui CPU usage history"); |
| 73 | |
| 74 | let history = &self.frame_times; |
| 75 | |
| 76 | // TODO(emilk): we should not use `slider_width` as default graph width. |
| 77 | let height = ui.spacing().slider_width; |
| 78 | let size = vec2(ui.available_size_before_wrap().x, height); |
| 79 | let (rect, response) = ui.allocate_at_least(size, Sense::hover()); |
| 80 | let style = ui.style().noninteractive(); |
| 81 | |
| 82 | let graph_top_cpu_usage = 0.010; |
| 83 | let graph_rect = Rect::from_x_y_ranges(history.max_age()..=0.0, graph_top_cpu_usage..=0.0); |
| 84 | let to_screen = emath::RectTransform::from_to(graph_rect, rect); |
| 85 | |
| 86 | let mut shapes = Vec::with_capacity(3 + 2 * history.len()); |
| 87 | shapes.push(Shape::Rect(epaint::RectShape::new( |
| 88 | rect, |
| 89 | style.corner_radius, |
| 90 | ui.visuals().extreme_bg_color, |
| 91 | ui.style().noninteractive().bg_stroke, |
| 92 | StrokeKind::Inside, |
| 93 | ))); |
| 94 | |
| 95 | let rect = rect.shrink(4.0); |
| 96 | let color = ui.visuals().text_color(); |
| 97 | let line_stroke = Stroke::new(1.0_f32, color); |
| 98 | |
| 99 | if let Some(pointer_pos) = response.hover_pos() { |
| 100 | let y = pointer_pos.y; |
| 101 | shapes.push(Shape::line_segment( |
| 102 | [pos2(rect.left(), y), pos2(rect.right(), y)], |
| 103 | line_stroke, |
| 104 | )); |
| 105 | let cpu_usage = to_screen.inverse().transform_pos(pointer_pos).y; |
| 106 | let text = format!("{:.1} ms", 1e3 * cpu_usage); |
| 107 | shapes.push(ui.fonts_mut(|f| { |
| 108 | Shape::text( |
| 109 | f, |
| 110 | pos2(rect.left(), y), |
| 111 | egui::Align2::LEFT_BOTTOM, |
| 112 | text, |
| 113 | TextStyle::Monospace.resolve(ui.style()), |
| 114 | color, |
| 115 | ) |
| 116 | })); |
| 117 | } |
| 118 | |
| 119 | let circle_color = color; |
| 120 | let radius = 2.0; |
| 121 | let right_side_time = ui.input(|i| i.time); // Time at right side of screen |
| 122 | |
| 123 | for (time, cpu_usage) in history.iter() { |
| 124 | let age = (right_side_time - time) as f32; |
| 125 | let pos = to_screen.transform_pos_clamped(Pos2::new(age, cpu_usage)); |
| 126 | |