This charts shows the weekly training mileage of strava athletes who ran the 2016 London Marathon. The data is rendered using a combination of d3 and d3fc components.
Weekly marathon training mileage
This file contains 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'> | |
<script src="https://unpkg.com/d3@4.6.0"></script> | |
<script src="https://unpkg.com/d3fc@12.1.0"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.18.0/d3-legend.js"></script> | |
<style> | |
body { | |
font-family: sans-serif; | |
font-size: 1.2em; | |
} | |
.tick { | |
font-size: 1.2em; | |
} | |
.gridline-y { | |
display: none; | |
} | |
.gridline-x { | |
opacity: 0.5; | |
} | |
.legend { | |
position: absolute; | |
bottom: auto; | |
top: 50px; | |
right: 10px; | |
width: 150px; | |
height: 120px; | |
font-size: 0.8em; | |
} | |
.y-axis-label { | |
transform: rotate(-90deg) translateY(20px) !important; | |
} | |
.point { | |
fill: inherit; | |
stroke: transparent; | |
} | |
.line { | |
stroke: inherit; | |
} | |
</style> | |
<div id='chart' style='height: 400px'></div> | |
<script src="training-mileage.js"></script> |
This file contains 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
week | 2 - 3 hours | 3 - 4 hours | 4 - 5 hours | 5 - 6 hours | |
---|---|---|---|---|---|
1 | 37.58857143 | 22.63053279 | 15.86790831 | 13.05769231 | |
2 | 41.21048951 | 23.61279528 | 18.4127027 | 15.47256637 | |
3 | 41.92 | 25.39609375 | 17.9571831 | 16.14122807 | |
4 | 41.42191781 | 25.33238095 | 18.49645777 | 14.77107438 | |
5 | 42.0489011 | 26.05599315 | 17.66459459 | 16.772 | |
6 | 46.67231638 | 27.82239583 | 20.04053333 | 16.58130081 | |
7 | 48.19044944 | 28.88290598 | 20.33341772 | 17.77096774 | |
8 | 49.64444444 | 29.67728814 | 21.46188119 | 18.08333333 | |
9 | 44.40748663 | 28.55257903 | 22.06059113 | 18.4728 | |
10 | 47.75654762 | 28.23784247 | 20.40025 | 14.61755725 | |
11 | 47.72601156 | 29.42739496 | 21.7739759 | 18.40378788 | |
12 | 50.48 | 30.72166667 | 24.93062201 | 19.68814815 | |
13 | 42.76358974 | 26.38578352 | 20.98762376 | 16.75952381 | |
14 | 47.30483871 | 30.17133443 | 22.27336562 | 17.66614173 | |
15 | 39.3483871 | 22.85170732 | 17.33044554 | 13.63257576 | |
16 | 24.93055556 | 15.11318865 | 10.62351421 | 8.540186916 | |
17 | 8.889005236 | 5.637198795 | 3.562150538 | 2.846060606 |
This file contains 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
d3.csv('training-mileage.csv', function(mileage) { | |
var group = fc.group() | |
.orient('horizontal') | |
.key('week'); | |
var groupedMileage = group(mileage); | |
var colourDomain = groupedMileage[0].map(function(d) { return d[0]; }); | |
var color = d3.scaleOrdinal(d3.schemeCategory10) | |
.domain(colourDomain); | |
var point = fc.seriesSvgPoint() | |
.size(20) | |
.crossValue(function(d, i) { return i + 1; }) | |
.mainValue(function(d, i) { return d[1]; }); | |
var line = fc.seriesSvgLine() | |
.crossValue(function(d, i) { return i + 1; }) | |
.mainValue(function(d, i) { return d[1]; }); | |
var pointLineSeries = fc.seriesSvgMulti() | |
.series([point, line]); | |
var multiLine = fc.seriesSvgRepeat() | |
.series(pointLineSeries) | |
.decorate(function(sel) { | |
sel.attr('stroke', function(_, i) { return color(colourDomain[i]); }) | |
.attr('fill', function(_, i) { return color(colourDomain[i]); }) | |
}); | |
var gridline = fc.annotationSvgGridline() | |
.yTicks(5); | |
var multi = fc.seriesSvgMulti() | |
.series([multiLine, gridline]); | |
var yExtent = fc.extentLinear() | |
.include([0]) | |
.pad([0, 0.1]) | |
.accessors([function(d) { return d.map(function(j) { return j[1]; }); }]); | |
var legend = d3.legendColor() | |
.shapeWidth(30) | |
.orient('vertical') | |
.scale(color); | |
var extent = yExtent(groupedMileage); | |
var chart = fc.chartSvgCartesian( | |
d3.scaleLinear(), | |
d3.scaleLinear() | |
) | |
.xDomain([0.5, mileage.length + 0.5]) | |
.yDomain(yExtent(groupedMileage)) | |
.yOrient('left') | |
.yTicks(5) | |
.yLabel('miles') | |
.xLabel('week') | |
.yNice() | |
.chartLabel('Weekly marathon training mileage') | |
.plotArea(multi) | |
.decorate(function(selection, data, index) { | |
// append an svg for the d3-legend | |
selection.enter() | |
.append('svg') | |
.attr('class', 'legend'); | |
// render the legend | |
selection.select('svg.legend') | |
.call(legend); | |
}); | |
d3.select('#chart') | |
.datum(groupedMileage) | |
.call(chart); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment