Published
Edited
Sep 9, 2022
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3.select('#title')
.text('📅 '+d3.timeYear().getUTCFullYear()+' Calendar')
Insert cell
monthNames = ["January","February","March",
"April", "May", "June",
"July", "August", "September",
"October", "November","December"];
Insert cell
Insert cell
//Month Boxes
d3.select('#main')
.selectAll('div')
.data(d3.timeMonth.range(
d3.timeYear.floor(new Date()), //year start
d3.timeYear.ceil(new Date())) //year end
)
.enter().append('div')
.attr('class', 'monthBox')
//Month Labels
.append('div')
.attr('class', 'monthLabel')
.text(d => monthNames[d.getMonth()])
//Building up the weeks...
.data().forEach(currentMonth => {
//Week Boxes
let weeks = d3.selectAll('.monthBox').filter(d => d == currentMonth)
.append('div')
.selectAll('div')
.data( d => d3.timeWeek.range(
d3.timeWeek.offset(d,d.getDay()==0 ? 0:-1), //includes the week prior to month start...
d3.timeMonth.offset(d,1) // ...up to the last week of the month.
)
)
.enter().append('div')
.attr('class', 'weekBox')
.style('background-color', (d,i,a) => i % 2 == 0 ? "#FFF" : "#EFF"); //alternating week colors
//Building up the days...
weeks.data().forEach((currentWeek,weekIndex) => {

//Day Boxes
let days = d3.selectAll('.weekBox').filter(d => d == currentWeek)
.selectAll('div')
.data( datum => d3.timeDay.range(
datum,
d3.timeDay.offset(datum,7) //create a range of days from the week start
)
)
.enter().append('div')
.attr('class', 'dateBox')
.style('background-color', datum => {
let bgColor;
if( currentMonth.getMonth() == datum.getMonth() ) //if the selected date is in the relevant month...
if( datum.toDateString() === new Date().toDateString() )
bgColor = "#FF5" //...highlight the current day
else
bgColor = datum.backgroundColor //...default color, if not current day
else
bgColor = "#EEE" //...blank out the non-relevant days in a month box
return bgColor
});
//Day Labels
days.text( datum => {
let dateString;
if( currentMonth.getMonth() == datum.getMonth() ) {
dateString = datum.getDate();
}
return dateString
});
})
});
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more