Top-level React wrapper that creates a ChartInstance and provides it to children via context. Owns the DOM container and canvas lifecycle; renders children as an overlay layer.
Detects <Title>, <InfoBar>, and <Legend> children and positions them as:
Title + InfoBar — absolutely-positioned *overlays* stacked at the top of the canvas
block, so the canvas (and therefore the grid) fills the full container height. The stacked height is measured and fed back into chart.setPadding({ top }) so series data stays below them.
Legend — flex sibling at the bottom (or right, when position="right"), so its height is
reserved by browser layout.
The root component every chart starts with. Provides theme, axis configuration, padding, and the canvas; collects series and overlays from its children. Use viewport={{ maxVisibleBars, initialRange }} to size the streaming window and apply an initial zoom *before* the first paint (same shape as the imperative chart.setVisibleRange).
Props
children?ReactNode
Series components and UI overlays (Tooltip, TimeAxis, etc.) rendered inside the chart.
theme?ChartTheme
Visual theme. Live — changing this at runtime updates all themed elements.
Viewport-level streaming behavior. Captured at mount only — changing this prop after the chart is created is ignored.
visibleRange?VisibleRangeSpec
Controlled visible range. Same shape as the imperative chart.setVisibleRange — a bar count, an explicit {from, to} window, or {from, bars}. Every reference/value change applies via chart.setVisibleRange, so pair it with onVisibleRangeChange for a two-way binding; a same-value literal (compared structurally) is a no-op, so an inline object from a parent re-render doesn't re-apply.
For a one-shot initial window that isn't re-applied on every prop change, use viewport.initialRange instead.
gradient?default to trueboolean
Show the chart background gradient. Live. Defaults to true.
interactive?default to trueboolean
Enable zoom, pan, and crosshair interactions. Defaults to true.
Mount-only — core has no setInteractive, so changing this prop after mount is ignored.
How <Title> and <InfoBar> are positioned relative to the canvas. Live.
'overlay' (default): absolute overlays on top of the canvas — the grid
and Y-axis labels render full-height behind the header strip.
'inline': flex siblings above the canvas — the canvas (and grid) are
shifted down by the measured header height, so nothing renders behind the title. The chart background still spans the full container.
animations?boolean | AnimationsConfig
Animation control. true / omitted uses built-in defaults; false disables every category. Per-series options on <LineSeries> / <CandlestickSeries> / <BarSeries> override these chart-level defaults unless the category here is explicitly false.
Init-only, but diffed by value, not reference. A same-value inline object literal is a no-op — only a genuine change to the resolved config recreates the underlying ChartInstance (and its canvas), since the animation engine doesn't support live reconfiguration yet. Still worth a stable reference (useMemo(() => ({...}), [deps])) to avoid the per-render deep-equal check, but forgetting it no longer tears the chart down. In dev mode the container emits a console warning if it detects >3 *genuine* recreates/s.
perf?PerfOption
Runtime performance instrumentation. Off by default — pass a config factory, not a plain object (that pulls the perf module into your bundle only when you actually use it):
perfHud() — attach a PerfMonitor and render a visible HUD overlay on this chart.
perfHud({ windowMs, maxSamples, ... }) — same, with monitor options.
perfHud(existingMonitor) — attach a visible HUD to an already-created monitor.
a raw PerfMonitor instance — instrumentation without the HUD.
Only read at mount; changing this prop after the chart is created is ignored.
onEdgeReached?(info: EdgeReachedInfo) => void
Fired after the user releases a pan/zoom gesture that pulled the viewport past a data edge by more than ~10% of the visible range. Hosts typically respond by prefetching more history.
For threshold-based prefetch (load *before* the user fully overshoots), use <EdgeLoader> instead — that component subscribes to viewportChange and arms when the visible range nears the data edge.
Captured at mount only; changing the prop identity later is ignored.
onPointClick?(info: PointClickInfo) => void
Fired on a click (or tap) on the chart canvas that isn't the tail end of a pan drag. info.spatialHit resolves a pie/heatmap/custom-spatial series directly under the pointer; for a time-series series, resolve the point yourself from info.time (chart.getDataAtTime / buildHoverSnapshots). Live — the latest callback is always used.
onPointDoubleClick?(info: PointClickInfo) => void
Fired on a double-click on the chart canvas. The chart also responds by calling fitContent(). Live — the latest callback is always used.
Fired when the spatially-hovered series/index changes (pie, heatmap, or a custom spatial kind) — null when the pointer leaves every hit area. Live — the latest callback is always used.
onReady?(chart: ChartInstance) => void
Fired once the underlying ChartInstance is constructed — on mount, and again if the chart is ever rebuilt (a genuine animations value change). Use this to reach for imperative APIs the declarative props don't cover yet. Live — the latest callback is always used for the next rebuild.
Fired whenever the committed visible range changes — pan, zoom, fitContent(), a data update that shifts the tail-scroll window, or a visibleRange prop change. Live — the latest callback is always used.