Reputation: 526
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.
Upvotes: 12
Views: 247
Reputation: 1787
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
Upvotes: 1