fix: size the timeline diagram to its container, not the window - #45
Merged
Conversation
Mermaid's gantt renderer takes its width from the parent of the element it
renders into, and mermaid.render() with no container renders into a throwaway
element on <body>. The diagram therefore sized itself to the whole window, and
`.nd-timeline__diagram svg { max-width: 100% }` scaled that down into the content
column -- so the wider the window, the smaller the result.
Material caps its content column at roughly 750px, so on the published docs this
shrank by about 2.5x at a typical desktop width: readable on a phone, unreadably
tiny on a monitor. Verified against the published site, where the same page is
legible at an 800px window and microscopic at 1900px.
Pass the container's measured width as gantt `useWidth`, which the renderer
prefers over the parent's, so the SVG is drawn at the size it is displayed and
nothing is scaled. Redraw on resize (debounced, bound once per page) since the
diagram is now sized rather than stretched.
Verified in a browser in the real Material layout at 1900px, before and after.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sizing the gantt to its container fixed the wide-window case but not the narrow one: squeezed into a phone-width column it overlaps its own task names and axis ticks, which is readable in neither direction. Draw at the greater of the container's width and a 720px floor, and pin that width onto the rendered SVG -- mermaid emits width="100%" with a max-width, which would otherwise shrink it straight back into the column. The container already had overflow-x, so below the floor it now scrolls at a readable size instead of scaling the labels away. Verified in a browser on the real page: at a 420px window the diagram stays legible and scrolls; at 1900px it fills the content column as before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Timeline diagrams render at a fraction of their intended size on the published docs. Straight from Mermaid's gantt renderer:
mermaid.render(id, src)with no container renders into a throwaway element on<body>, so the gantt sizes itself to the whole window. Our.nd-timeline__diagram svg { max-width: 100% }then scales that down into the content column. The wider the window, the smaller the diagram.Material caps its content column at ~750px, so on a typical desktop this is about a 2.5× shrink — which is why it looks fine on a phone and unreadable on a monitor. Measured on the live site: the same page is legible at an 800px window and microscopic at 1900px.
The fix — part 1: size to the container
Pass the container's measured width as gantt
useWidth, which the renderer prefers over the parent's. The SVG is then drawn at the size it is displayed, somax-widthhas nothing to scale and text lands at its intended size at any window width.Because the diagram is now sized rather than stretched, a resize has to redraw — added a debounced
resizehandler, bound once per page rather than once per block.The fix — part 2: never below a legible width
Fitting the container is not the same as being readable. At a 420px window the diagram fit its column perfectly and was still unusable: task names overlapped their bars and the axis ticks ran together.
So the width is now
max(container, 720px), and that width is pinned onto the rendered SVG — Mermaid emitswidth="100%"plus amax-width, which would otherwise shrink it straight back into the column..nd-timeline__diagramalready hadoverflow-x: auto, so below the floor the diagram keeps its readable size and scrolls rather than scaling its labels into nothing. The exact-date table underneath is unaffected and stays fully readable at any width.Type of change
Checklist
dotnet format Netdocs.slnx --verify-no-changespassesdotnet build Netdocs.slnx -c Releasesucceedsdotnet test Netdocs.slnx -c Releasepasses (510, +3 new)docs-site/docs/**— new "Diagram size" section on the timeline pageVerification
Browser, on the real page, at both ends of the range:
I also confirmed this is not environment-specific before fixing it: prod and dev pages are byte-identical apart from asset URLs, and the self-hosted Mermaid module produces exactly the same
viewBox 0 0 984 244as the CDN one. The variable was window width all along.Notes for reviewers
The two new tests assert on the emitted JavaScript source, not its behaviour — the sizing happens in the client evaluator, which nothing in
dotnet testexecutes. They pin the contract; the browser check above is the real evidence. This is the same coverage gap I flagged on #43, and it just cost us a round trip: one existingEvaluatorJs_*test broke purely because I changed the text of a call it string-matched, with no behaviour change at all. I retargeted it at the intent (the diagram still receives the unsorted events) rather than the literal call.Once merged, the docs site needs a rebuild for the published diagrams to pick this up.
🤖 Generated with Claude Code