interface ChartOptions {
    animAutoscale?: boolean;
    animZoom?: boolean;
    ariaLabel?: string;
    axisChrome?: AxisChromeOptions;
    barsProvider?: IndicatorBarsProviderAccess | IndicatorBarsProvider;
    branding?: boolean | LogoWatermarkOptions;
    canvas?: CanvasOptions;
    conflate?: boolean;
    conflationFactor?: number;
    crosshairMode?: CrosshairMode;
    crosshairSnapToBar?: boolean;
    document?: Document;
    doubleClick?: DoubleClickAction;
    grid?: Partial<GridOptions>;
    indicatorLegendCollapsed?: boolean;
    legendIconSize?: number;
    legendOffset?: { left?: number; top?: number };
    movablePrimaryPane?: boolean;
    navigation?: Partial<ChartNavigationOptions>;
    now?: () => number;
    pixelRatio?: () => number;
    priceAxisWidth?: number;
    priceFormatter?: (price: number) => string;
    priceOnlyAutoScale?: boolean;
    priceScale?: Partial<PriceScaleOptions>;
    raf?: { cancel?: RafCanceller; schedule: RafScheduler };
    renderBackend?: RenderBackendFactory;
    renderer?: RendererChoice;
    shortcuts?: false | ShortcutManager | Partial<ShortcutManagerOptions>;
    statusLine?: LegendStatusLineOptions;
    theme?: ChartTheme;
    timeAxisHeight?: number;
    timeFormatter?: (utcSeconds: number, tickMark?: TickMarkType) => string;
    timeNavigator?: boolean | Partial<TimeNavigatorOptions>;
    timeScale?: Partial<TimeScaleOptions>;
    timezone?: string;
    watermark?: boolean | ChartWatermarkOptions;
    zoomAnchor?: ZoomAnchor;
}

Properties

animAutoscale?: boolean

Ease automatic price ranges during navigation. Defaults to animZoom (true).

animZoom?: boolean

Ease a wheel zoom over a few frames instead of landing the whole step on one. Default true, matching the inertial pan a flick already gets: a chart that glides when panned and jumps when zoomed reads as two different instruments. Off restores the single-frame step.

ariaLabel?: string

Accessible label for the chart container (screen readers).

axisChrome?: AxisChromeOptions

Optional chrome on the axis strips: the corner clock and the bar-close countdown. Both are off unless asked for, so a chart that omits this block draws the axes it always drew.

Where an indicator gets another instrument's bars. The engine is handed one symbol's history and owns no transport, so a study that compares against a benchmark asks through this and the host answers from wherever it keeps candles. Change it later with setBarsProvider. Without one an indicator's requestBars rejects, and the study reports itself unsupported rather than drawing something invented.

branding?: boolean | LogoWatermarkOptions

OpenAlgo corner mark by default. Pass false to hide it or options for custom branding.

canvas?: CanvasOptions

The settings dialog's Canvas block: grid, crosshair, scale text/lines and plot margins. Every field is an override of the theme, so a later setTheme still restyles anything the dialog did not touch.

conflate?: boolean

Level of detail for a zoomed-out chart (§4.4). Default true: once bars are narrower than the stick a candle is drawn with (about one CSS px; exactly one at a whole pixel ratio), the bars sharing a device-pixel column are drawn as one OHLC-preserving stick (open of the first, close of the last, the column's high and low), and line and histogram series keep each column's first, lowest, highest and last values. A frame then costs the plot's width, not the number of bars in view. Above that spacing nothing changes. Data, autoscale, indicators and the crosshair still see every bar. false draws every bar at every zoom.

The default time scale never zooms out past one bar per CSS px (timeScale.minBarSpacing: 1), so it matters once a host lowers that floor.

conflationFactor?: number

Column width in sticks (default 1). Higher merges into wider columns, and from spacings that many times wider, for a coarser, cheaper picture.

crosshairMode?: CrosshairMode

Crosshair behaviour. 'normal' (default): the cross follows the pointer exactly. 'magnet': the horizontal line snaps to the nearest O/H/L/C of the bar under the cursor (price pane only).

crosshairSnapToBar?: boolean

Snap the vertical crosshair to the nearest primary bar's center. Default false; independent of the price magnet.

document?: Document
doubleClick?: DoubleClickAction

What a double-click on a pane does. 'reset' (the default, and what the chart has always done) fits every loaded bar on screen and autoscales, which also lands the viewport on the oldest bar and so wakes a history loader. 'maximize' gives the pane the whole stack, and a second double-click puts the stack back, which is what a multi-pane terminal usually wants from the gesture. 'none' only emits the event. While a tool is being placed a double-click finishes the shape whatever this says.

grid?: Partial<GridOptions>

Grid lines: visibility (both default to true) plus per-axis colour, dash, width and spacing. Unset colours/dashes fall through to the theme.

indicatorLegendCollapsed?: boolean

Collapse study legend rows into a count without hiding their plots or stopping calculations. Default false.

legendIconSize?: number

Square side of a legend action button in media px. Default 16, held to 12..28. Applied to every pane legend, because the rows stack against it.

legendOffset?: { left?: number; top?: number }

Where indicator legend rows start inside one pane, in media px. A host that draws its own overlay in a pane's top-left corner (an OHLC readout, a symbol line, a trade panel) needs to push these clear of it, or the rows land underneath and their settings / close buttons become invisible and unclickable.

It follows the primary price pane, which is at the top until something moves it below its studies: a readout of the price belongs to the price pane, wherever it sits. Maximizing a study pane hides the price pane, so the maximized pane, now in the same corner, inherits the offset. Every other pane keeps the default corner, because a short study pane would have its legend pushed off it entirely.

Defaults to { top: 6, left: 8 }.

movablePrimaryPane?: boolean

Let the primary price pane leave the top of the stack: below its studies through movePane, setPrimaryPaneIndex, a study pane's own up and down controls, or a restored layout that saved it lower down. Default false, which keeps the price pane pinned at slot 0 exactly as every earlier release did: movePane refuses to move or displace it, setPrimaryPaneIndex returns false, and restoreState refuses a layout that puts it anywhere else, so an explicit pane 0 always means the price.

Opt-in because a host that passes 0 to mean the price pane (a price or order line, coordinateToPrice(y, 0) pricing a right-click order, a price alert check, panes()[0]) would read a study's units the moment a user moved a study above the candles. Before turning it on, drop those explicit zeros or ask primaryPaneIndex(), and follow paneMoved. Decided once, at construction; read it back with movablePrimaryPane(). createWidget and createChartGrid hand it to their charts as given, off by default too.

navigation?: Partial<ChartNavigationOptions>

Saved navigation preferences, also exposed in the Axes settings tab.

now?: () => number

Time source for kinetic animation (defaults to performance.now). WidgetOptions.now is a different clock (the widget's wall clock, epoch milliseconds) and is not passed to a widget's chart.

pixelRatio?: () => number
priceAxisWidth?: number
priceFormatter?: (price: number) => string

Custom price formatter for every pane's axis tick labels, the last-price tag, and price-line labels. e.g. (p) => '$' + p.toFixed(2). When omitted, a tick-size-aware toFixed is used. Change it later via setPriceFormatter.

priceOnlyAutoScale?: boolean

Fit the primary series' scale to that series only. Does not enable auto-fit. Default false.

priceScale?: Partial<PriceScaleOptions>

Default price-scale options applied to every pane (tick size minMove, mode: 'linear' | 'logarithmic' | 'percentage' | 'indexed-to-100', inverted, and top/bottom margins). minMove is the instrument's, so it lands only on panes that quote it, see setPriceScaleOptions. Tune a single pane later via chart.panes()[n].priceScale.setOptions(...).

raf?: { cancel?: RafCanceller; schedule: RafScheduler }

The frame scheduler, for deterministic tests. Supplied, it runs every frame the chart paints, the one after a resize or a new pixel ratio included; with the default one the chart paints those inside the callback that reports them, so a resize never shows a cleared canvas.

renderBackend?: RenderBackendFactory

Build the backend directly, one call per pane, bypassing renderer and the registry. For a host bringing its own backend, and for tests that want to see what the pane asks a backend to paint. A factory that returns null gets the 2D backend for that pane.

renderer?: RendererChoice

Which backend paints the series. 'canvas2d' (the default) is the 2D path every chart has always drawn with. 'webgl2' asks for the GPU backend: it throws when the tier that registers it has not been imported (a missing import is a mistake in the code), and on a device where that tier finds no WebGL2 it falls back to canvas2d with one console warning (a property of the machine the host should still hear about). 'auto' takes webgl2 when it is registered and available on this device and canvas2d otherwise, silently. Decided once, at construction; read what was actually chosen from rendererKind. A GPU backend that loses its context later moves the chart to canvas2d for the rest of the session and emits 'renderer:fallback'.

shortcuts?: false | ShortcutManager | Partial<ShortcutManagerOptions>

Keyboard shortcuts. Pass a configured ShortcutManager, options to build one, or false to disable keyboard control. Defaults to the built-in keymap.

Per-field status-line switches applied to every pane legend on the chart.

theme?: ChartTheme

Full palette; pass lightTheme (the default), darkTheme, or a custom ChartTheme.

timeAxisHeight?: number
timeFormatter?: (utcSeconds: number, tickMark?: TickMarkType) => string

Custom time-axis and crosshair label formatter (receives UTC seconds). When omitted, labels follow timezone, which is IST unless set. e.g. for UTC: (s) => new Date(s * 1000).toISOString().slice(11, 16).

timeNavigator?: boolean | Partial<TimeNavigatorOptions>

Hover-revealed zoom / step controls above the time axis, as terminals show. true by default: they stay invisible until the pointer nears the bottom of the chart. Pass false to drop them, or an options object to restyle.

timeScale?: Partial<TimeScaleOptions>

Initial horizontal scale configuration, including spacing limits for wide profiles.

timezone?: string

IANA zone the time axis and crosshair label in, e.g. 'America/New_York' or 'Europe/London'. Defaults to 'Asia/Kolkata': a caller who passes nothing gets exactly the labels the chart produced before this option existed.

An IANA name and not a fixed offset, because a zone that observes DST is a different offset in July than in January and a fixed one is silently wrong for half the year. Change it at runtime with setTimezone when the terminal moves between an NSE symbol and a US one. An explicit timeFormatter outranks this: a host that formats its own labels has settled the question.

Throws if the runtime does not recognise the name.

watermark?: boolean | ChartWatermarkOptions

Background text, off by default. Blank text follows setDataContext.

zoomAnchor?: ZoomAnchor

What a wheel zoom holds still: the bar under the cursor, or the right edge (the latest bar). Default 'cursor', which is what the chart has always done. 'right' keeps the most recent bar pinned while history stretches away from it, which is what a live chart usually wants.