Skip to main content


Defines the structure and content of a subDomain


A subDomain is a time range, each represented by a cell in the calendar.

Taking the month/day example above, there is 6 month domains, each having a varying number of days subDomain, months having a different number of days.

Given a domain type and a time window, a Template generates a collection of subDomains, and defines how they are arranged on a x/y axis.

This template is then consumed by the calendar in order to draw the given subDomain cells.

When to use

By default, CalHeatmap ships with the year, month, week, day, xDay, ghDay, hour and minute templates.

Each of these templates are pretty basic, but will be enough for most use cases.

You can create and use a custom template if you wish to:

  • change the number of columns and rows (ex: all subDomains on same row)
  • change the time interval of a subDomain (ex: each subDomain equal 5min)
  • exclude some time window (ex: showing only weekdays)

How to use

Creating a template

A template is a javascript function taking 2 arguments and returning a TemplateResult.

type Template = function(DateHelper: DateHelper, options: Options) {
return TemplateResult;


  • DateHelper: a Datehelper object, also used internally by the calendar for all date related computation. You should always rely on this helper whenever possible for date computation consistency.
  • Options: the Options object

Return value

type TemplateResult = {
name: string,
parent?: string,
rowsCount: (ts: number) => number,
columnsCount: (ts: number) => number,
mapping: (startTimestamp: number, endTimestamp: number) => SubDomain[],
extractUnit: (ts: number) => number,


Name of the subDomain type.

Will be used by subDomain.type options, and child template.


Name should be unique


Parent template's name

Optional, set the name of another template to inherit its options.


Total number of rows

This number may vary depending on the domain type.

Example from the hour template

rowsCount: ts => {
const TOTAL_ITEMS = 24;
const ROWS_COUNT = 6;
const { domain } = options;

switch (domain.type) {
case 'week':
return (TOTAL_ITEMS / ROWS_COUNT) * 7;
case 'month':
return (
(domain.dynamicDimension ? : 31)
case 'day':


Total number of columns

This number may vary depending on the domain type.


Function returning an array of SubDomain, used to populate each domain in the calendar.

A subDomain have 3 main properties:

type SubDomain = {
t: number,
x: number,
y: number,
  • t: the subDomain timestamp, rounded to the start of the time range

  • x: the row index of the cell

  • y: the column index of the cell

  • Rows are indexed from top to bottom, with the top one being 0.

  • Columns are indexed from left to right, with the left one being 0.


Function returning the start of the subDomain time range.

This function is used to bind your data to a subDomain


  • If each subDomain is a 5min range, the timestamp for 9:18AM should return the timestamp for 9:15AM
  • If each subDomain is a weekday, the function should return the timestamp for the start of that day (00:00AM), and return null for a weekend.

Take a look at the built-in templates on the github repository, for real-world examples.

Real world Example

Quarter subDomain template

Each subDomain represent 3 months.

const quarterTemplate = function (DateHelper) {
return {
name: 'quarter',
rowsCount() {
return 1;
columnsCount() {
return 4;
mapping: (startDate, endDate, defaultValues) =>
DateHelper.intervals('quarter', startDate,
(d, index) => ({
t: d,
x: index,
y: 0,
extractUnit(d) {

Days subDomain, with all days on the same row

Using day template as parent.

const sameRowDayTemplate = function (DateHelper) {
return {
name: 'day_same_row',
parent: 'day',
rowsCount() {
return 1;
columnsCount() {
return 31;
mapping: (startDate, endDate, defaultValues) =>
DateHelper.intervals('day', startDate,
(d, index) => ({
t: d,
x: index,
y: 0,
// Missing extractUnit property, will be inherit from parent
const cal = new CalHeatmap();
range: 1,
domain: { type: 'month' },
subDomain: { type: 'day_same_row' },

Days subDomain, showing only the weekdays

See Showcase