chartjs-chart-matrix
A Chart.js module that adds a matrix chart type for rendering heatmaps and grid-based visualizations.
Repository Health
Technical Analysis
chartjs-chart-matrix extends Chart.js (v3 and v4) with a new matrix dataset type for rendering data as a grid of colored, sizeable rectangles instead of bars, lines, or points. It registers a MatrixController and MatrixElement directly into Chart.js’s own component registry, so consumers opt in with a single import and type: 'matrix' in their chart config — no separate rendering pipeline or canvas management to learn.
Each cell in the grid maps to an {x, y, v} data point and supports independently scriptable width, height, anchor position, background color, and per-side border radius/width, making it a natural fit for heatmaps, confusion matrices, correlation grids, and availability/occupancy calendars. The library ships full TypeScript typings that augment Chart.js’s own ChartTypeRegistry, so the matrix type gets the same autocomplete and type-checking as any built-in Chart.js chart type.
What You Get
- A
matrixdataset type registered into Chart.js via a single import (Chart.register()happens automatically) - Per-cell width, height, and anchor (
anchorX/anchorY) options that can be static values or scriptable callbacks driven by chart area size - Rounded-rectangle cell rendering with independent per-side border widths and radius
- Default linear x/y scale overrides with a reversed y-axis, matching conventional matrix/heatmap layouts
- Full TypeScript module-augmentation typings so
type: 'matrix'is type-checked like a built-in Chart.js chart type - Built-in hit-testing and tooltip positioning per cell (
inRange,inXRange,inYRange,getCenterPoint)
Common Use Cases
- Heatmaps for temperature, website traffic, or performance-monitoring dashboards
- Confusion matrices for visualizing machine-learning classification results
- Availability/occupancy grids for scheduling and booking interfaces
- Correlation matrices showing pairwise relationships between dataset variables
Under The Hood
Architecture
The package registers MatrixController and MatrixElement into Chart.js’s own DatasetController/Element base classes and component registry (Chart.register() in src/index.ts), following the exact controller/element pattern Chart.js itself uses for built-in chart types. MatrixController.updateElements() (src/controller.ts) pulls pixel positions from the chart’s linear x/y scales and delegates per-cell anchor resolution to module-level resolveX/resolveY helpers, while MatrixElement.draw() (src/element.ts) renders each cell as a rounded rect via Chart.js’s own addRoundedRectPath helper, using boundingRects() (src/helpers.ts) to compute inner/outer boxes for independent per-side border widths. Hit-testing (inRange/inXRange/inYRange) is centralized in helpers.ts rather than duplicated per method, keeping the controller/element wiring thin and the geometry math isolated and independently testable.
Tech Stack
Written in strict-mode TypeScript targeting ES2022, with chart.js >=3.0.0 as the only peer dependency (works across Chart.js v3 and v4). Built with Rollup using @rollup/plugin-swc for fast TypeScript compilation, emitting UMD (CommonJS + minified) and ESM bundles plus jsdelivr/unpkg fields for direct CDN use. The documentation site is a static Astro + Starlight build. Linting runs through Biome extending the author’s shared @kurkle/configs config (used consistently across the author’s other Chart.js chart-type plugins), and releases are automated via semantic-release.
Code Quality
The project tests at two levels: native TypeScript unit tests (element.test.ts, helpers.test.ts) using Jasmine-style specs with jasmine.createSpy canvas-context mocks, and browser-level Karma specs (test/specs/controller.spec.js) that exercise the controller against real Chart.js instances via chartjs-test-utils. Coverage is measured with c8 (text + lcov reporters) and enforced through a SonarCloud quality gate wired into CI (.github/workflows/main-ci.yml, pr-ci.yml). TypeScript strict mode is enabled with noUnusedLocals, noImplicitReturns, and strictBindCallApply, and the package ships an ambient chart.js module augmentation giving downstream consumers typed matrix dataset config out of the box.
API Design
The public surface is deliberately minimal: importing the package self-registers the matrix type as a side effect, so consumers just set type: 'matrix' in a chart config with per-cell width/height/anchorX/anchorY options — including scriptable callback options via ScriptableAndArrayOptions — with no manual registration boilerplate. The types/index.esm.d.ts module augmentation extends Chart.js’s own ChartTypeRegistry, so matrix gets the same autocomplete and type-checking as a built-in chart type with no separate type import required. This mirrors the integration ergonomics of the author’s sibling Chart.js chart-type plugins (chartjs-chart-treemap, chartjs-chart-sankey) — a well-executed, conventional integration pattern rather than a novel rendering algorithm.