Tooltip
The <Tooltip> component displays data values when users hover over chart elements.
Add a tooltip
Place <Tooltip> inside any chart container:
<BarChart :width="500" :height="300" :data="data">
<Bar data-key="value" fill="#8884d8" />
<Tooltip />
</BarChart>
Customize tooltip content
Use the #content slot for full control:
<Tooltip>
<template #content="{ active, payload, label }">
<div v-if="active && payload?.length" class="bg-background border rounded p-2 shadow">
<p class="font-medium">{{ label }}</p>
<p v-for="entry in payload" :key="entry.dataKey" :style="{ color: entry.color }">
{{ entry.name }}: {{ entry.value }}
</p>
</div>
</template>
</Tooltip>
Pre-select a tooltip index
Use default-index to show the tooltip at a data index on the first render. Users can still
hover to move it.
<Tooltip :default-index="2" />
Activate on click
With trigger="click", the tooltip appears when the user clicks, and stays until the user
clicks elsewhere.
<Tooltip trigger="click" />
Keep the tooltip open
active overrides the chart: true keeps the tooltip visible, false hides it. Combine it
with default-index to pin the tooltip to one point:
<Tooltip :active="true" :default-index="3" />
To control the active point from outside the chart, bind v-model:active-index. See
Events and v-model.
Shared and item tooltips
Each chart type activates the tooltip in one of two ways:
- Axis: the tooltip follows the category axis and shows every series at that index. This is the default for AreaChart, BarChart, LineChart, ComposedChart, RadarChart and RadialBarChart.
- Item: the tooltip opens on the hovered item and shows only that item. This is the default for ScatterChart, PieChart, FunnelChart and the standalone charts.
shared switches between the two where the chart supports both: :shared="false" gives item
tooltips in a BarChart, LineChart or RadialBarChart, and :shared="true" gives axis tooltips
in a ScatterChart. AreaChart, ComposedChart and RadarChart always use axis tooltips; PieChart
and FunnelChart always use item tooltips.
<Tooltip :shared="false" />
Disable the cursor
<Tooltip :cursor="false" />
Tooltip props
| Prop | Type | Default | Description |
|---|---|---|---|
active | boolean | undefined | Force active state. true keeps tooltip visible, false hides it, undefined lets the chart control visibility. |
active-index | number | null | — | Current model index; null selects no target |
default-index | number | — | Pre-selected data index shown on initial render |
trigger | 'hover' | 'click' | 'hover' | Activation trigger |
shared | boolean | undefined | Show all series at hovered index. When undefined, defaults to true for axis-type charts. |
cursor | boolean | object | true | Show/customize cursor. Pass an object to set SVG attrs on the cursor element. |
offset | number | 10 | Pixel offset from cursor |
include-hidden | boolean | false | Show hidden series data |
filter-null | boolean | true | Filter out entries with null values |
formatter | (value, name, entry, index, payload) => VNodeChild | [value, name] | — | Format each row of the default content. Return a pair to change the name too. It wins over a chart's own formatter |
label-formatter | (label, payload) => VNodeChild | — | Format the label in the default content |
transition | ChartTransition | motion tokens | Timing and easing for tooltip motion |
is-animation-active | boolean | true | Animate tooltip position changes |
allow-escape-view-box | { x: boolean, y: boolean } | { x: false, y: false } | Allow tooltip to overflow the chart area |
position | { x?: number, y?: number } | — | Pin tooltip to a fixed position |
reverse-direction | { x: boolean, y: boolean } | { x: false, y: false } | Flip tooltip placement direction |
to | string | HTMLElement | — | Teleport tooltip to a CSS selector or DOM element |
payload-uniq-by | boolean | Function | — | Deduplicate payload entries |
axis-id | string | number | 0 | Target axis ID for tooltip interaction |
content-style | object | {} | Inline styles for tooltip content wrapper |
label-style | object | {} | Inline styles for the label |
item-style | object | {} | Inline styles for each payload item |
item-sorter | 'name' | 'value' | 'dataKey' | Function | — | Sort payload items. Without it, items keep the series order |
separator | string | ' : ' | Separator between name and value in default content |
style | object | {} | Inline styles for the tooltip bounding box |
Payload
The #content slot, the formatter and label-formatter receive payload: one
TooltipPayloadEntry per row, in series order.
| Field | Type | Description |
|---|---|---|
name | string | number | Series name, or the data key |
value | number | string | Array | Raw value of the row; an array for ranged data |
payload | unknown | The data row (or node, link or cell) behind the entry |
dataKey | row path or accessor | The series data key |
color, fill, stroke | string | Colors of the series or entry, for swatches |
unit | string | number | Series unit |
chartType | string | Series type, for example 'line' |
hide | boolean | Whether the series is hidden; hidden rows show only with include-hidden |
All charts use this shape, including the standalone charts: payload is the domain object
(your Treemap or Sankey node, a Heatmap cell, a Tracker row, …) and value is the raw number.
The default content shows readable text; a formatter receives the raw value. Import
TooltipPayloadEntry and TooltipPayload from vccs to type your own content.
Tooltip slots
| Slot | Props | Description |
|---|---|---|
#content | { active, payload, label, coordinate, accessibilityLayer } | Full tooltip content |
#cursor | Shape-specific SVG props | Custom cursor element. Receives Cross props for ScatterChart, Rectangle props for BarChart, Sector props for radial charts, Curve props for others. |
<script setup lang="ts">
import { ref } from 'vue'
import { Tooltip } from 'vccs'
const activePoint = ref<number | null>(null)
</script>
<template>
<Tooltip v-model:active-index="activePoint" />
</template>
Multiple Tooltip components share selection. The first owns interaction settings; each can customize its presentation. Only one may bind active-index; conflicting bindings warn in development and the first controls selection. See Events and v-model for index order and control precedence.