140e29ae6894cc8d55bb231e73e7a16f7e51a146 braney Wed Aug 5 14:20:32 2026 -0700 Docent: keep a print render's tooltips and track heights in proportion Two things stayed 1x in a 3x still. hgTracks takes the tooltip's font-size from the browser text size, which a scaled run has already multiplied by k for the image, and then the device pixel ratio scales that same text a second time -- so the popups came out k times too big, swamping the figure, and the last tooltip pinned fell off the crop. Pin the tooltip font-size back to the 1x value. The other is height. Neither pix nor textSize reaches a track whose height is a fixed pixel count, so a 128px bigLolly row that was 15% of an 850px image was 5% of a 2550px one -- ClinVar's lollipop row came out a sliver with unreadable y-axis labels next to a bed track that had grown with the font. After each view change, ask for k times the height of every row the page actually drew. Going by the drawn names is what reaches a lifted view, whose tracks are hub tracks under names trackDb never saw. Each track's own maxHeightPixels still clamps the request, so a track that should stay short does. refs #37892 Co-Authored-By: Claude Opus 5 (1M context) diff --git src/hg/utils/docent/README.md src/hg/utils/docent/README.md index ddf8043147b..948201abe1c 100644 --- src/hg/utils/docent/README.md +++ src/hg/utils/docent/README.md @@ -78,30 +78,44 @@ DOCENT_SCALE=3 DOCENT_STILLS=stills.hires DOCENT_FAST=1 node docent.js BP1.docent.yaml ``` What k does: - **deviceScaleFactor: k**, with the viewport left at its 1x CSS size. The page lays out exactly as at 1x — same line breaks, same jQuery-dialog width, same tooltip placement — and all of it rasterizes with k times the pixels. - **`pix` × k, `textSize` stepped up with it** (hgTracks' size ladder: 6, 8, 10, 12, 14, 18, 24, 34; 3x lands exactly on 24). The server draws a genuinely wider image, and the bigger font keeps its layout decisions proportional — tick spacing, room for labels, how features pack into rows. A wider image with an 8px font would be a different picture, not a bigger one. - **`zoom: 1/k` on the image table**, handing that wider image the 1x amount of layout space, so one image pixel lands on one device pixel. Native resolution, no resampling. +- **The tooltip font is pinned back to its 1x size.** hgTracks takes the tooltip's + font-size from the browser text size (`window.browserTextSize` → `hg/js/utils.js` + `addMouseover`), which `textSize × k` has just tripled — and then the device pixel ratio + scales the same text a second time. Left alone, a 3x still gets tooltips 3x too big: the + popups swamp the figure and the last one pinned falls off the crop. +- **Every drawn row asks for k times its height** (`.heightPer`, sent after each view + change for the rows the page actually drew). A track with a FIXED PIXEL height does not + follow `pix` or `textSize` — a bigLolly or wiggle row is a pixel count from trackDb/the + cart — so a 128px row that was 15% of an 850px image would be 5% of a 2550px one. That is + how ClinVar's lollipop row came out a sliver with unreadable y-axis labels. It is asked of + the **drawn** row names, which is the only way to reach a **lifted/quickLift view**, whose + tracks are hub tracks under names trackDb never saw. Each track's own `maxHeightPixels` + still clamps the request, so **a fixed-height track needs a ceiling in trackDb to grow**: + without one the default (128) is also the maximum and the request is silently clamped. Everything hgTracks reports about the image — map-box coords, mouseOver spans, `insideX` — is in the pixels the server drew, so it goes through the image's natural-to-displayed ratio before it becomes a page coordinate. That is why a `mouseover: {item: ...}` lands on the same feature at 3x as at 1x. Two things to expect: - **No mp4.** A scaled run is a figure run; build the video from an unscaled run of the same script. - **Densely packed tracks come out shorter.** hgTracks' font metrics are not perfectly linear across the size ladder, so a 24px font is a little narrower than three 8px ones and `pack` fits the same features into fewer rows. Same window, same tracks, same items, slightly roomier picture.