# Tooltips and the hover readout

> The value beside the cursor: three modes, and a template you write for what it says.

Section: Customization. Source: https://ortexcharts.com/docs/tooltips

## The Value Beside the Cursor

A chart with a dozen lines on it already has a legend, and the legend carries every series
and its value at the crosshair. What it cannot do is answer the question a reader asks by
pointing: *what is this one, here?* The tooltip is that answer, and nothing else — it
follows the pointer, and by default it says one line rather than all of them.

```ts
const chart = createFinancialChart(el, {
  data: bars,
  tooltip: {
    mode: "hovered",
    template: "{name}  {value}   1d {value % value[-1]}   1w {value % value[-7]}",
  },
});
```

Hovering the short-interest line then reads:

```text
29 AUG
■ Short interest  12.50
  1d +1.20%   1w -3.40%
```

The box carries three things: the hovered bar's date, formatted exactly as the time axis
labels it, then a row per series with that series' colour beside it, and under each row
whatever the template put after a newline. Set `title: false` to drop the date.

## Three Modes

| `mode` | What shows | When to use it |
|---|---|---|
| `"none"` | Nothing. The default. | A chart that has not asked for a tooltip does not grow one. |
| `"hovered"` | One row, for the series under the pointer | A page with many series, where the reader is pointing at one of them |
| `"all"` | One row per series on the hovered pane | Two or three series that are read together, such as a spread |

`hitRadius` decides how close the pointer has to be, in pixels, for a series to count as
hovered. It defaults to 24, which is a comfortable target on a touch screen; lower it if
your series sit on top of each other and the wrong one keeps winning.

## The Template

The text is a template you write, not a format we picked. It is deliberately small: it
reads a value, reads a value from earlier bars, compares two of them, and formats the
result. Anything past that is what `formatter` is for.

A placeholder is `{ term (operator term)? (|format)? }`.

### Fields

| Field | What it reads |
|---|---|
| `name` | The series title |
| `value` | The series' value at the hovered bar; the close, on a candlestick series |
| `open`, `high`, `low`, `close` | The bar's own fields |
| `volume` | The bar's volume |
| `index` | The bar's index in the data, which is occasionally useful while debugging |
| `time` | The hovered bar's timestamp |

A field can read backwards: `value[-1]` is the bar before the hovered one, `value[-7]`
seven bars before it. On a daily chart that is yesterday and last week; on a five-minute
chart it is five and thirty-five minutes ago. The offset counts bars, not days, because
that is what the chart has.

### Averages

`avg(field, n)` is the mean of `n` bars ending at the term's offset, which is how a chart
says "against the week behind it".

```ts
tooltip: { mode: "hovered", template: "{name} {value|compact}
vs 1w average {value % avg(value[-1],7)}" }
```

`avg(value[-1],7)` is the seven bars *before* the hovered one, so today is compared with
the week it followed rather than with a week it is part of. A window that runs off the
start of the data has no mean, and the row says so with an em dash rather than averaging
whatever happens to be there: on the third bar of a chart, a week-average comparison is a
question the data cannot answer.

Volume carries this by default, so a volume bar reads as busy or quiet rather than as a
number on its own.

### Operators

| Operator | Meaning | Example |
|---|---|---|
| `%` | Percent change from the right value to the left, which is what a reader means by "change" | `{value % value[-7]}` → `+4.10%` |
| `-` | Difference | `{value - value[-1]}` → `1.20` |
| `/` | Ratio | `{high / low\|num}` → `1.03` |

### Formats

A format follows a pipe: `{value|compact}`.

| Format | Output |
|---|---|
| `price` | The series' own price format, with its precision. The default for a value. |
| `pct` | `+4.10%`. The default when the operator is `%`. |
| `num` | `1.03`, rounded to two decimals |
| `compact` | `1.25M`, `3.40B` |
| `raw` | The number as JavaScript prints it |
| `date`, `time` | For `{time}`: `2026-09-07`, or `14:30` |

Two rules keep a template honest at the edges. A value the data does not have prints an em
dash rather than `NaN`, so a week-change placeholder on the eighth bar of the history says
so instead of lying. A placeholder that cannot be parsed is left on the page exactly as it
was written, which is how you find a typo without opening the console.

## Two Lines, and a Template per Series

A newline in the template starts a quieter line under the value. That is where a change
belongs: the value is what the reader came for, and the comparison is context.

```ts
template: "{name} {value}
1d {value % value[-1]}   1w {value % value[-7]}"
```

A series can also carry its own text, which overrides the chart's template for that row.
A volume histogram wants a different sentence from a price line, and the chart cannot
guess which.

```ts
chart.addSeries("histogram", {
  title: "Volume",
  tooltipTemplate: "{name} {value|compact}
vs 1w average {value % avg(value[-1],7)}",
});
```

## When the Template Is Not Enough

`formatter` receives the same row the template would have rendered and returns a string, or
`null` to fall back to the template.

```ts
tooltip: {
  mode: "hovered",
  formatter: (row) =>
    row.name === "Short interest"
      ? `${row.name} ${row.values.value?.toFixed(2)}% of free float`
      : null,
}
```

The row carries `name`, `time`, `index`, the series' `values` at the hovered bar, its
`priceFormat`, and `at(field, offset)` — the same reader the template's offsets use.

## Where It Sits

`offset` moves the box relative to the pointer, `{ x: 14, y: 14 }` by default. The box
flips to the other side of the cursor by itself when it would leave the chart, so a series
at the right edge is still readable.

The tooltip is styled from the theme tokens, so it follows a theme change without a second
configuration. See [Colors, fonts and formatting](https://ortexcharts.com/docs/customization).

## On the Shell

The shell passes the option straight through, so a full chart application configures it in
the same place as everything else.

```ts
const shell = createChartShell(el, {
  symbol: "AAPL",
  datafeed,
  tooltip: { mode: "hovered", template: "{name} {value}  {value % value[-1]}" },
});
```

Markers keep their own tooltips. A badge or a lane you hover still shows what it was given
in `tooltip`, whether or not series tooltips are on, because those two answer different
questions.
