var secondsPerMinute = 60; var minutesPerHour = 60; var timeFormat = function(d) { return d3.timeFormat('%H:%M')(new Date(0, 0, 0, d, (d*60)%60, 0)); } d3.text('finish.txt', function(text) { var times = d3.csvParseRows(text, function(d) { return d.map(Number); }); var grouped = d3.nest() .key(function(d) { return Math.floor(d[0] / secondsPerMinute); }) .entries(times) .sort(function(a, b) { return d3.ascending(+a.key, +b.key); }); var bar = fc.seriesSvgBar() .barWidth(fc.seriesFractionalBarWidth(1.1)) .crossValue(function(d) { return (+d.key + 0.5) / minutesPerHour; }) .mainValue(function(d) { return d.values.length; }) var gridlines = fc.annotationSvgGridline(); var multi = fc.seriesSvgMulti() .series([bar, gridlines]); var yExtent = fc.extentLinear() .accessors([function(d) { return d.values.length; }]) .pad([0, 0.1]); var chart = fc.chartSvgCartesian( d3.scaleLinear(), d3.scaleLinear() ) .xDomain([2, 7]) .yDomain(yExtent(grouped)) .yOrient('left') .yTicks(5) .yLabel('Frequency') .xLabel('Finish time (hours)') .chartLabel('London Marathon 2016 Finish Time Distribution') .xTickFormat(timeFormat) .plotArea(multi); d3.select('#chart') .datum(grouped) .call(chart); });