mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Make timings graphs scalable to user's window (#15766)
### What does this PR try to resolve? This PR changes the way the charts produced by `cargo build --timings` scale. It changes the scale slider so that its min/max values adapt to the duration of the build, to allow zooming in/out even for very short build durations. It also automatically initializes the scale value based on the client's window width. The number of pixels per second per scale value has been changed from 1 to 8, to avoid having too many scale values for the given duration of supported chart widths, which I have determined in this PR to be `[200, 4096]` pixels. https://github.com/user-attachments/assets/3e6e9f14-eabe-425a-a568-9fcb5c835145 ### How to test and review this PR? Run `cargo build --timings` e.g. on https://github.com/BurntSushi/ripgrep. Then open the resulting page in a browser, and try to enlarge/ensmall the window (possibly using mobile emulation), and see how the charts react to window size. Fixes: https://github.com/rust-lang/cargo/issues/15666
This commit is contained in:
commit
1d5d0ba023
@ -23,6 +23,42 @@ let UNIT_COORDS = {};
|
|||||||
let REVERSE_UNIT_DEPS = {};
|
let REVERSE_UNIT_DEPS = {};
|
||||||
let REVERSE_UNIT_RMETA_DEPS = {};
|
let REVERSE_UNIT_RMETA_DEPS = {};
|
||||||
|
|
||||||
|
const MIN_GRAPH_WIDTH = 200;
|
||||||
|
const MAX_GRAPH_WIDTH = 4096;
|
||||||
|
|
||||||
|
// How many pixels per second is added by each scale value
|
||||||
|
const SCALE_PIXELS_PER_SEC = 8;
|
||||||
|
|
||||||
|
function scale_to_graph_width(scale) {
|
||||||
|
// The scale corresponds to `SCALE_PIXELS_PER_SEC` pixels per seconds.
|
||||||
|
// We thus multiply it by that, and the total duration, to get the graph width.
|
||||||
|
const width = scale * SCALE_PIXELS_PER_SEC * DURATION;
|
||||||
|
|
||||||
|
// We then cap the size of the graph. It is hard to view if it is too large, and
|
||||||
|
// browsers may not render a large graph because it takes too much memory.
|
||||||
|
// 4096 is still ridiculously large, and probably won't render on mobile
|
||||||
|
// browsers, but should be ok for many desktop environments.
|
||||||
|
// Also use a minimum width of 200.
|
||||||
|
return Math.max(MIN_GRAPH_WIDTH, Math.min(MAX_GRAPH_WIDTH, width));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function performs the reverse of `scale_to_graph_width`.
|
||||||
|
function width_to_graph_scale(width) {
|
||||||
|
const maxWidth = Math.min(MAX_GRAPH_WIDTH, width);
|
||||||
|
const minWidth = Math.max(MIN_GRAPH_WIDTH, width);
|
||||||
|
|
||||||
|
const trimmedWidth = Math.max(minWidth, Math.min(maxWidth, width));
|
||||||
|
|
||||||
|
const scale = Math.round(trimmedWidth / (DURATION * SCALE_PIXELS_PER_SEC));
|
||||||
|
return Math.max(1, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init scale value and limits based on the client's window width and min/max graph width.
|
||||||
|
const scaleElement = document.getElementById('scale');
|
||||||
|
scaleElement.min = width_to_graph_scale(MIN_GRAPH_WIDTH);
|
||||||
|
scaleElement.max = width_to_graph_scale(MAX_GRAPH_WIDTH);
|
||||||
|
scaleElement.value = width_to_graph_scale(window.innerWidth * 0.75);
|
||||||
|
|
||||||
// Colors from css
|
// Colors from css
|
||||||
const getCssColor = name => getComputedStyle(document.body).getPropertyValue(name);
|
const getCssColor = name => getComputedStyle(document.body).getPropertyValue(name);
|
||||||
const TEXT_COLOR = getCssColor('--text');
|
const TEXT_COLOR = getCssColor('--text');
|
||||||
@ -318,11 +354,7 @@ function setup_canvas(id, width, height) {
|
|||||||
|
|
||||||
function draw_graph_axes(id, graph_height) {
|
function draw_graph_axes(id, graph_height) {
|
||||||
const scale = document.getElementById('scale').valueAsNumber;
|
const scale = document.getElementById('scale').valueAsNumber;
|
||||||
// Cap the size of the graph. It is hard to view if it is too large, and
|
const graph_width = scale_to_graph_width(scale);
|
||||||
// browsers may not render a large graph because it takes too much memory.
|
|
||||||
// 4096 is still ridiculously large, and probably won't render on mobile
|
|
||||||
// browsers, but should be ok for many desktop environments.
|
|
||||||
const graph_width = Math.min(scale * DURATION, 4096);
|
|
||||||
const px_per_sec = graph_width / DURATION;
|
const px_per_sec = graph_width / DURATION;
|
||||||
const canvas_width = Math.max(graph_width + X_LINE + 30, X_LINE + 250);
|
const canvas_width = Math.max(graph_width + X_LINE + 30, X_LINE + 250);
|
||||||
const canvas_height = graph_height + MARGIN + Y_LINE;
|
const canvas_height = graph_height + MARGIN + Y_LINE;
|
||||||
|
@ -776,11 +776,18 @@ static HTML_CANVAS: &str = r#"
|
|||||||
<table class="input-table">
|
<table class="input-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for="min-unit-time">Min unit time:</label></td>
|
<td><label for="min-unit-time">Min unit time:</label></td>
|
||||||
<td><label for="scale">Scale:</label></td>
|
<td title="Scale corresponds to a number of pixels per second. It is automatically initialized based on your viewport width.">
|
||||||
|
<label for="scale">Scale:</label>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input type="range" min="0" max="30" step="0.1" value="0" id="min-unit-time"></td>
|
<td><input type="range" min="0" max="30" step="0.1" value="0" id="min-unit-time"></td>
|
||||||
<td><input type="range" min="1" max="50" value="20" id="scale"></td>
|
<!--
|
||||||
|
The scale corresponds to some number of "pixels per second".
|
||||||
|
Its min, max, and initial values are automatically set by JavaScript on page load,
|
||||||
|
based on the client viewport.
|
||||||
|
-->
|
||||||
|
<td><input type="range" min="1" max="100" value="50" id="scale"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><output for="min-unit-time" id="min-unit-time-output"></output></td>
|
<td><output for="min-unit-time" id="min-unit-time-output"></output></td>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user