Skip to content

Make timings graphs scalable to user's window #15766

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions src/cargo/core/compiler/timings.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,42 @@ let UNIT_COORDS = {};
let REVERSE_UNIT_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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the 0.75 from?

Regardless, feel good, and we can always tweak if people find a better default. Thank you for the PR!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is an arbitrary constant, to fit ~75% of the screen 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured that. Anyway, I feel 75% is pretty balanced and eye-friendly.


// Colors from css
const getCssColor = name => getComputedStyle(document.body).getPropertyValue(name);
const TEXT_COLOR = getCssColor('--text');
Expand Down Expand Up @@ -318,11 +354,7 @@ function setup_canvas(id, width, height) {

function draw_graph_axes(id, graph_height) {
const scale = document.getElementById('scale').valueAsNumber;
// 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.
const graph_width = Math.min(scale * DURATION, 4096);
const graph_width = scale_to_graph_width(scale);
const px_per_sec = graph_width / DURATION;
const canvas_width = Math.max(graph_width + X_LINE + 30, X_LINE + 250);
const canvas_height = graph_height + MARGIN + Y_LINE;
Expand Down
11 changes: 9 additions & 2 deletions src/cargo/core/compiler/timings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,11 +776,18 @@ static HTML_CANVAS: &str = r#"
<table class="input-table">
<tr>
<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>
<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>
<td><output for="min-unit-time" id="min-unit-time-output"></output></td>
Expand Down