Charts - Zoom & Pan
Add interactive zoom and pan to cartesian charts with mouse wheel, drag-to-select, shift-pan, touch pinch, and programmatic control.
#Usage
import { ChartNavigator, ChartSvg, ChartZoom } from '@primeui/vue-chart';<ChartSvg>
<!-- series and axes -->
<ChartZoom />
</ChartSvg>Zoom and pan are supported on Line, Bar, Scatter, and Candlestick charts. Add ChartZoom to enable wheel zoom, drag-to-select, and shift-pan; remove it and the chart is static. A reset button appears when the chart is zoomed. Add ChartNavigator alongside for a mini overview with a range selector.
#Basic
Add ChartZoom to enable zooming on the X axis. Three interactions are enabled by default. Scroll the mouse wheel to zoom in and out, drag to draw a selection rectangle and zoom to that region, and hold Shift + drag to pan the view. A reset button shows up when the chart is zoomed; click it or double-click the chart to go back to the original view. Set resetButton to false to hide the button and use zoomRef for programmatic reset instead.
#Zoom Mode
Set mode to control which axes zoom. 'x' zooms only the category or time axis (default), 'y' zooms only the value axis, and 'xy' zooms both at once. The xy mode is handy for scatter charts where both dimensions are continuous.
#Wheel Zoom
Wheel zoom is enabled by default. Set wheel to false to disable it, or pass a ZoomWheelConfig object to customize speed and require a modifier key. Set modifierKey to 'ctrl' to avoid accidental zoom while scrolling a page.
#Drag to Zoom
Drag-to-zoom is enabled by default. Drag across the chart to draw a selection rectangle and zoom to that region. Set drag to false to disable it, or require a modifier key such as 'alt' to avoid conflicting with pan.
#Pan
Hold Shift and drag to pan the view. This is the default modifier key so that a regular drag still triggers zoom selection. Set pan to false to disable panning entirely, or pass a ZoomPanConfig to change the modifier key. Omit modifierKey entirely to make drag always pan. Set drag: false separately to disable drag-to-zoom.
#Zoom and Pan Buttons
Set zoomButtons to true to render a control cluster in the corner of the chart: zoom out, zoom in, and, where a drag-pan gesture exists, pan left and pan right. The reset button joins the same cluster.
The buttons make zooming and panning reachable without a drag gesture, which is what WCAG 2.5.7 (Dragging Movements) requires, and reachable by keyboard alone, which is what WCAG 2.1.1 (Keyboard) requires. They are opt-in, so a chart that offers dragging without enabling them leaves both routes closed.
The pan pair appears only where a drag-pan gesture exists, that is when pan is enabled or a ChartNavigator is mounted. Adding a navigator therefore changes what the cluster contains, because the navigator window is itself dragged to pan.
Every button takes its accessible name from the text catalogue, so it is translated wherever a locale is registered. A button whose action becomes unavailable is marked aria-disabled and stays in the tab order rather than disappearing, which keeps focus where the user left it. Each press announces the resulting range to screen readers.
#Touch Pinch
Pinch-to-zoom is enabled by default on touch devices. Set pinch to false to disable it.
#Zoom Limits
Set limits to restrict how far the user can zoom in. Use min and max to fix the outer domain boundary. This stops the user from zooming outside the data range. Use minRange to set the minimum visible window size, which prevents over-zooming on time series.
#Zoom Change Event
Set onZoomChange to receive the current zoom state whenever the view changes. The callback receives a ZoomState object with the current X and Y windows. Use this to sync zoom state to external state, URL params, or other charts.
#Programmatic Control
Pass a ref to zoomRef to control zoom programmatically. Call setZoomState to jump to a specific range, resetZoom to return to the original view, and getZoomState to read the current state at any time without a re-render.
#Navigator
Add ChartNavigator alongside ChartZoom to display a mini overview chart below the main chart with a draggable selection window. The navigator and zoom stay in sync.
For full configuration see Navigator.
#API
#ChartZoom
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'x' | 'y' | 'xy' | 'x' | Which axes to zoom |
wheel | boolean | ZoomWheelConfig | true | Mouse wheel zoom. false to disable, object for fine control |
drag | boolean | ZoomDragConfig | true | Drag-to-select zoom. false to disable, object for fine control |
pan | boolean | ZoomPanConfig | true | Drag-to-pan. false to disable, object for fine control |
pinch | boolean | ZoomPinchConfig | true | Touch pinch-to-zoom. false to disable, object for fine control |
limits | { x?: ZoomLimits; y?: ZoomLimits } | - | Per-axis zoom limits |
onZoomChange | (state: ZoomState) => void | - | Fires when the zoom range changes |
zoomRef | ref<ZoomHandle> | - | Ref for programmatic zoom control |
resetButton | boolean | { text?: string; className?: string } | true | Reset zoom button shown when the chart is zoomed. false hides it, object customizes label and CSS class |
zoomButtons | boolean | ZoomButtonsConfig | false | Zoom and pan buttons rendered beside the reset button. true renders the cluster, object tunes the step sizes and CSS class |
#ZoomWheelConfig
| Prop | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable wheel zoom |
speed | number | 0.1 | Zoom speed per scroll tick. Higher is faster |
modifierKey | 'ctrl' | 'alt' | 'shift' | 'meta' | - | Require this key to activate wheel zoom |
#ZoomDragConfig
| Prop | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable drag-to-zoom |
modifierKey | 'ctrl' | 'alt' | 'shift' | 'meta' | - | Require this key to activate drag zoom |
#ZoomPanConfig
| Prop | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable panning |
modifierKey | 'ctrl' | 'alt' | 'shift' | 'meta' | 'shift' | Modifier key to activate pan. Hold while dragging |
#ZoomButtonsConfig
| Prop | Type | Default | Description |
|---|---|---|---|
factor | number | 1.25 | Zoom step per press. Proportional, so the number of presses does not depend on the series length |
panStride | number | 0.1 | Pan step per press, as a fraction of the visible window |
className | string | - | Extra CSS class applied to every button in the cluster |
#Styling the buttons
className applies to every button in the cluster. Colours resolve from CSS custom properties, so a
class rule can override them.
| Token | Default (light / dark) | Applies to |
|---|---|---|
--p-chart-zoom-button-bg | rgba(255,255,255,0.92) / rgba(39,39,42,0.92) | Background, both states |
--p-chart-zoom-button-color | neutral-80 ramp step | Label, available state |
--p-chart-zoom-button-border-color | #808080 | Border, available state |
--p-chart-zoom-button-disabled-color | neutral-60 ramp step | Label, unavailable state |
--p-chart-zoom-button-disabled-border-color | rgba(0,0,0,0.08) / rgba(255,255,255,0.1) | Border, unavailable state |
--p-chart-zoom-button-radius | 4px | Corner radius |
Values with two entries resolve through light-dark() and follow the page's color-scheme. The
border is a single value because at the 3:1 threshold the ranges that work against a light and a dark
background overlap; at the 4.5:1 threshold required for text they do not, which is why the label
needs a pair.
.my-zoom-buttons {
--p-chart-zoom-button-bg: #1f2937;
--p-chart-zoom-button-color: #f9fafb;
--p-chart-zoom-button-disabled-color: #9ca3af;
}The 24x24 minimum target size (WCAG 2.5.8) is not themeable and holds whatever these tokens are set to. Contrast cannot be held the same way, because it is a relationship between the label and the background rather than a property of either. The defaults meet 4.5:1 for the label (WCAG 1.4.3) and 3:1 for the button boundary (WCAG 1.4.11) in both modes. Overriding either half of a pair moves responsibility for meeting those ratios to the override.
#ZoomPinchConfig
| Prop | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable touch pinch-to-zoom |
#ZoomLimits
Set on limits.x or limits.y to restrict the zoom range on that axis.
| Field | Type | Description |
|---|---|---|
min | number | 'original' | Minimum allowed domain start. 'original' locks the boundary to the initial data domain, preventing panning before the first data point |
max | number | 'original' | Maximum allowed domain end. 'original' locks the boundary to the initial data domain, preventing panning beyond the last data point |
minRange | number | Minimum visible window size to prevent over-zooming. When not set, computed as 5× the smallest data interval so the user cannot zoom into empty space between points |
#ZoomHandle
Obtained via zoomRef. Use for programmatic zoom control.
| Method | Signature | Description |
|---|---|---|
setZoomState | (state: ZoomState) => void | Jump to a specific zoom range. Pass { x: null, y: null } to reset |
resetZoom | () => void | Reset to the original unzoomed view |
getZoomState | () => ZoomState | Read current zoom state. Always up-to-date, never stale |
#ZoomState
| Field | Type | Description |
|---|---|---|
x | { min: number; max: number } | null | Current X axis window. null when not zoomed on X |
y | { min: number; max: number } | null | Current Y axis window. null when not zoomed on Y |