Plot.plot({
aspectRatio: 0.6,
marginLeft: 90,
width: 1152,
style: `
margin: 0 -14px;
background: #111;
color: #fff;
max-width: none;
text-transform: uppercase;
width: calc(100% + 28px);
`,
x: {domain: d3.range(1, 40), axis: null},
y: {domain: d3.range(12)},
length: {type: "identity"},
marks: (({data, x, y, r, hemisphere, projection}) => [
Plot.axisY({textAnchor: "start", tickFormat: Plot.formatMonth(locale, "long"), tickSize: 0, dx: -50}),
Plot.dot(data, {x, y, r, fill: "#fff"}),
Plot.text(data, {x, y, r, text: (d) => d.getUTCDate(), dy: -r - 5, fontSize: 7}),
Plot.vector(data, {
x,
y,
length(d) {
const noon = d3.utcHour.offset(d, 12);
const illum = suncalc.getMoonIllumination(noon);
return 180 - illum.phase * 360;
},
shape: {
draw(context, length) {
projection.rotate([length, 180]).scale(r);
const path = d3.geoPath(projection, context);
path(hemisphere);
}
},
anchor: "start",
fill: "#333"
})
])({
data: (() => {
const start = d3.utcYear(Date.UTC(year, 0, 1));
return d3.utcDays(start, d3.utcYear.offset(start));
})(),
x(d) {
const start = d3.utcMonth(d);
const offset = start.getUTCDay() || 7;
return d.getUTCDate() + offset;
},
y(d) {
return d.getUTCMonth();
},
r: 12,
hemisphere: d3.geoCircle()(),
projection: d3.geoOrthographic().translate([0, 0])
})
})