How hover works
Hit-testing runs in the engine, and the query depends on the geom:- Banded and bucketed cartesian geoms (bars, lines, areas) snap along the main axis: the coordinate the bands or buckets run along, which is x for a vertical bar or line chart and y for a horizontal bar chart. The cursor never has to land exactly on an observation, which is why a line chart responds smoothly between vertices. Everything at that main-axis position highlights together, every segment in a stack and every group in a multi-line chart, and the tooltip lists their values in legend order.
- Point layers (scatter) use the nearest neighbor in 2D, so the closest point is picked rather than the nearest column.
- Polar charts (pie and donut) hit-test the enclosing arc: the slice the cursor is inside.
- Grid layers (heatmaps) hit-test the enclosing cell, over its full band rather than the inset tile painted inside it. Cells the data leaves empty answer no hover.
interactive: false, for example a decorative point overlay that should not compete with the line beneath it:
attachTo. An attached layer never takes the hover itself. It joins the hover of the layer it attaches to, and its tooltip rows sit under that layer’s, each under the observation it describes. 'previous' attaches to the nearest earlier layer that stands alone, a layer id names one, and 'none' keeps the layer on its own, which is the default for every built-in geom:
id that names no such layer, or a 'previous' with nothing before it, leaves the layer on its own and the chart still renders.
Marker diameter is a style, not a geom parameter:
Restyling hover and dimming
Hover and dimming are painted through two style states,hovered and dimmed, that any geom entry can scope to. dimmed covers both cases where an element steps back: a highlight matched something else, or the pointer is on another element. States only paint. They never feed layout, so nothing moves when the pointer does.
dimmed drops a geom to alpha: 0.4. A hovered geom gains a soft shadow, and hovered bars and tiles also draw a white outline. See Styling for the full cascade.
Tooltips
Tooltips are on by default.config.tooltip.mode chooses which hovered observations the tooltip lists:
'band'(default) lists everything at the hovered position: every segment of a stack, every bar of a group, and the related observation on each other layer. A range row, such as an error bar’s, lists every group’s range in legend order, each named after its group.'observation'lists only what was hovered, and from each other layer the observation in the same group. In a grouped bar chart with error bars, hovering one bar shows that bar and its interval.'none'shows no tooltip. Hover, highlight and the hover guide still respond.
showTooltips={false} on the renderer hides the tooltip whatever the spec says. The 'editable' and 'point-and-edit' modes hide it too:
A layer’s rows
Each layer contributes its geom’s rows: the hovered value, labeled by its color group, or the fields a geom declares (a candlestick’s open, high, low and close). A layer’stooltip adds, removes, renames, reorders and formats them. Its keys name an aesthetic the layer maps, a variable the geom derives, or one of the geom’s own fields; a layer’s default rows are named y. Your entries come first, in their order, then the geom’s remaining rows:
falseremoves a row andtrueadds or moves it.titlereplaces the row’s label, andformatits value format. Values are formatted in the chart’s locale. The default rows keep their color group’s label, so atitleonynames them only on a layer without color groups.heading: trueheads the tooltip with the field’s value instead of the hovered main-axis value.
UNKNOWN_TOOLTIP_FIELD warning, and the chart still renders.
Appearance
To change how the tooltip looks, replace it with theTooltip slot. It receives TooltipSlotProps: a single content prop carrying the formatted, render-ready rows the default tooltip gets. Positioning stays built in. DefaultTooltip is exported, so a custom tooltip can wrap it rather than rebuild it:
Animation
A graph animates by default: an intro entrance on first mount (or, withtrigger: 'inView', when its
panel comes into view), and transitions between compiled states when the data or a config value changes. Pass animation to turn either kind off, or to tune the intro:
boolean
default:"true"
Whether the entrance plays at all. Passing
intro: false is the same thing.'mount' | 'inView'
default:"mount"
When the entrance starts.
inView waits until 40% of the panel is on screen,
so a graph below the fold plays it as the reader scrolls to it. Until then
only the title, axes and pill legends draw. It plays once, and on mount where
the browser has no IntersectionObserver. Use mount for a panel that may
never be 40% on screen: one clipped by its container, one taller than two and
a half screens, or a printed page.number
default:"1"
Multiplier applied to every entrance duration and stagger delay.
boolean
default:"true"
Whether geoms that support a staggered entrance enter one after another rather
than all at once.
IntroStaggerOrder
default:"main-axis"
The order staggered point geoms enter in. Bars and slices always enter in
visual order.
Transitions
boolean
default:"true"
Whether geoms animate to their new position when the data or a config value
changes. Set on
animation itself, beside intro: turning one off leaves the
other running.Dense charts
number
default:"1500"
Total geom count across all layers above which the graph plays no animation,
intro or transitions. A line or area is one geom however many points it draws.
Set on
animation itself, beside intro and transitions.Related
- Styling — the
hoveredanddimmedstates, and everything else the chart paints - Slots — replace the tooltip or other regions
- Provider & renderer —
showTooltips,animation,mode

