First of all, sorry about the title.
I am trying to achieve something similar to this: https://bl.ocks.org/mbostock/4063318 I'm really close and the only thing I can't get is the path around the months.
I'm using the open source code from that page as well as my variation of this https://github.com/Teamie/calendar-heatmap/blob/master/src/calendar-heatmap.js
Currently I'm pretty close, but this is what it comes out to:
The date range on this pic is August 15th 2016 - August 15th 2017 but it starts the path as if it is August 1st 2015 - August 19th 2017. So what happens is the path surrounding a month will actually be surrounding the last half of one month and the first half of another. Somewhere it's getting the wrong data, I just can't figure it out.
Here is my code for the trail itself:
/*
*
* REFERENCE
*
* M = moveto
* H = horizontal lineto
* V = vertical lineto
* Z = closepath
*
*/
// https://bl.ocks.org/mbostock/4063318 MAGIC
function monthPath(t0) {
//What the hell is a t0 anyways?
console.log(counter + " " + t0);
let cellSize = SQUARE_LENGTH + SQUARE_PADDING;
let t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
d0 = t0.getDay(), w0 = d3.timeWeek.count(d3.timeYear(t0), t0),
d1 = t1.getDay(), w1 = d3.timeWeek.count(d3.timeYear(t1), t1);
let voodoo = 'M' + (w0 + 1) * cellSize + ',' + d0 * cellSize +
'H' + w0 * cellSize + 'V' + 7 * cellSize +
'H' + w1 * cellSize + 'V' + (d1 + 1) * cellSize +
'H' + (w1 + 1) * cellSize + 'V' + 0 +
'H' + (w0 + 1) * cellSize + 'Z';
console.log(voodoo);
return voodoo;
/*
* TRANSLATION OF VOODOO
*
* voodoo = startat boundaries of w0, d0.
* move horizontally over one cell
* move vertically 7 cells
* move horizontally to the boundaries of w1 + one cell
* move vertically to the boundaries of (d1 + one) + one cell
* move horizontally to the boundaries of (w1 + one) + one cell
* move vertically 0 pixels??
* hove horizontally to (w0 +1) + one cell
* close the path
*/
}
}
And the code where I am calling the function:
// month border
let first = dateRange[0];
let last = dateRange[dateRange.length - 1];
let tempRange = [];
tempRange.push(first);
for(let i = 1; i < 13; i++) {
tempRange.push(new Date(first.getFullYear(), first.getMonth() + i, 1));
}
tempRange.push(dateRange[dateRange.length - 1]);
console.log(tempRange);
svg.append('g')
.attr('transform', 'translate(-1,' + (MONTH_LABEL_PADDING - 1) + ')')
.selectAll('.monthpath')
.data(d3.timeMonths(new Date(first.getFullYear(), first.getMonth(), first.getDay()), new Date(last.getFullYear(), last.getMonth(), last.getDay())))
//.data(tempRange)
//NOTE: I have tried both .data() attempts with the same result for each
.enter().append('path')
.attr('class', 'monthpath')
.attr('d', monthPath);
Any help is much appreciated.
EDIT: Didn't notice the weirdness going on around Mar/Apr but also have no idea what's going on there.
To find the number of months or days between two dates, type into a new cell: =DATEDIF(A1,B1,”M”) for months or =DATEDIF(A1,B1,”D”) for days.
DATEDIF is not a standard function and hence not part of functions library and so no documentation. Microsoft doesn't promote to use this function as it gives incorrect results in few circumstances. But if you know the arguments, you may use it and it will work and in most of the cases will give correct results.
Calculates the number of days, months, or years between two dates.
The Mike Bostock code draws the months' paths from Jan to Dec in each row, not from August through to July, as you want.
The "weirdness" you see at April is two August months overlapping.
In the monthPath function, the start of the path is in part determined by the day number within the year (d0 = t0.getDay()
). You will need to offset this to account for shifting the months from Jan-Dec to August-July
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With