Data Legend and Readout
Two ways to answer "what are the numbers at the bar under my cursor": the built-in corner panel, or getDataAt() for building your own.
The built-in legend
const chart = new ApexStock(el, {
legend: { show: true, position: 'top-left' },
// ...
})
Or imperatively:
chart.showLegend({ position: 'top-right' })
chart.hideLegend()
chart.toggleLegend()
chart.isLegendVisible()
| Option | Default | What it controls |
|---|---|---|
show | false | Whether the panel is drawn |
position | 'top-left' | 'top-left', 'top-right', 'bottom-left', 'bottom-right' |
showChange | true | The change against the previous close |
showVolume | true | The bar's volume |
showIndicators | true | Each main-chart overlay indicator's value |
The panel reads out the instrument's OHLC, the change against the previous close, and the volume at the crosshair, falling back to the latest bar when the pointer is off the chart. It tracks the pointer through the crosshairMove event and stays in sync as indicators are toggled. It is pointer-events: none, so it never intercepts a click or a drag meant for the chart.
Reading the same values in code
getDataAt(index?) is a read-only, structured snapshot at a bar index:
const at = chart.getDataAt(120)
at.index
at.x
at.ohlc // { open, high, low, close }
at.volume // null when the bar carries none
at.change // { absolute, percent }, null on the first bar
at.indicators // [{ name, value, color, pane, key? }]
indicators covers both main-chart overlays, where pane is 'main', and oscillator panes, where pane is the indicator's key. That includes the drawdown pane.
Values are plain unformatted numbers. Anything unavailable is null (volume, change) or omitted (an indicator still inside its warm-up period). With the index omitted or out of range, it returns the latest bar.
Building a custom legend
Pair it with the crosshairMove event's dataPointIndex:
chart.on('crosshairMove', ({ dataPointIndex }) => {
const at = chart.getDataAt(dataPointIndex)
if (!at) return
panel.textContent = [
`O ${at.ohlc.open.toFixed(2)}`,
`H ${at.ohlc.high.toFixed(2)}`,
`L ${at.ohlc.low.toFixed(2)}`,
`C ${at.ohlc.close.toFixed(2)}`,
at.change ? `${at.change.percent.toFixed(2)}%` : '',
...at.indicators.map((i) => `${i.name} ${i.value.toFixed(2)}`),
].join(' ')
})
This is the route to a side panel, a header strip, or a readout rendered by your own framework instead of by the chart.
See also
- Range Statistics and Drawdown for statistics over a window rather than at a point
- Technical Indicators for the indicators the readout reports
- Methods for the full event list