Skip to main content
Charts are interactive by default. Hovering highlights the nearest observation and shows a tooltip, with no configuration.
How the highlight and the dimming around it are painted is a style question; see Restyling hover and dimming below.

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.
Custom geoms answer their own hit-test queries. Layers can opt out with interactive: false, for example a decorative point overlay that should not compete with the line beneath it:
A non-interactive layer is filtered out before both hit-testing and grouping, so it never takes a hover and never appears as a companion row in another layer’s tooltip. As far as hover is concerned it is decoration. A rule layer is non-interactive by default. A layer that describes another, such as a marker for each bar’s target or an error bar over its bar, attaches to it with 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:
A layer can only attach to an interactive layer that stands alone. An 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.
By default 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’s tooltip 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:
  • false removes a row and true adds or moves it.
  • title replaces the row’s label, and format its value format. Values are formatted in the chart’s locale. The default rows keep their color group’s label, so a title on y names them only on a layer without color groups.
  • heading: true heads the tooltip with the field’s value instead of the hovered main-axis value.
A key the layer cannot read is dropped with an UNKNOWN_TOOLTIP_FIELD warning, and the chart still renders.

Appearance

To change how the tooltip looks, replace it with the Tooltip 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, with trigger: '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:
The intro takes these settings:
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.
A viewer who prefers reduced motion gets no animation whatever this asks for.

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.
  • Styling — the hovered and dimmed states, and everything else the chart paints
  • Slots — replace the tooltip or other regions
  • Provider & renderer — showTooltips, animation, mode