Skip to main content

Template

Defines the structure and content of a subDomain

Introduction

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;
}

Arguments

  • 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

Name of the subDomain type.

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

caution

Name should be unique

parent

Parent template's name

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

rowsCount

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 (
(TOTAL_ITEMS / ROWS_COUNT) *
(domain.dynamicDimension ? DateHelper.date(ts).daysInMonth() : 31)
);
case 'day':
default:
return TOTAL_ITEMS / ROWS_COUNT;
}
};

columnsCount

Total number of columns

This number may vary depending on the domain type.

mapping

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.

extractUnit

Function returning the start of the subDomain time range.

This function is used to bind your data to a subDomain

Example

  • 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.
tip

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, DateHelper.date(endDate)).map(
(d, index) => ({
t: d,
x: index,
y: 0,
...defaultValues,
})
),
extractUnit(d) {
return DateHelper.date(d).startOf('quarter').valueOf();
},
};
};

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, DateHelper.date(endDate)).map(
(d, index) => ({
t: d,
x: index,
y: 0,
...defaultValues,
})
),
// Missing extractUnit property, will be inherit from parent
};
};
const cal = new CalHeatmap();
cal.addTemplates(sameRowDayTemplate);
cal.paint({
range: 1,
domain: { type: 'month' },
subDomain: { type: 'day_same_row' },
});

Days subDomain, showing only the weekdays

See Showcase