Skip to content

Instantly share code, notes, and snippets.

@curran
Last active October 23, 2019 22:40
Show Gist options
  • Save curran/27420ce88227892d000c3988a5b06c8c to your computer and use it in GitHub Desktop.
Save curran/27420ce88227892d000c3988a5b06c8c to your computer and use it in GitHub Desktop.
Moon Calendar 2017
license: mit
border: no
height: 380
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin: 0;position: fixed;top: 0;right: 0;bottom: 0;left: 0;
}
text {
font-size: 1rem;
}
.axis .domain, .axis line {
display: none;
}
</style>
</head>
<body>
<svg width="960" height="380"></svg>
<script>
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
margin = { left: 100, right: 15, top: 35, bottom: 35 },
moonSize = 12,
moonStroke = 0.5,
axisPadding = moonSize - 2,
startDate = new Date(2017, 0, 1),
endDate = new Date(2017, 11, 31);
var g = svg.append("g")
.attr("transform", "translate(" + [margin.left, margin.top] + ")"),
innerWidth = width - margin.right - margin.left,
innerHeight = height - margin.bottom - margin.top,
formatMonth = d3.timeFormat("%B"),
formatDay = d3.timeFormat("%d"),
newMoon = (new Date(1970, 0, 7, 20, 35, 0)).getTime(),
lunarPeriod = 2551443000,
data = d3.timeDays(startDate, endDate).map(type);
function type (date){
return {
month: formatMonth(date),
day: formatDay(date),
phase: -((date.getTime() - newMoon)) / lunarPeriod * 360 + 180
};
}
var xScale = d3.scaleLinear()
.domain(d3.extent(data, function (d){ return d.day; }))
.range([0, innerWidth]),
yScale = d3.scalePoint()
.domain(data.map(function (d){ return d.month; }))
.range([0, innerHeight]);
var circle = d3.geoCircle(),
projection = d3.geoOrthographic()
.scale(moonSize)
.translate([0, 0]),
path = d3.geoPath()
.projection(projection);
g.append("g")
.attr("class", "y axis")
.attr("transform", "translate(-" + axisPadding + ")")
.call(d3.axisLeft().scale(yScale));
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,-" + axisPadding + ")")
.call(d3.axisTop().scale(xScale).ticks(30));
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (innerHeight + axisPadding) + ")")
.call(d3.axisBottom().scale(xScale).ticks(30));
var moons = g.selectAll(".moon").data(data)
.enter().append("g")
.attr("class", "moon")
.attr("transform", function (d){
return "translate(" + [xScale(d.day), yScale(d.month)] + ")";
});
moons.append("circle")
.attr("fill", "#2b281b")
.attr("r", moonSize + moonStroke);
moons.append("path")
.attr("fill", "#f7f6f2")
.attr("d", function (d){
return path(circle.center([d.phase, 0])());
});
svg.on("click", function (){
var d = type(new Date());
g.append("circle")
.attr("cx", function (){ return xScale(d.day); })
.attr("cy", function (){ return yScale(d.month); })
.attr("stroke", "red")
.attr("stroke-width", "50px")
.attr("stroke-opacity", 0)
.attr("fill", "none")
.attr("r", 500)
.transition().duration(1000)
.attr("stroke-width", "3px")
.attr("stroke-opacity", 1)
.attr("r", moonSize + 5);
});
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment