Repository navigation
v4.27.0 — Chart controls and reference tags
[4.27.0] — 2026-10-09
Added
-
referenceLineGrouping.mode: "stack"keeps individual reference tags readable
using measured bounds and independent horizontal columns. Supports name/value
pills, custom tags, off-axis pins, and moved press/drag targets without changing
price strokes. Stack mode avoids the visible live value badge by default via
avoidValueBadge; custom renderers receivetagOffsetY. Existing collapse
behavior remains the default. The Working orders demo compares all three modes.
(#377) -
Opt-in
yAxis.scaleGesturefor line, candle, and multi-series charts, with
exportedYAxisScaleGestureConfig: drag the actual price gutter down to
widen the range or up to zoom in, and double-tap to reset. Supports bounded
scaling, configurable sensitivity, and either a suppliedyRangeScaleor
internal state. Uses live layout/label measurements and leaves interactive
overlays and plot gestures intact. The Y-range scale demo now uses it.
(#376) -
ReferenceLine.valueBadgeand exportedReferenceLineValueBadgeConfig: a
separate UI-thread price pill for horizontal reference lines, positioned in
the plot or aligned with the right price column. Name/value pills share drag
values, connector geometry, off-axis pinning, custom-renderer replacement,
and grouping. The Working orders demo includes placement and axis controls.
(#375) -
Opt-in
scrub.markersonLiveChartandLiveChartSeries, with exported
ScrubMarkerConfig: return timestamp-matched markers and theirdatathrough
onScrub, plus a UI-threadmarkersshared value inLiveChart.renderTooltip.
Line charts use a configurable horizontal radius (default 16 px); candle
charts select the hovered bucket. Matches include stacked/collapsed members
in input order. The Markers & trades demo includes line/candle inspection.
(#366) -
xAxis.gridLinesonLiveChartandLiveChartSeries: vertical grid lines at
the time labels, drawn behind the series in the horizontal grid's layer and
fading with their labels at the plot edges.trueuses thegridStylelook;
aGridStyleConfigoverrides only the fields it sets. They run through a
candle chart's volume band to the axis line, stay within the plot width, and
followLiveChart'saxisAutoHide. Off by
default. The Axes & grid demo has a toggle for them. -
Experimental
LiveChart.viewport(false | ViewportConfig) and exported
ChartViewportControl/ViewportConfig: adopt
app-owned shared values for scroll/zoom, with gestures writing the same pair.
External overrides survive base-window and gesture-setting changes, honor
future right edges, and wakeautoSleep. Followers can set
windowSmoothing: falseto copy the leader's drawn width without easing twice.
Omitted/false uses private state; behavior defaults resolve at render time in
the shared config resolver, preserving the supplied shared values by reference. -
A Synced charts demo and guide: one instrument in 1m/15m candle panes,
leader selection, reset, base-window changes, and idle engine counters. -
minRangeonLiveChartandLiveChartSeries: the smallest Y span the
auto-fit shows, in data units. Near-flat data widens to it around its
midpoint instead of zooming in until every grid label reads the same, e.g.
minRange={priceIncrement * 4}. On anonNegativechart or under
maxValuethe span slides off the bound rather than shrinking, even when the
ordinary fit's margin is clipped. If both hard bounds leave less room than
the floor, they win; manual zoom applies afterward. Invalid or overflowing
floors are ignored. Omitted, the fit is unchanged. -
A Minimum Y range demo and matching guide with rounded-label comparisons,
zero/ceiling bounds, line/candle/series modes, static updates, manual zoom,
and a simulator walkthrough. -
onScrubCandleChangeonLiveChart(candle mode): called when the scrub
crosshair enters or revisits a candle, with an OHLC snapshot on the JS thread.
Sendsnullwhen the scrub ends, enters a gap, or leaves candle mode.
UnlikeonScrub, which fires every frame on a live chart, it fires once per
candle, e.g. for a haptic tick per candle. -
A discoverable Candle feedback demo with entry/exit counts, a gap, a ticking
forming candle, haptics, and an optional per-frame callback comparison, with a
matching guide and simulator recording. -
A discoverable Badge alignment demo with centered/column comparison,
repeatable$99.95/$100.00transitions, and controls for axis layouts,
gutter width, badge font, tail, and offset, with a matching guide and recording. -
BadgeConfig.textAlign("center" | "yAxisColumn", default"center"):
"yAxisColumn"lines the right-gutter live badge's value up with a
right-anchored Y-axis label column (yAxis.labelRightMargin). The value
starts at the labels' left X, a value wider than every axis label ends at the
column's right edge, and it stays within the pill's padding. Centered, the
value sits half the pill's spare room off the column even with matching badge
metrics, and the automatic right inset leaves a digit spare (it sizes for the
value ×10). The value moves with the column's width; the axes guide shows a
matchingmetrics.badgeandinsets.rightsetup.
Changed
LiveChartreuses its gesture configurations and composition across reference
level updates and replacement JS callbacks. Cached config/layout results avoid
rebuilding unrelated interaction inputs. Reference drags read current line
props on the UI thread; JS callbacks use the latest committed props. Gesture
recognition and numeric layout changes still invalidate the relevant configuration;
equivalent padding from recreated inline configs keeps scrub gestures cached.
Completes the gesture follow-up to #383 (#373).LiveChartis memoized, so a parent render with unchanged props no longer
re-runs the chart. Pass stable references (memoized arrays and callbacks) to
benefit; live data still flows through SharedValues as before.- Reference lines, gap bands and the
renderReferenceLine/
renderOffAxisReferenceLineprobes are only re-resolved when
referenceLines,candleGaps/lineGapsor those renderers change, not on
every render. A chart without gaps also keeps a stable crosshair gap list.
Fixed
- Static single-series charts now re-settle when
yRangeScaleornonNegative
changes without replacing data, so a manual zoom also updates a floored fit. - The right gutter for y-axis labels and the value badge now re-measures once
the first real value arrives, instead of staying sized for a0placeholder
and clipping labels like$87,000.LiveChartandLiveChartSeriesskip
0and non-finite values when sampling, and re-measure only when the value
moves a full order of magnitude. Multi-series charts sample the largest finite
magnitude, so negative values alongside zero placeholders are measured too. - With
yRangeScalebelow1, the line, area fill, candles and gap bridges
are now clipped to the plot's vertical extent instead of drawing past its top
and bottom and over the time axis. In candle mode the clip stops at the price
plot, above the volume band. Applies toLiveChartandLiveChartSeries. xAxis.minGapnow sets the minimum spacing between time labels on
LiveChartandLiveChartSeries. It was resolved but never applied, so the
labels always kept the default 60 px spacing. Changing the gap also replaces
the label set immediately on paused or parked charts, so old labels cannot
remain at the previous spacing while their fade waits for engine frames.- Static single-series charts now re-settle when
nowOverridechanges, and a
chart that becomesstaticin the same render as new data (e.g. a recycled
list cell) lands fully on the new window instead of stopping part way or
keeping the previous right edge. - A dragged reference line stays under the finger when the price range changes
or the plot is resized while the finger rests (live data, arangeAnimation
easing): it is re-mapped from the finger's position with the samesnapand
bounds, and its tag, grouping, press target andonDragIn/onDragOut
follow it in the same frame.onCommitgets the value under the finger.
onChangestill reports finger moves (plus one catch-up on release if the
line ended elsewhere), and the range still fits the value the finger last set,
so a line held near the plot's edge doesn't push the range out every frame;
dropped there, it widens the range once. - With
snap, a line dragged to the plot's top or bottom edge is drawn and
dropped on the nearest increment inside the visible range instead of just
past it. Dragged past the edge, the value the finger sets rounds outward, so
even a coarsesnapcan widen the range. - If lines added or removed mid-drag move a dragged line with an
idto
another index, the drag lets go: it stops following the finger and commits
nothing, instead of moving and committing the line that took that index. That
line immediately gets its ownvalueback in place of the dragged value it
inherited by index, even while the finger rests. Bringing the original line
back before release does not resume the cancelled drag. - Removing the line being grabbed or dragged no longer throws on the UI thread
(readingvalueas the drag starts or on release, orsnapon the next
move); the drag lets go. - Markers are no longer drawn up to 24 px past the plot's left and right edges.
A marker now disappears as soon as its anchor leaves the plot, so panning
back no longer slides it over the y-axis labels in a right- or left-side
gutter, andonMarkerPressno longer fires for it there. A glyph anchored
just inside an edge still overhangs it by up to half its width. On the left
this is a visible change: with the default 12 px inset, a marker scrolling
out used to slide off the canvas; it now disappears at the plot's left edge.
A marker dated after the chart's current time appears once that time is
reached, at the right edge. The 24 px allowance above and below the plot is
unchanged. Live markers stay visible while the time window expands, including
during pinch zoom, by keeping timestamp rounding below half a visible pixel. DotConfig,DotRingConfig,LineStyleConfig,ThresholdFillConfig, and
TimeScrollConfigare now exported from the package root, which the Types
reference says holds every type. Importing them fromreact-native-livechart
no longer fails to typecheck.- The extrema labels guide's
LineStyleConfiglink points at the Config objects
section of the Types reference instead of a missing anchor.