LiveChart normally fits its Y-axis to the visible data. Pass a SharedValue<number> through
yRangeScale to multiply that fitted range around its midpoint: 1 keeps auto-fit, values above
1 show more vertical range, and values between 0 and 1 zoom in.
Live example:
app/demo/y-range-scale.tsx
includes line/candle/multi-series toggles, preset buttons, a draggable price gutter, and
double-tap reset. Turn on Zero floor and choose 8× to see how a
nonNegative chart stops its zoom-out at 0.Drag the price gutter to stretch or compress the fitted Y-range
priceScalePan on your own axis-gutter view with GestureDetector. Keeping that gesture
outside the chart lets you choose its hit area and compose it with the rest of your screen.
Behavior
- The multiplier is applied after the normal margin and minimum-range fit, so auto-fit continues tracking the visible data while scaled.
- On
LiveChartSeries, the multiplier applies to the shared range after hidden series are excluded. - While the SharedValue changes, the displayed range tracks it without frame-lag. Once it stops,
ordinary range changes use
smoothingor the optionalrangeAnimationoverrides. - Reset with an animation such as
withTiming(1)for the same smooth result whether the current scale is above or below1. - On a
nonNegativechart, zoom-out stops when the lower bound reaches0. The upper bound does not keep growing after the floor is reached, so the values remain centered instead of being pinned to the bottom of the plot. maxValueis applied after scaling, so that hard ceiling still wins.- Values must be positive and finite. Invalid values safely behave as
1; clamp gesture output to a product-appropriate range as shown above.
yRangeScale changes the value range only. It composes with timeScroll and zoom,
which control the visible time window.
Animating automatic range changes
By default, both charts snap outward bounds immediately and ease inward bounds withsmoothing.
Opt into outward easing with rangeAnimation={{ animateExpansion: true }}. This also applies
when a reference line enters the fit, without changing recorded values or moving the time window.
For separate speeds, use the exported RangeAnimationConfig:
smoothing. It also applies to other inward fits while configured.
Omitted direction speeds inherit smoothing; expansionSmoothing only takes effect while
animateExpansion is true. Each bound chooses its own direction, so one can expand while the
other contracts. Finite speeds clamp to 0..1; non-finite speeds inherit smoothing.
On initial fitting or a data change that moves the fitted range wholly above or below
the displayed range, contraction is limited to the animated expansion speed until
the ranges overlap. This keeps the Y-axis bounds ordered even with very slow or frozen
expansion; normal independent speeds resume once the ranges overlap.
These speeds are frame-rate-independent exponential easing fractions, not fixed durations.
The 300 ms calculation assumes a stationary target; live data can continue moving the fit.
smoothing={1} takes precedence over the overrides, as do snapKey changes, static mode,
and active manual yRangeScale dragging. For reduced motion, use smoothing={1} and configure
axis-label fades with metrics={{ grid: { fadeInSpeed: 1, fadeOutSpeed: 1 } }} as needed.
Axis-label alpha transitions remain controlled by metrics.grid.fadeInSpeed and
fadeOutSpeed. The chart, reference lines, and overlays using ChartOverlayContext.scale
share the interpolated bounds throughout expansion and contraction. transitions continues
to control reveal/mode changes separately.