Calendar Heatmap

January 26, 2026 ยท View on GitHub

This project is not actively maintained

Calendar Heatmap

A heatmap representing time series data, inspired by GitHub's contribution chart.

Reusable D3.js Calendar Heatmap chart

Configuration

PropertyUsageDefaultRequired
dataChart datanoneyes
selectorDOM selector to attach the chart tobodyno
widthChart width (grid + legend)750no
heightChart height (grid)110no
cellSizeDay cell size in pixels (before padding)11no
cellPaddingGap between day cells in pixels2no
fitWidthAuto-resize cell size to fit the provided widthfalseno
minCellSizeMinimum cell size when fitWidth is true6no
maxCellSizeMaximum cell size when fitWidth is true18no
legendWidthLegend area width150no
legendStepsNumber of legend swatches4no
legendGapGap between legend swatches2no
legendOffsetVertical spacing between grid and legend8no
maxMaximum countmax found in datano
startDateDate to start heatmap at1 year agono
dateParserCustom function to parse date inputsnew Date(...)no
weekStartWeek start day ('sunday' or 'monday')'sunday'no
colorRangeMinimum and maximum chart gradient colors['#D8E6E7', '#218380']no
tooltipEnabledOption to render a tooltiptrueno
formattersFormatting hooks for labels, tooltip, legend, and aria labels{}no
labelsControl visibility and spacing for day/month labels{}no
legendEnabledOption to render a legendtrueno
onClickcallback function on day click events (see example below)nullno
onHovercallback function on day hover eventsnullno
onLeavecallback function on day mouse leave eventsnullno
onFocuscallback function on day focus eventsnullno
onBlurcallback function on day blur eventsnullno
accessibilityTableRender an accessible, screen-reader-only table of all valuestrueno
ariaLabelAccessible chart label'Calendar heatmap'no
ariaDescriptionAccessible chart descriptionauto-generatedno

Installation

npm install @goujon/calendar-heatmap

Usage

1: Import calendar-heatmap and its styles

import calendarHeatmap from '@goujon/calendar-heatmap';
import '@goujon/calendar-heatmap/calendar-heatmap.css';

2: Format the data so each array item has a date and count property. As long as new Date() can parse the date string it's ok, or provide a custom dateParser. Note - all data should be rolled up into daily bucket granularity.

3: Configure the chart and render it

// chart data example
var chartData = [{
  date: valid Javascript date object,
  count: Number
}];
var chart1 = calendarHeatmap()
              .data(chartData)
              .selector('#chart-one')
              .colorRange(['#D8E6E7', '#218380'])
              .tooltipEnabled(true)
              .onClick(function (data) {
                console.log('onClick callback. Data:', data);
              });
chart1();  // render the chart
var chart1 = calendarHeatmap()
              .data(chartData)
              .selector('#chart-one')
              .ariaLabel('Team activity heatmap')
              .ariaDescription('Daily activity for the last 12 months.')
              .formatters({
                ariaLabel: function (date, count) {
                  return date.toDateString() + ': ' + count + ' contributions';
                }
              });
chart1();

custom tooltip formatting

var chart1 = calendarHeatmap()
              .data(chartData)
              .formatters({
                tooltip: function (date, count) {
                  var unit = count === 1 ? 'contribution' : 'contributions';
                  return count + ' ' + unit + ' on ' + date.toDateString();
                }
              });
chart1();  // render the chart

responsive sizing + labels

var chart1 = calendarHeatmap()
              .data(chartData)
              .width(700)
              .fitWidth(true)
              .minCellSize(7)
              .maxCellSize(12)
              .labels({
                day: { interval: 1, start: 0 },
                month: { padding: 14 }
              });
chart1();

Pull Requests and issues

...are very welcome!

Build (TypeScript)

npm run build

Tests

npm run test

Releases

This repo uses Changesets for versioning and publishing.

npm run changeset
npm run version
npm run release

Monorepo Layout

This repository is a workspace with two packages:

  • packages/calendar-heatmap (@goujon/calendar-heatmap)
  • packages/react-calendar-heatmap (@goujon/react-calendar-heatmap)

React Package (Preview)

npm install @goujon/react-calendar-heatmap
import { CalendarHeatmap } from '@goujon/react-calendar-heatmap';
import '@goujon/calendar-heatmap/calendar-heatmap.css';

Demo

npm run demo

This starts a local dev server and opens the showcase page.