Last active
October 7, 2016 23:25
-
-
Save pcarolan/8546e6c2953dd4c71ad35a908f988d07 to your computer and use it in GitHub Desktop.
Calendar Graph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{"created_at": "2016-10-06T16:22:24.520Z"}, | |
{"created_at": "2016-10-05T16:24:39.039Z"}, | |
{"created_at": "2016-10-04T16:24:39.039Z"}, | |
{"created_at": "2016-10-02T16:24:39.039Z"}, | |
{"created_at": "2016-10-01T16:24:39.039Z"}, | |
{"created_at": "2016-09-25T16:24:39.039Z"}, | |
{"created_at": "2016-09-24T16:24:39.039Z"}, | |
{"created_at": "2016-09-23T16:24:39.039Z"}, | |
{"created_at": "2016-09-22T16:24:39.039Z"}, | |
{"created_at": "2016-09-21T16:24:39.039Z"}, | |
{"created_at": "2016-09-20T16:24:39.039Z"}, | |
{"created_at": "2016-09-06T16:24:39.039Z"}, | |
{"created_at": "2016-09-05T16:24:39.039Z"}, | |
{"created_at": "2016-10-04T16:24:39.039Z"}, | |
{"created_at": "2016-10-03T16:24:39.039Z"}, | |
{"created_at": "2016-10-02T16:24:39.039Z"}, | |
{"created_at": "2016-10-01T16:24:39.039Z"}, | |
{"created_at": "2016-09-01T16:24:39.039Z"}, | |
{"created_at": "2016-08-01T16:24:39.039Z"}, | |
{"created_at": "2016-07-01T16:24:39.039Z"}, | |
{"created_at": "2016-06-01T16:24:39.039Z"}, | |
{"created_at": "2016-05-01T16:24:39.039Z"}, | |
{"created_at": "2016-04-01T16:24:39.039Z"}, | |
{"created_at": "2016-03-01T16:24:39.039Z"}, | |
{"created_at": "2016-02-01T16:24:39.039Z"}, | |
{"created_at": "2016-01-01T16:24:39.039Z"}, | |
{"created_at": "2015-12-01T16:24:39.039Z"}, | |
{"created_at": "2015-11-01T16:24:39.039Z"} | |
] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function calendarGraph() { | |
class Grid { | |
constructor(x, y) { | |
this.x = x; | |
this.y = y; | |
} | |
build() { | |
let a = []; | |
for (let i = 0; i < this.x; i++) { | |
for (let j = 0; j < this.y; j++) { | |
a.push({ | |
"x": i, | |
"y": j | |
}); | |
} | |
} | |
return a; | |
} | |
} | |
grid = new Grid(52, 7); | |
var margin = { | |
top: 200, | |
right: 30, | |
bottom: 220, | |
left: 30 | |
}; | |
var width = 660 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
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 + ")"); | |
// origin is top right because everything goes backwards and down. | |
var xScale = d3.scaleLinear().domain([1, grid.x]).range([width, 0]); | |
var yScale = d3.scaleLinear().domain([1, grid.y]).range([0, height]); | |
var xMap = function(d) { | |
return xScale(d.x) | |
}; | |
var yMap = function(d) { | |
return yScale(d.y) | |
}; | |
dateParser = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"); | |
weekParser = d3.timeFormat('%U'); | |
function weeksAgo(rawDate) { | |
return d3.timeWeek.count(dateParser(rawDate), new Date) | |
} | |
// draw the base grid | |
svg.selectAll("rect") | |
.data(grid.build()) | |
.enter() | |
.append("rect") | |
.attr("stroke", "lightgrey") | |
.attr("fill", "none") | |
.attr("width", 10) | |
.attr("height", 10) | |
.attr("x", xMap) | |
.attr("y", yMap) | |
.append("svg:title") | |
.text(function(d) { | |
return d.x + "," + d.y; | |
}); | |
// days of the week axis | |
dayLabels = [{'x': 53, 'y': 1, 'label': 'Mon'}, | |
{'x': 53, 'y': 3, 'label': 'Wed'}, | |
{'x': 53, 'y': 5, 'label': 'Fri'}] | |
var yLabels = svg.selectAll("text") | |
.data(dayLabels) | |
.enter(); | |
yLabels.append("text") | |
.attr("x", xMap) | |
.attr("y", yMap) | |
.attr("font-size", ".5em") | |
.attr("font-family", "Helvetica") | |
.attr("fill","grey") | |
.attr("dy", "8.5px") | |
.text(function(d){return d.label;}) | |
// month of year axis | |
today = d3.timeWeek.offset(new Date(), -0) | |
aYearAgo = d3.timeWeek.offset(new Date(), -52) | |
var xLabelScale = d3.scaleTime() | |
.domain([aYearAgo, today]) | |
.range([0, width]); | |
var xAxis = d3.axisBottom() | |
.scale(xLabelScale) | |
.tickSize(0, 0) | |
.tickFormat(d3.timeFormat("%b")); | |
xAxisG = svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + -35 + ")") | |
.call(xAxis) | |
xAxisG.selectAll(".tick text") | |
.style("text-anchor", "start") | |
.attr("fill","grey") | |
.attr("x", 6) | |
.attr("y", 6); | |
xAxisG.selectAll(".axis path") | |
.style("stroke", "none") | |
d3.json("activity.json", function(measurements) { | |
for (i = 0; i < measurements.length; i++) { | |
measurements[i]['day_of_week'] = dateParser(measurements[i]['created_at']).getDay(); | |
measurements[i]['week_of_year'] = parseInt(weekParser(dateParser(measurements[i]['created_at']))); | |
measurements[i]['y'] = measurements[i]['day_of_week']; | |
measurements[i]['x'] = weeksAgo(measurements[i]['created_at']); | |
} | |
svg.selectAll('rect') | |
.data(measurements, function(d) { | |
return d.x + "," + d.y; | |
}) | |
.attr("stroke", "lightgrey") | |
.attr("fill", "#AAF2D7") | |
// don't show days that are in the future. | |
var noDays = [] | |
for (i = 6; i > (new Date).getDay(); i--) { | |
noDays.push({ | |
"x": 0, | |
"y": i | |
}) | |
} | |
svg.selectAll('rect') | |
.data(noDays, function(d) { | |
return d.x + "," + d.y; | |
}) | |
.attr("fill", "none") | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<body> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script src="calendarGraph.js"></script> | |
<script type="text/javascript">calendarGraph()</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment