<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
Or you can download it and use
it locally
<link rel="stylesheet" href="path/to/css/cal-heatmap.css" />
<script type="text/javascript" src="path/to/cal-heatmap.min.js"></script>
bower install cal-heatmap
Then continue with step 3 of the classic way to include it in your application
jam install cal-heatmap
Then continue with step 3 of the classic way to include it in your application
Just include the following lines in your page head
section:
<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.min.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.css" />
Cal-Heatmap is compatible with AMD module.
Creating your first calendar is easy
<div id="cal-heatmap"></div>
<script type="text/javascript">
var cal = new CalHeatMap();
cal.init({});
</script>
By default, calling init()
with an empty object will
initialize a blank calendar of 12 hours, with 60 minutes each, starting
from the current hour.
Read the data section for how to fill the calendar with your own data, and the presentation section for the calendar layout.
Cal-Heatmap works on most modern browsers supporting SVG, and was tested on
Calendar can be customized by setting various options in the object
passed to init()
.
#cal-heatmap
DOM node to insert the calendar in.
All CSS3 selectors can be used as a Selector String, so you can, for example, select by:
tag | cal.init({ itemSelector: "div"}) |
ID | cal.init({ itemSelector: "#id"}) |
class | cal.init({ itemSelector: ".class"}) |
attribute | cal.init({ itemSelector: "[title=hi]"}) |
containement | cal.init({ itemSelector: "div > span + b"}) |
If the Selector String is returning multiple node, the first one will be used.
If you already have a reference to a DOM Element, you can directly use it.
getElementByID() |
cal.init({ itemSelector: document.getElementByID("myId")
});
|
getElementsByClassName() |
cal.init({ itemSelector:
document.getElementsByClassName(".class")[0] });
|
querySelector() |
cal.init({ itemSelector: document.querySelector(".class")
});
|
jQuery Selector | cal.init({ itemSelector: $(".class")[0] }); |
d3.js selector |
cal.init({ itemSelector: d3.select(".class")[0][0] });
|
hour
Type of domain
Valid domains:
min
Type of subDomain
Valid subDomains:
By default, all subdomain cells are read from top to bottom, and from left to right. The x_ variants are used to rotate the reading order to left to right, then top to bottom.
day
subDomain
x_day
subDomain
When not set, Cal-heatmap will decide the most appropriate subDomain for the current type of domain.
Not all subDomains can be used with a domain.
Only "responsible" domain/subDomain couple are available,
e.g: {domain: "year", subDomain: "min"}
will
not work.
(Because painting one half million svg nodes will probably crash your
browser ...)
subDomain must always be smaller than domain.
12
Number of domain to display
10
Size of each subDomain cell, in pixel.
Default cellSize of 10px
cellSize of 15px
2
Space between each subDomain cell, in pixel.
Default cellPadding of 2px
cellPadding of 5px
0
subDomain cell's border radius, for rounder corner, in pixel.
Default cellRadius of 0px
cellRadius of 5px
Set shape-rendering
value to other than
crispedges
for better rendering.
2
Space between each domain, in pixel.
Default domainGutter of 2px
domainGutter of 10px
[0, 0, 0, 0]
Margin around each domain, in pixel.
Ordered like in CSS (top, right, bottom, left), it also accepts CSS like values:
0
and [0]
are equivalent to
[0, 0, 0, 0]
[0, 1]
is equivalent to [0, 1, 0, 1]
[0, 1, 2]
is equivalent to [0, 1, 2, 1]
No margin
10px margin
domainMargin
is specially useful when coupled with the
domain highlighting function.
true
Whether to enable domain dynamic width and height.
Some domain>subdomain couple, like month>days, doesn't always have the same number of subDomain cells. Some months have 6 weeks, some only 4.
With dynamic dimension enabled, the domain width and height will be adjusted to fit the domain content, whereas when it's disabled, all domains will have the same dimension : the biggest.
Dynamic dimensions enabled.
Browse with the next/previous buttons, and note that the whole
calendar is also resized to fit the domains width
Dynamic dimensions disabled.
Notice that, sometimes, there's a
gap between domains, when the month has less than 6 weeks
false
To display the calendar vertically, with each domain one under the other
Default horizontal orientation
Vertical orientation
Use the x_
variant subDomain for a more natural reading
order.
For a smoother reading, see the
label
option to move the label
position on the side.
Position and alignment of the domain label.
It takes an object with up to 5 properties:
name | default | values | description |
---|---|---|---|
position | bottom | top, right, bottom, left | Position of the label, relative to the domain |
align | center | left, center, right | Horizontal align of the domain |
rotate | null | null, left, right | Rotation for a vertical label |
width | 100 | any integer | Only used when label is rotated, defines the width of the label |
offset | {x:0, y:0} | An object with x and y | More control about label positioning, if the default value does not fit your need, especially when label is rotated, or when using a big font-size. |
height | null | any integer |
3.1.1+
Height of the domain label in pixels.
If you want to remove the label, set
|
Default values are only for when label is positioned on bottom, without rotation.
Label on bottom, centered
Label on top, centered
Label on left
Label on right, with offset
Label on left, rotate left
Label on right, rotated left, with a bigger width
Label on right, rotate left
Label on right. rotate left, aligned right
Styling tips
Use .graph-label
to style the label.
null
Control the number of columns to split the domain dates into.
Each domain is split into an arbitrary number of columns (or rows
depending on the reading direction). You can overwrite that number with
colLimit
, and force all dates on the same line, or split
them into more columns.
That setting limit the maximum number of columns, and doesn't necessary means that each rows will contains that number of columns.
Default splitting, 4 columns with 6 hours each
All hours on the same line
null
Control the number of rows to split the domain dates into.
If rowLimit
and colLimit
are both used,
rowLimit
will be ignored.
7 days per column (default)
10 days per column
false
Whether to display a tooltip when hovering over a date.
Default title on hover
Tooltip on hover
new Date()
Starting date of the calendar
It doesn't have to be precise, the calendar will not start at that date, but at the first domain containing that date.
For the date: January 15, 2000 @15:36 :
Starting today
Starting January 15th, 2000
""
Data used to fill the calendar.
It can accepts either a string, or a json object
The string is interpreted as an URL to an API, which should be returning the data used to fill the calendar.
var cal = new CalHeatMap();
cal.init({
data: "http://localhost/datas.json"
});
The data must be formatted according to the expected
data format. In case it's not possible, you
should first set the correct
dataType
if it's not returning a
json response, then use the
afterLoadData()
to transform
the data into the expected format.
4 template strings are available to limit the scope of data returned by the API
Value | Description |
---|---|
{{t:start}} |
Timestamp of the first subDomain cell |
{{t:end}} |
Timestamp of the last subDomain cell |
{{d:start}} |
ISO-8601 formatted date of the first subDomain cell |
{{d:end}} |
ISO-8601 formatted date of the last subDomain cell |
The first time, the first subDomain cell will be the one in the first domain, and the last subDomain cell, the one in the last domain, so that, if your calendar have 5 domains, it'll get the data for the 5 domains.
For each subsequent call, like when loading new domains dynamically with
next()
and
previous()
, the first and last subDomain cell will only be the ones inside the
newly loaded domain.
var cal = new CalHeatMap();
cal.init({
start: new Date(2000, 0), // January, 1st 2000
range: 12,
domain: "year",
subDomain: "month",
data: "http://localhost/api?start={{d:start}}&stop={{d:end}}"
});
/*
{{d:start}} === 2000-01-01T00:00:00Z
{{d:end}} === 2000-12-31T23:59:59Z
=> Fetch 12 months
*/
cal.next(); // Load January 2001
/*
{{d:start}} === 2001-01-01T00:00:00Z
{{d:end}} === 2001-01-31T23:59:59Z
=> Fetch 1 month
*/
The object will be used to fill the calendar.
Again, if the object is not formatted according to the
expected format, use
afterLoadData()
callback to
transform it.
json
Engine used to parse the data.
Value | Description |
---|---|
json |
Interpret the data as json |
csv |
Interpret the data as csv |
tsv |
Interpret the data exactly like csv , but are delimited
with a tab character, instead of a comma.
|
txt |
Just return the data as a string |
var cal = new CalHeatMap();
cal.init({
data: "http://localhost/datas.csv",
dataType: "csv"
});
When using the txt
dataType, the data is returned as a
plain text. You have to use the
afterLoadData()
callback to
transform it to the expected data format.
false
Highlight selected subDomain cells.
Takes an array of Date object. Can also accepts the
now
string, equivalent to Date.now()
.
{highlight: "now"}
{highlight: ["now"]}
{highlight: ["now", new Date(2000, 1, 15)]}
{highlight: [new Date(2000, 1, 15)]}
{highlight: new Date(2000, 1, 15)}
Highlight current hour, and tomorrow at the same hour
Styling tips
The .highlight
class is used to style highlighted cells.
Additionally, a .now
is also applied when the highlighted
cells correspond to the current time.
Use rect.highlight
/rect.now
and
text.highlight
/text.now
to style the cell and
the text inside respectively.
See the domain highlighting section if you want to highlight the entire domain.
true
Whether to start the week on Monday, instead of Sunday.
First column is Monday
First column is Sunday
null
Lower limit of the domain navigation, preventing navigating beyond a certain date.
When set, calling previous()
will
only work only until the leftmost domain containing
minDate
. Like with start
, minDate
does not have to be precise, and just have to be
a date inside the domain.
previous()
will always return
true
, unless the domain containing
minDate
is reached, in which case,
it'll return false
.
Considering a calendar with month domain, and
day subDomain, let's set
minDate
to
January 25th, 2000. The last
previous()
call will load the
January domain, as January 25th is a subDomain inside the January
domain.
Calling previous()
again will do
nothing and just return false
, since the next incoming
domain is December, and January 25th is not a subDomain of the
December domain.
Bound the calendar from February to September
The
onMinDomainReached()
event is triggered when you've hit the leftmost domain allowed by
minDate
.
null
Upper limit of the domain navigation, preventing navigating beyond a certain date.
Same as minDate
, but for the upper limit. Refer to
minDate
documentation.
false
Whether to consider missing date:value couple in the data source as equal to 0.
By default, when the a date is not associated to a value, it's considered as null, and rendered as a no value cell.
You should ask yourself, if the API is not returning result for a date, is it because there is really no value associated to this date, or because it's supposed to be equal to 0, and it's skipped in order to save bandwidth ?
[10, 20, 30, 40]
Assign each range of values to a color.
legend
accepts an array of any number
of arguments, as long as they are number (even negative numbers), and in
ascendant order.
An array of N values (thresholds) will generate a legend of
N + 1 colors. Each colors correspond to a CSS class, formatted
like .q{n}
.
With [10, 20, 30, 40]
, you end up with 5 colors:
CSS Class | Range |
---|---|
.q1 |
Less than 10 |
.q2 |
Between 10 and 20 |
.q3 |
Between 20 and 30 |
.q4 |
Between 30 and 40 |
.q5 |
More than 40 |
By default, the CSS only come with 5 .q{n} class. You're free to add your own if needed, and modify the colors of the existing one.
Default legend
Float and negative legend values
Styling tips
.graph-rect
class is applied to all subDomain cells, and
used when the cell is not associated to a value.
Styling tips
.q0
will be applied to all dates with values == 0.
Styling tips
.qi
will be applied to all dates with "overflowing" values,
like negative values, when the legend is all positive.
Styling tips
Use the .q{n} + title + .subdomain-text
CSS selector to
change cell text style.
You can also generate the colors automatically without using CSS, refer
to legendColors
.
true
Whether to display the legend.
Legend
No legend
Legend can be added or removed after initialisation, by calling
showLegend()
and
removeLegend()
.
10
Size of the legend cells, in pixel.
Default legendCellSize of 10px
legendCellSize of 5px
2
Padding between each legend cell, in pixel.
Default legendCellPadding
legendCellPadding of 5px
[10, 0, 0, 0]
Margin around the legend, in pixel
Default legendMargin
Margin of 50px on top and left
bottom
Vertical position of the legend.
Value | Description |
---|---|
top |
Place the legend above the calendar |
center |
Place the legend on the calendar's side
Use with
|
bottom |
Place the legend below the calendar |
Default legendVerticalPosition
legend on top, with a legend margin-bottom of 10px
Legend on the left side
Legend on the right side
left
Horizontal position of the legend.
Value | Description |
---|---|
left |
Align the legend to the left |
center |
Center the legend |
right |
Align the legend to the right |
Default legendHorizontalPosition
legend align on the right
horizontal
Orientation of the legend.
Value | Description |
---|---|
horizontal |
Legend is displayed horizontally, from left to right |
vertical |
Legend is displayed vertically, from top to bottom |
legendOrientation
is best
used together with
legendHorizontalPosition
when the legend is positioned on the side.
Vertical legend on the left side
Vertical legend on the right side, on a vertical oriented calendar
null
Set of colors to automagically compute the heatmap colors.
Instead of relying on the CSS for your heatmap's colors, you can also set the heatmap's colors directly with cal-heatmap on initilialisation, or even dynamically change them after.
The legendColors
setting takes an object with the following
keys:
Key | Description | CSS equivalent |
---|---|---|
min |
Color of the smallest value on the legend | .q1 |
max |
Color of the highest value on the legend | .qx , where x is the highest number |
empty |
Optional Color for the dates with value == 0 | .q0 |
base |
Optional Base color of the date cell's | .graph-rect |
overflow |
Optional Color for the special value | .qi |
Colors can be defined using the hexadecimal notation
#FFFFFF
or its english equivalent name white
.
Other fancy function like hsl(350, 100%, 50%)
are
also accepted.
var cal = new CalHeatMap();
cal.init({
legendColors: {
min: "#efefef",
max: "steelblue",
empty: "white"
// Will use the CSS for the missing keys
}
});
When using only the mandatory min
and
max
keys, you can use an array [min, max]
,
instead of the whole object.
var cal = new CalHeatMap();
cal.init({
legendColors: ["#efefef", "steelblue"]
});
All the intermediate colors on the legend will be interpolated from the
min
and max
colors, using the
HCL interpolation.
All legend settings can be changed dynamically after calendar
initialisation, with setLegend()
.
["item", "items"]
Name of the entity you're representing on the calendar.
Takes an array of String, with the first index as singular form, and the second index, the plural form.
var cal = new CalHeatMap();
cal.init({
itemName: ["cat", "cats"]
});
For the lazy, you can also pass a simple string, ar a single element array, and it'll automatically guess the plural form, as long as it's the singular form plus the "s" suffix.
The 2 following examples are the same as the one above
var cal = new CalHeatMap();
cal.init({
itemName: "cat"
});
var cal = new CalHeatMap();
cal.init({
itemName: ["cat"]
});
Format of the title displayed when hovering a subDomain.
Takes an object with 2 properties:
Property name | Default value | Description |
---|---|---|
empty |
{date} |
Format of the title when there is no value associated to the date. |
filled |
{count} {name} {connector} {date} |
Format of the title when it's associated to a value |
Some template string are available, and enclosed in braces.
Template | Description |
---|---|
{name} |
Name of the entity represented in the calendar (see
itemName )
|
{count} |
The value associated to the date |
{date} |
The date of the cell. It's automatically formatted according to the
type of subDomain. See subDomainDateFormat to further customize that date
formatting.
|
{connector} |
An English preposition placed before a datetime (on Monday, at 15:00, etc..). Each subDomain have their own default connector, corresponding to the default date format. |
Format of the {date}
template string inside
subDomainTitleFormat
.
{date}
is by default formatted according to the subDomain
type.
month
subDomain, it'll return something like
January, 2000
week
subDomain, it'll return for example
Week #1
hour
subDomain, it'll return
20h, January 6th, 2000
subDomainDateFormat
can accepts any string with directive
accepted by
d3.time.format(), like "%Y-%m-%d".
As
d3.time.format()
will only output english dates, subDomainDateFormat
can
also accepts a function, with the subDomain date as argument.
var cal = new CalHeatMap();
cal.init({
subDomainDateFormat: function(date) {
return moment(date).format("LL"); // Use the moment library to format the Date
}
});
Format of the text inside a subDomain cell.
Disabled by default, you can display a text inside each subDomain cell.
Works exactly like subDomainDateFormat
, except that the
function takes the cell value as second argument.
Display the date in cell
Display the value in cell
Styling tips
Use .subdomain-text
in your CSS to style the text. Text is
centered horizontally and vertically, and can not by changed.
Format of the domain label.
Works exactly like
subDomainDateFormat
, and will format the domain label with any string accepted by
d3.time.format(), or a function.
Default label according to the domain type
Custom domain label
See
subDomainDateFormat
for
more infos on accepted values.
To not display the domain label, set
domainLabelFormat
to
""
(empty string). 3.1.1+
Formatting of the legend title, displayed when hovering a legend cell.
It takes an object with up to 3 properties:
Property | Default value | Description |
---|---|---|
lower | less than {min} {name} |
Formatting of the smallest (leftmost) value of the legend |
inner | between {down} and {up} {name} |
Formatting of all the value but the first and the last |
upper | more than {max} {name} |
Formatting of the biggest (rightmost) value of the legend |
Some template string are available, and enclosed in braces.
Template | Description |
---|---|
{name} |
Name of the entity represented in the calendar (see
itemName )
|
{min} |
The first value of the
legend array.
|
{max} |
The last value of the
legend array.
|
{down} |
The lower bound of a color |
{up} |
The upper bound of a color |
500
Animation duration, in milliseconds.
500ms
1.5 second
false
Will attach the previous()
event to
the specified element, on a mouse click, shifting the calendar one
domain back.
Targeting a simple #ID
Using a more complex Selector String
Then, let's go back to the previous domain.
If you want to shift by more than one domain, see the
previous()
method
See itemSelector
for details
about String Selector and Element type.
false
Will attach the next()
event to the
specified element, on a mouse click, shifting the calendar one domain
forward.
If you want to shift by more than one domain, see the
next()
method
See previousSelector
for an
example.
See itemSelector
for details
about String Selector and Element type.
cal-heatmap
The calendar instance namespace.
If you have more than one instance of Cal-Heatmap, you should assign each instance its own namespace, in order to isolate each instance event handler.
This will not work
var cal = new CalHeatMap();
cal.init({
nextSelector: "#next" // Attach #next onClick event to cal.next()
});
var cal2 = new CalHeatMap();
cal2.init({
nextSelector: "#next" // Attach #next onClick event to cal2.next(), overiding cal.next()
});
This will work
var cal = new CalHeatMap();
cal.init({
nextSelector: "#next",
// Attach #next.cal onClick event to cal.next()
itemNamespace: "cal"
});
var cal2 = new CalHeatMap();
cal2.init({
nextSelector: "#next",
// Attach #next.cal2 onClick event to cal2.next()
itemNamespace: "cal2"
});
Beside init()
, Cal-HeatMap also boast other methods to
control the behavior of the calendar.
Shift the calendar n domains back
n is optional, and by default is equal to 1.
var cal = new CalHeatmap();
cal.init({});
cal.previous();
See previousSelector
if you
wish to directly attach previous()
to an Element mouse
click event.
Shift the calendar n domains forward
n is optional, and by default is equal to 1.
var cal = new CalHeatmap();
cal.init({});
cal.next();
cal.next(5); // Move back by 5 domains
See nextSelector
if you
wish to directly attach next()
to an Element mouse click
event.
Jump the calendar to the specified date
This method will shift the calendar backward or forward, until the domain containing the specified date is visible.
Argument | Type | Description |
---|---|---|
Date |
Date |
The date to jump to. |
reset |
boolean |
Optional Default:
false
Whether to set the domain with the specified as the calendar's first domain. |
With reset
== false, jumpTo
will stop as
soon as the wanted date is visible
With reset
== true, jumpTo
will move the
wanted domain to the start of the calendar
Reset the calendar back to the start date
The following calendar will jump 5 domains forward immediatly on load. Use the Rewind button to reset to the initial start date.
Update the calendar with new data
Use update()
when you want to refresh the calendar with a
new set of data.
Particularly useful if you're filling the
calendar in realtime, or if you want to display a subset of the current
data.
Argument | Type | Description |
---|---|---|
data |
string |object |
Accept the same format as the
data option.
|
afterLoad |
boolean |function |
Optional Default:
true
Whether to execute the
It can also directly takes a function, in case your data can not
be converted with the
|
updateMode |
constant |
Optional Define how to insert the new data into the calendar. Accepted values are:
|
The updated data are not persisted across domain navigation. If the
domain was removed then reinserted after a navigation, all updates will
be lost, since it'll fetch the datasource given in
data
.
If you're using the Instance.RESET_ALL_ON_UPDATE
mode, you
can change data
to the new datasource,
to persist the change.
var cal = new CalHeatmap();
cal.init({
data: "user=Eric"
});
// Wrong way !
cal.update("user=Marc");
// Same as calling cal.update("user=Marc", true, cal.RESET_ALL_ON_UPDATE);
cal.next();
// => The new loaded domain contains data from Eric !
// Right way
cal.update("user=Marc");
cal.options.data = "user=Marc";
cal.next();
Toggling between 2 data sets
Increment a random date by 2
Set a random date to 1
Change the highlighed dates
Accepts the same arguments as the
highlight
option in
init()
.
var cal = new CalHeatMap();
cal.init({
highlight: new Date(2000, 0, 1) // Highlight January 1st
});
// I changed my mind, let's highlight January 2nd instead
cal.highlight(new Date(2000, 0, 2));
// Add January 5th to already highlighted dates
cal.highlight(cal.options.highlight.push(new Date(2000, 0, 5)));
Return the SVG source code with the appropriate CSS
The returned string code is valid and ready to be placed in a .svg file.
Change the legend settings and/or threshold
Can takes 2 optional arguments:
Value | Description |
---|---|
legend |
Same as legend : an array of thresholds
|
legendColors |
Same as legendColors : an object with the heatmap's colors, or an array of 2 colors
|
When called without arguments,
setLegend()
will just redraw the
legend.
var cal = new CalHeatMap();
cal.init({
legendVerticalPosition: "top",
legendHorizontalPosition: "left",
legendOrientation: "horizontal"
});
// Lets' move the legend on the right side, and rotate it by 90deg
cal.legendVerticalPosition: "center";
cal.legendHorizontalPosition: "right";
cal.legendOrientation: "vertical";
// Let's redraw the calendar to apply the settings
cal.setLegend();
Check the legend playground for example.
Remove the legend from the calendar
Settings are kept and you can re-add the legend with the same settings
using showLegend()
.
Check the legend playground for example.
Display the legend, if not already shown
Check the legend playground for example.
Remove the calendar from the DOM
destroy()
always return null
.
It can take a function as argument, that will be executed when the calendar is removed from the DOM, at the end of the animation.
Remember to self-assign the result of destroy()
to your
calendar instance, or it'll lead to a memory leak.
var cal = new CalHeatMap();
cal.init({}); // Creating the calendar
cal = cal.destroy(); // Remove the calendar from the DOM, and assign the 'cal' variable to `null`
Called after a mouse click event on a subDomain cell.
Styling tips
.hover_cursor
style is applied to all click-able cells.
Called after drawing the empty calendar, and before filling it with data.
Called after shifting the calendar one domain back.
The date
argument is the start date of the domain that was
added.
Called after shifting the calendar one domain forward.
The date
argument is the start date of the domain that was
added.
Called after drawing and filling the calendar.
Useful in case you're loading data via ajax, as it's loading data asynchronously. This event will wait for the ajax request to complete before triggering.
This event will only trigger once, on the initial
setup. See
afterLoadPreviousDomain
and
afterLoadNextDomain
for
callback events after a domain navigation.
Called after getting the data from source, but before filling the calendar.
This callback must return a json object formatted in the expected data format.
afterLoadData()
is used to do some works on the data,
especially when the data source is not returning data in the expected
format.
// datas is an array of object
var datas = [
{date: 946702811, value: 15},
{date: 946702812, value: 25},
{date: 946702813, value: 10}
]
var parser = function(data) {
var stats = {};
for (var d in data) {
stats[data[d].date] = data[d].value;
}
return stats;
};
/* Parser will output the object
{
"946702811": 15,
"946702812": 25,
"946702813": 10
}*/
var cal = new CalHeatMap();
cal.init({
data: datas,
afterLoadData: parser
});
Triggered after previous()
, when the incoming domain is containing
minDate
.
When the leftmost domain set by
minDate
is loaded into the calendar,
onMinDomainReached()
will be triggered with
true
as argument.
This event is useful if you want to disable your previous button, since there is no more previous domains to load.
In order to reverse the action,
onMinDomainReached()
will
be called with false
as argument after
next()
, only once, and only if the leftmost domain is not the lower limit
domain anymore.
Triggered after next()
, when the incoming domain is containing
maxDate
.
See onMinDomainReached()
.
Cal-Heatmap expects data in a JSON object in the following format:
{
"timestamp": value,
"timestamp2": value2,
...
}
All timestamp
are in seconds.
value
can be any number (integer or float).
If your API is not returning a JSON object, set the
dataType
option according to the
returned result mimetype. In addition to JSON, Cal-Heatmap can also
parse CSV, TSV and plain text file.
Using the right dataType
allows
cal-heatmap to interpret and convert the response to a valid json
object, but does not guarantee that it'll be formatted in the
timestamp:value format.
If the first and second column of your CSV or TSV files are respectively
the timestamp and value, no additional action is required, cal-heatmap
will try to extract the appropriate data, else, you have to use the
afterLoadData()
callback to
convert the data yourself. See
example with Google Analytics data.
All timestamps belonging to the same subDomain will be stacked together, and all subDomains with no associated data will be considered as empty (no data), and does not fall back to value = 0.
Opposed to subDomain Highlight, domain highlighting is "passive", you don't need to inject code into the calendar to highlight a domain, you have to edit the stylesheet.
Each domain have a set of class according to a date.
y_xxxx |
Year, xxxx is a four digit year |
m_1 to m_12 |
From January to December |
w_1 to w_54 |
Week 1 to Week 54 |
d_1 to d_31 |
Day of the month |
dy_0 to dy_6 |
Day of the week, Sunday is 0 and Saturday is 6 3.0.7+ |
h_0 to h_23 |
From 00h to 23h |
y_2000
and m_1
y_2000
, m_1
, w_1
,
d_1
and h_15
To highlight January 2000, you can use
/* Apply a red background to january 2000 */
.y_2000.m_1 .domain-background {
fill: red;
}
For better result, apply some margin with
domainMargin
.
You can also apply some "recursive" style, to highlight sleep hours.
.h_23 .domain-background, .h_0 .domain-background, .h_1 .domain-background, .h_2 .domain-background, .h_3 .domain-background, .h_4 .domain-background, .h_5 .domain-background, .h_6 .domain-background, .h_7 .domain-background {
fill: steelblue;
}
.h_23 .graph-label, .h_0 .graph-label, .h_1 .graph-label, .h_2 .graph-label, .h_3 .graph-label, .h_4 .graph-label, .h_5 .graph-label, .h_6 .graph-label, .h_7 .graph-label {
fill: #fff;
}
v2 documentation is still available at /v2/
There's a lot of changes coming with the 3.x branch. You should read the full documentation to use all the new features. Instruction below are only to migrate your v2 code to the v3 version.
onClick
event is now applied even to date with no data.
The second argument will be equal to null
when there is no
data associated to this date.
The duration
option has been renamed to
animationDuration
The id
option has been replaced by
itemSelector
, and now accepts a Selector String or an
Element, instead of an ID name.
cellsize
has been renamed to cellSize
(camel
case)
cellpadding
has been renamed to
cellPadding
(camel case)
cellradius
has been renamed to
cellRadius
(camel case)
cellLabel
has been renamed to
subDomainTitleFormat
scaleLabel
has been renamed to
legendTitleFormat
weekStartOnMonday
now takes a boolean (true/false) instead
of an integer (0/1)
format
has been spitted into multiple options.
format.date
is now subDomainDateFormat
format.legend
is now domainLabelFormat
The domain label can now be customized, by passing a function to
domainLabelFormat
.
browsing
option has been removed, see the
next()
, previous()
events, and the
nextSelector
and previousSelector
options.
highlightToday
has been replaced by highlight
,
and accepts an array of dates, allowing highlighting more than one date.
itemName
now accepts a single value array, or just a
string, and will auto guess the plural form as long as it's just the
singular form plus "s".
Previously, calendar width was dynamic, when using the month domain, coupled with the x_week subDomain, as a month not always contains the same number of weeks. Domain width was adjusted to the number of weeks to avoid blank space.
This function has been removed in v3, the domains will now always have the same width, so there'll be a blank space on some months with fewer weeks. This will avoid complex calculation, and allow smoother animation when navigating between domains.
This does not affect other domain/subDomain couple.
All examples are using the datas-hours and datas-years data source.
Read the page source for the examples' complete code, as the stylesheet is not visible via the View code buttons.
Localized in French, this graph is displaying the number of flies falling in Master Lao Zhi's living room because of his suffocating ki energy.
Hover over the subDomain and legend cells to view the new customized title.
Let's try other calendar view (month > day), and re-calibrate the legend colors for our data.
Week > hour view.
Year > day view.
Year > Month view.
Week > day view, vertically.
Dynamic domain dimension was
disabled to avoid page height "fluctuation".
Pass domain label
to an external function to uppercase it.
Week > day view
Hover on a subDomain cell to view the date
Give another background color for all February.
Display all the hours of the day on the same line.
Use Google Analytics data
You have to pre-process the csv files generated by Google Analytics to remove the header comments, as well as the last 2 lines.
Same datasource as previous example, with one line per day
Coming soon ...
Cal-HeatMap is licensed under the MIT License
Developed with love by Wan Qi Chen