xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.day {
fill: #fff;
stroke: #ccc;
stroke-width: .5px;
}
.month {
fill: none;
stroke: #000;
stroke-width: 1px;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 960 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var years = d3.range(2010, 2016).reverse(),
sizeByYear = height/years.length+1;
sizeByDay = d3.min([sizeByYear/8,width/54]);
var day = function(d) { return (d.getDay() + 6) % 7; },
week = d3.time.format("%W"),
date = d3.time.format("%b %d"),
parseDate = d3.time.format("%Y-%m-%d").parse;
var color = d3.scale.linear()
.range(["#f7fcb9","#006837"]);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var year = svg.selectAll(".year")
.data(years)
.enter().append("g")
.attr("class", "year")
.attr("transform", function(d,i) { return "translate(0," + i * sizeByYear + ")"; });
year.append("text")
.attr("class", "yearTitle")
.attr("transform", "translate(-6," + sizeByDay * 3.5 + ")rotate(-90)")
.attr("text-anchor", "middle")
.attr("font-weight", "bold")
.text(function(d) { return d; });
var rect = year.selectAll(".day")
.data(function(d) { return (d === 2015) ? d3.time.days(new Date(d, 0, 1), new Date(d , 10, 6)) : d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
.enter().append("rect")
.attr("class", "day")
.attr("width", sizeByDay)
.attr("height", sizeByDay)
.attr("x", function(d) { return week(d) * sizeByDay; })
.attr("y", function(d) { return day(d) * sizeByDay; });
year.selectAll(".month")
.data(function(d) { return d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
.enter().append("path")
.attr("class", "month")
.attr("d", monthPath);
rect.append("title")
.text(function(d) { return date(d); });
d3.json("data.json", function(data) {
var nested_data = d3.nest()
.key(function(d) { return parseDate(d.created_at.split("T")[0]); })
.rollup(function(leaves) { return leaves.length; })
.map(data);
color.domain(d3.extent(d3.values(nested_data)));
rect.filter(function(d){ return d in nested_data; })
.style("fill", function(d){ return color(nested_data[d]); })
.select("title")
.text(function(d){ return date(d) + ": " + nested_data[d]; });
});
function monthPath(t0) {
var t1 = new Date(t0.getFullYear(), t0.getMonth() + 1, 0),
d0 = +day(t0), w0 = +week(t0),
d1 = +day(t1), w1 = +week(t1);
return "M" + (w0 + 1) * sizeByDay + "," + d0 * sizeByDay
+ "H" + w0 * sizeByDay + "V" + 7 * sizeByDay
+ "H" + w1 * sizeByDay + "V" + (d1 + 1) * sizeByDay
+ "H" + (w1 + 1) * sizeByDay + "V" + 0
+ "H" + (w0 + 1) * sizeByDay + "Z";
};
d3.select(self.frameElement).style("height", (height + margin.top + margin.bottom) + "px");
</script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js