chartjs-plugin-zoom

Zoom and pan plugin for Chart.js, adding drag, wheel, and pinch gesture navigation to any chart.

Library
npm
v2.2.0
623 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
80 /100 Excellent
Development Activity 84
Maintenance 72
Community 84
Maturity 60
Momentum 20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
83 /100 Excellent
Architecture 85
Code Quality 88
Innovation 72
Learning Curve 85

chartjs-plugin-zoom is the official interaction plugin for Chart.js, adding zoom and pan behavior to any chart type without extra rendering. It plugs directly into the Chart.js plugin lifecycle (start/beforeUpdate/beforeDraw/stop hooks), listening for mouse wheel, click-and-drag, and Hammer.js-powered pinch gestures, then rewrites the affected scale’s min/max and calls chart.update() to redraw.

Because it targets the Chart.js scale API instead of a fixed chart type, it works across linear, logarithmic, category, and time scales, and exposes a small imperative API (chart.zoom(), chart.pan(), chart.resetZoom(), chart.getZoomLevel()) alongside declarative plugin options for wiring zoom/pan into dashboards, monitoring UIs, and any chart where users need to inspect a narrow slice of a larger dataset.

What You Get

  • Mouse wheel zoom with configurable speed and modifier-key gating
  • Drag-to-zoom rectangle selection with customizable border/background styling
  • Pinch-to-zoom and touch panning via Hammer.js gesture recognition
  • Programmatic pan/zoom API (chart.pan(), chart.zoom(), chart.zoomScale(), chart.resetZoom())
  • Per-axis zoom/pan limits (min, max, minRange) to bound how far a user can navigate
  • Lifecycle callbacks (onZoom, onZoomComplete, onZoomStart, onZoomRejected, onPan, onPanComplete) for hooking into every stage of an interaction

Common Use Cases

  • Exploring dense time-series data (metrics, stock prices, sensor logs) by zooming into a narrow time window
  • Letting dashboard users drag-select a region of interest on a chart to inspect it more closely
  • Adding pinch-to-zoom navigation to charts embedded in mobile/touch web apps
  • Constraining how far users can zoom/pan out of a dataset’s meaningful range with scale limits
  • Resetting a zoomed chart back to its original view via a toolbar button using resetZoom()

Under The Hood

Architecture Chart.js registers this as a plugin object exported from src/index.ts, implementing lifecycle hooks (start, beforeUpdate, beforeDatasetsDraw/afterDatasetsDraw/beforeDraw/afterDraw, stop) defined in src/plugin.ts. State is centralized per-chart in src/state.ts, holding options, drag state, pan deltas, and original/updated scale limits. Core zoom/pan math lives in src/core.ts (zoom, zoomRect, zoomScale, pan, resetZoom, getZoomLevel, isZoomedOrPanned), delegating actual scale mutation to per-scale-type functions registered in src/scale.types.ts (indexed by scale.type, with a default fallback) — this indirection is what lets the plugin support category, linear, logarithmic, and time scales uniformly. Input handling is fully separated into src/handlers.ts (native mouse/wheel/keyboard DOM listeners, added and removed dynamically based on enabled options) and src/hammer.ts (touch gesture recognition via Hammer.js, restarted whenever relevant options change). This is a clean layered design: plugin.ts orchestrates the lifecycle, handlers/hammer.ts capture raw input, core.ts translates input into scale changes, scale.types.ts encapsulates per-scale-type math, and state.ts holds the mutable per-chart state — extending the core zoom algorithm would mainly touch core.ts and scale.types.ts, not the input-handling layer.

Tech Stack Written in TypeScript 5.0 and bundled with Rollup 4 (via @rollup/plugin-swc, plugin-commonjs, plugin-node-resolve, and plugin-terser) into CJS, ESM, and minified builds, with declaration files emitted separately via tsc. It peer-depends on chart.js (>=3.2.0, developed against ^4.x) and hard-depends on hammerjs for touch gesture recognition, reusing chart.js/helpers utilities (isNumber, sign, getRelativePosition, _isPointInArea) rather than reimplementing geometry helpers. The documentation site is built with VuePress plus typedoc-plugin-markdown, generating published API docs directly from the TSDoc comments on the option interfaces.

Code Quality Testing is extensive and multi-layered: Jasmine unit tests with c8 coverage, Karma browser tests (karma-chrome-launcher, karma-firefox-launcher, karma-rollup-preprocessor) that exercise real DOM/canvas behavior, and dedicated visual-regression fixtures under test/fixtures/{pan,zoom} that pair recorded chart configs with reference PNG screenshots. A separate test-types script type-checks a standalone exports.ts against the public API surface. ESLint (eslint-config-chartjs, typescript-eslint) lints source, tests, docs, and even markdown/HTML samples, and CI runs lint, typecheck, build, and the full test suite on both Ubuntu and Windows for every change. Error handling favors explicit console.warn deprecation notices over silent behavior changes, and the codebase consistently uses small pure functions over class hierarchies.

API Design The public surface is deliberately declarative-first — wheel, drag, and pinch zoom can all be enabled purely through a zoom/pan/limits options object on options.plugins.zoom, with zero imperative code required for the common case. For programmatic control, the plugin binds a small, chart.js-idiomatic API directly onto the Chart instance (chart.zoom(), chart.pan(), chart.resetZoom(), chart.getZoomLevel()) rather than exposing a separate controller object, so it reads like a native Chart.js method rather than a bolted-on extension. Every option is typed through documented TypeScript interfaces (ZoomPluginOptions, ZoomOptions, PanOptions) whose TSDoc comments double as the published documentation, and centralized defaults mean most integrations only need to override a handful of fields. This follows Chart.js’s own plugin and typing conventions closely rather than introducing a novel pattern, but it executes that convention with very low boilerplate for consumers.

Used by 6 apps in this directory

Go
83%
MIT

Gitea

Developer Tools · Devops · Project Management

58,194

Self-hosted DevOps in a single Go binary — Git hosting, GitHub Actions-compatible CI/CD, and 30+ package registries without any SaaS dependency.

View details
93
Repo Health
79
Technical
64
Dependency
Built with
Go 83%
Updated 5 days ago
Scala
63%
AGPL 3.0

lila (Lichess)

Community

18,776

The forever-free, ad-free, open-source chess server powering millions of real-time games, AI analysis, puzzles, and tournaments worldwide.

View details
89
Repo Health
80
Technical
76
Dependency
Built with
Scala 63%
TypeScript 26%
Updated 5 days ago
Vue
49%
MIT

Mixpost

Marketing · Social Media

3,738

Self-host your own social media scheduler and publish to 11 platforms without subscriptions or data lock-in.

View details
50
Repo Health
64
Technical
71
Dependency
Built with
Vue 49%
PHP 44%
Updated 6 months ago
TypeScript
91%
AGPL 3.0

PeerTube

Social Media

15,340

A federated, ActivityPub-based video hosting platform built by Framasoft — self-hostable instances interconnect into a network with no vendor lock-in, P2P-assisted streaming, and no ads.

View details
96
Repo Health
75
Technical
70
Dependency
Built with
TypeScript 91%
Updated 1 weeks ago
Python
55%
Other

PostHog

Ab Testing Experimentation · Analytics · Developer Tools

39,975

The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.

View details
92
Repo Health
80
Technical
65
Dependency
Built with
Python 55%
TypeScript 36%
Updated 5 days ago
Rust
32%
Other

Windmill

Automation · Developer Tools

18,043

Turn scripts into webhooks, workflows, and auto-generated UIs — the fastest self-hostable workflow engine, 13x faster than Airflow.

View details
91
Repo Health
82
Technical
65
Dependency
Built with
Rust 32%
TypeScript 24%
Svelte 22%
Updated 5 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers