JSFiddle - React, Tailwind, and code Playground
by m1erickson
HTML
<canvas id="canvas" width=775 height=650></canvas>
CSS
body{ background-color: ivory; }
canvas{border:1px solid red;}
JavaScript
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var year = 2014;
var PI2 = Math.PI * 2;
var cx = 375;
var cy = 375;
var radialIncrement = 15;
var rotationIncrement = -Math.PI / 31;
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var dayNames = ['Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa', 'Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa'];
var monthsFirstWeekday = []
for (var m = 1; m <= 12; m++) {
monthsFirstWeekday.push(new Date(m + "/01/" + year).getDay());
}
for (var d = 0; d <= 38; d++) {
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rotationIncrement * (31 - d) + Math.PI / 2);
var x = -3;
var y = -13 * radialIncrement - 150;
ctx.font = "12px verdana";
ctx.fillStyle = "blue";
ctx.fillText(dayNames[d], x, y);
ctx.restore();
}
for (var m = 0; m < months.length; m++) {
ctx.save();
ctx.translate(cx, cy + 25);
ctx.rotate(Math.PI * 3 / 2);
ctx.fillStyle = "blue";
ctx.fillText(months[m], 0, -(months.length - m) * radialIncrement - 150);
ctx.restore();
}
for (var d = 0; d <= 38; d++) {
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rotationIncrement * (31 - d) + Math.PI / 2);
for (var m = 0; m < months.length; m++) {
var x = 0;
var y = -(months.length - m) * radialIncrement - 150;
var dd = d - monthsFirstWeekday[m] + 1;
if (dd > 0 && dd <= days[m]) {
ctx.fillStyle = "black";
ctx.fillText(dd, x, y);
} else {
ctx.beginPath();
ctx.arc(x + 3, y, 1, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = "red";
ctx.fill();
}
}
ctx.restore();
}