babf25e13ff2e01e1f2a3c295f7b84420d3de421 braney Thu Aug 6 10:07:35 2026 -0700 Docent: say which height the print scaling actually scales, refs #37892 The k*128 a scaled run asks for is the default heightPer times k, not each track's own height times k, so a row deliberately configured at 50px or 300px comes back the same size as everything else instead of in proportion. Every track a tour has used took the default, so this has not bitten, and fixing it properly means reading each row's heightPer out of the cart before asking for k times it. Write down the assumption and what the symptom looks like -- a row that is the wrong size at k and the right size at 1x -- so the next person to hit it knows where to look rather than rediscovering the constant. diff --git src/hg/utils/docent/docent.js src/hg/utils/docent/docent.js index 2c83e02ae75..e3b1bb7d803 100755 --- src/hg/utils/docent/docent.js +++ src/hg/utils/docent/docent.js @@ -107,30 +107,36 @@ Math.abs(b - 8 * SCALE) < Math.abs(a - 8 * SCALE) ? b : a); // What every hgTracks nav carries: the image width, plus the font to draw it with at scale. const IMGVARS = `pix=${PIX}` + (SCALE > 1 ? `&textSize=${TEXTSIZE}` : ''); // The tooltip's font-size, forced back to what a 1x run gives it (see SCALE_INIT). hgTracks // takes it from the browser text size, which is TEXTSIZE on a scaled run, and then the device // pixel ratio scales it a second time. const SCALE_ARGS = { k: SCALE, tipPx: Math.round(TEXTSIZE / SCALE) }; // `pix` makes the image k times WIDER; nothing makes a fixed-height track taller. A bigLolly // or wiggle row is a pixel count (`DEFAULT_HEIGHT_PER` = 128 in hg/inc/wiggle.h), read from // trackDb/the cart and untouched by `pix` or `textSize` -- so a 128px row that was 15% of an // 850px image is 5% of a 2550px one, which is how the ClinVar lollipop row came out a sliver // with unreadable y-axis labels. A print run therefore asks for k times the height of every // track a `track:` step turns on. It is harmless where it means nothing (a bigBed never reads // heightPer) and each track's own `maxHeightPixels` still clamps it, so a track that should // stay short does -- raise that ceiling in trackDb for one that should not. +// The k*128 is the DEFAULT height scaled, not each track's own: a row configured at 50px or +// 300px gets k*128 too, which is proportional only for the tracks that took the default. That +// covers every track a tour has used so far, and going further would mean reading each row's +// heightPer out of the cart before asking for k times it. If a tour ever wants a figure of a +// deliberately short or tall row, that is the fix -- the symptom is a row that comes back the +// wrong size in a scaled still and the right size at 1x. const HEIGHTPER = SCALE > 1 ? Math.round(128 * SCALE) : 0; // FAST: iterate on the FIGURES. Everything that exists only for the video is dropped -- // the dwells, the cursor animation, the dropdown theatrics, the screen recording and the // mp4 transcode. The stills are byte-for-byte what a full run produces, and a run costs // roughly a third as long. `fast: true` in the script, DOCENT_FAST=1, or `make FAST=1 BP1`. // A scaled run is a figure run: at 3x the video would be a 3000px-wide recording of a tour // nobody watches at that size, so the mp4 is skipped and only the stills are produced. Build // the video from an unscaled run of the same script. const FAST = !!(doc.fast || process.env.DOCENT_FAST || SCALE > 1); const PACE = FAST ? 0 : Math.round((doc.pace ?? 1.2) * 1000); // dwell after each step const SHOTHOLD = FAST ? 0 : Math.round((doc.shotHold ?? 2.2) * 1000); // extra pause at a shot // ---------- trackDb ---------- // Docent carries NO table of per-track cart variables. Such a table encodes one snapshot // of trackDb and then quietly lies when trackDb changes (this file used to pin