Skip to content

Fix rangeslider "fixed" rangemode using placeholder range of autoranged counter axis - #7967

Open
Guhapriya01 wants to merge 4 commits into
plotly:mainfrom
Guhapriya01:fix-rangeslider-fixed-rangemode-placeholder
Open

Fix rangeslider "fixed" rangemode using placeholder range of autoranged counter axis#7967
Guhapriya01 wants to merge 4 commits into
plotly:mainfrom
Guhapriya01:fix-rangeslider-fixed-rangemode-placeholder

Conversation

@Guhapriya01

Copy link
Copy Markdown

Fixes plotly/plotly.py#5614

Problem

With rangeslider.yaxis.rangemode: "fixed" and no explicit range, the slider renders two grey bands on initial load; toggling rangemode away and back clears them. The bands are the opp-axis masks, which shade the slider outside the fixed y-range — visible only when that range disagrees with the data.

image

Cause

rangeslider/defaults.js defaults the fixed range off yAxOut.range. When the counter axis autoranges, that is still the DFLTRANGEY [-1, 4] placeholder at supplyDefaults time. Unlike rangemode: 'auto', nothing revisits it afterwards.
Toggling works only because it forces a second supplyDefaults, by which point the axis holds its computed range.

Fix

Flag a fixed range defaulted off a not-yet-autoranged axis, and let doAutoRange fill it in via the path 'auto' already uses. The flag is deleted once consumed, so fixed resolves once and then stays put, and the internal key is not copied out to layout.

No schema change; auto, match, explicit ranges and non-autoranged axes are unaffected.

@Guhapriya01
Guhapriya01 marked this pull request as ready for review August 16, 2026 09:13
@robertclaus
robertclaus requested a review from emilykl August 17, 2026 19:33

@CAOShurong CAOShurong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Exact-head verification review (diff walked against upstream/main ba10ef79d, PR head 11f79e4f).

Root cause - confirmed

  • src/plots/cartesian/set_convert.js (~L492) falls back to constants.DFLTRANGEY = [-1, 4] when a y axis has no valid range at supply-defaults time.
  • src/components/rangeslider/defaults.js (~L67-72) then defaults the counter-axis rangeslider.yaxis.range off yAxOut.range.slice() for any rangemode !== 'match' - so for fixed on an autoranged counter axis, the slider range starts life as the [-1, 4] placeholder.
  • doAutoRange (src/plots/cartesian/autorange.js ~L401) only refreshes axeRangeOpts.range when rangemode === 'auto', so the stale placeholder survives to draw; the opposite-axis masks then shade everything outside the disagreement between [-1, 4] and the real data band, which is exactly the two grey bands in the screenshots.
  • The toggle behavior also checks out: switching rangemode away and back forces a second supply-defaults pass, by which time the y axis holds its computed range, so the re-coerced fixed range is correct.

Fix assessment

  • Flagging only defaulted-from-placeholder fixed ranges (!rangemodeDflt && yAxOut.autorange) and routing them through the existing 'auto' branch in doAutoRange is a minimal fix with no schema change. Delete-on-consume gives "resolve once, then stays put", which matches the fixed contract: later autorange changes correctly leave the slider alone (covered by the restyle step in the new test).
  • Internal-key hygiene checked: the flag lives on the full-layout container, and by the time anchorAx._input.rangeslider[ax._name] = Lib.extendFlat({}, axeRangeOpts) copies state back toward user input the flag has already been deleted, so nothing leaks into gd.layout. Fresh newPlot calls start from clean containers, so no stale-flag path there either.

Nits (non-blocking)

  1. The new test locks in the numeric behavior but not the internal-key claim from the PR description. Cheap insurance: assert '_rangeDfltFromAutorangedAx' in gd._fullLayout.xaxis.rangeslider.yaxis is false after the first plot (and/or absent from the layout input). That guards against someone later moving the extendFlat copy above the delete.
  2. The reported repro includes the rangemode toggle clearing the bands. A follow-up Plotly.relayout(gd, 'xaxis.rangeslider.yaxis.rangemode', ...) round-trip asserting the slider range stays sane would pin down the second-supply-defaults path this PR deliberately leaves untouched.
  3. Explicit-but-invalid rangeslider.yaxis.range together with fixed: rangemodeDflt stays undefined, so the flag applies and the range resolves once from autorange. I believe that is the right fallback (user asked for fixed with an unusable range), but a line in the draftlog entry would stop future readers from mistaking it for an accident.

CI note: only the Orca security scans have run on this head so far; the jasmine suites are maintainer-gated, so the new test has not executed yet. Mergeable state verified via API at review time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Range slider y-axis "fixed" rangemode renders unexpected thick horizontal bars on initial load

3 participants