'Is there a way to perfectly align rows in a heatmap where the yAxis is the month?
The Problem
I am trying to generate a heatmap with highcharts. The chart will show the average PM2.5 value over x years for a day in a month. The issue is that the rows are not aligned because of the different lengths of the months.
I expect the cells in the grid to not be overflowing to the cell above it like in the large heatmap demo. In my example the overflow is visible when hovering a cell.
What I Have Tried
I have tried reducing the rowsize
a little bit (e.g. 24 * 25 * 36e5
) but it results in uneven white space between the rows.
In theory I could use categories but I also need to have the possibility to illustrate the daily variation over a year using the yAxis hour and xAxis for julian day. The xAxis in this case would need to be formatted as month (%B
).
The proper solution would be to make the grid symmetrical but since I use datetime
on both axes, I can't manually make all days of the months 31 days long.
Current Code
let data = [];
// random data generation
const daysPerMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
let month;
// yAxis: month
for (let i = 0; i < 12; i++) {
month = new Date(2022, i, 2).getTime(); // use second hour to align the cell to the correct month
// xAxis: days
for (let j = 0; j < daysPerMonth[i]; j++) {
const randomAdden = Math.random() * (5 - 1) + 1;
const plusOrMinus = Math.random() < 0.5 ? -1 : 1;
let previousValue = 50; // starting value
if (data[data.length - 1] != null) {
previousValue = data[data.length - 1][2];
}
const day = j * 24 * 36e5;
data.push([day, month, Math.max(previousValue + randomAdden * plusOrMinus, 0)]);
}
}
Highcharts.chart('container', {
accessibility: {
enabled: false, // disabled to remove console warning on stack overflow
},
title: {
text: 'PM2.5 random heat map',
align: 'left',
x: 40
},
subtitle: {
text: 'PM2.5 average per day and month over a year',
align: 'left',
x: 40
},
xAxis: {
type: 'datetime',
min: 0,
max: 36e5 * 24 * 31,
labels: {
align: 'left',
x: 5,
y: 14,
format: '{value:%e}'
},
},
yAxis: {
type: 'datetime',
min: Date.UTC(2022, 0, 1),
max: Date.UTC(2022, 11, 31),
title: {
text: null
},
gridLineWidth: 0,
labels: {
format: '{value:%B}' // long month
},
startOnTick: false,
endOnTick: false,
tickmarkPlacement: 'on',
tickInterval: 24 * 31 * 36e5,
showLastLabel: false,
},
colorAxis: {
stops: [
[0.048, '#00e400'],
[0.14, '#ffff00'],
[0.22, '#ff7e00'],
[0.6, '#ff0000'],
[0.9999, '#8f3f97'], // if equal to max (250)
[1, '#7e0023'] // more than max (250)
],
min: 0,
max: 251,
startOnTick: false,
endOnTick: false,
labels: {
format: '{value} µg/m³'
}
},
series: [{
type: 'heatmap',
data: data,
borderWidth: 0,
nullColor: '#EFEFEF',
colsize: 24 * 36e5,
rowsize: 24 * 31 * 36e5,
tooltip: {
headerFormat: 'PM2.5<br/>',
pointFormat: '{point.x:%e} {point.y:%b}: <b>{point.value} µg/m³</b>'
}
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<div id="container" />
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|