Skip to main content
Experimental. yRangeScale is available on LiveChart (line and candle modes) and LiveChartSeries. The library owns the scale math, while your app owns the gesture and reset behavior.
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

Mount 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 smoothing or the optional rangeAnimation overrides.
  • Reset with an animation such as withTiming(1) for the same smooth result whether the current scale is above or below 1.
  • On a nonNegative chart, zoom-out stops when the lower bound reaches 0. 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.
  • maxValue is 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 with smoothing. 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:
The return speed applies directly to contraction on the UI thread, so release needs no timer or temporary change to global 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.