Visualising distribution of WEHoRR finish times for 2018.
Source: http://www.wehorr.org/results/
Highlights:
xxxxxxxxxx
<html>
<head>
<title>WEHoRR Results</title>
<script src="https://cdn.jsdelivr.net/gh/pshihn/rough/9be60b1e/dist/rough.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Just+Another+Hand" rel="stylesheet">
<style>
canvas {
margin: 20px 20px 20px 20px;
}
@font-face {
font-family: 'Just Another Hand';
font-style: normal;
font-weight: 400;
src: local('Just Another Hand Regular'), local('JustAnotherHand-Regular'),
url(https://fonts.gstatic.com/s/justanotherhand/v9/845CNN4-AJyIGvIou-6yJKyptyOpOfr4DGiHSIax.woff2) format('woff2');
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
WebFontConfig = {
google: {
families: ['Just Another Hand'],
},
active: function () { draw(); },
};
(function (d) {
var wf = d.createElement('script'), s = d.scripts[0];
wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
wf.async = true;
s.parentNode.insertBefore(wf, s);
})(document);
function draw() {
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const rc = rough.canvas(canvas);
const width = 600;
const height = 400;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
const scale = window.devicePixelRatio;
canvas.width = width * scale;
canvas.height = height * scale;
// Normalize coordinate system to use css pixels.
context.scale(scale, scale);
d3.csv('wehorr-results-2018.csv').row(
function (d) {
const time = d3.timeParse('%M:%S.%L')(d.Time);
return {
finish: +d.Finish,
start: +d.Start,
name: d.Name,
time: 60 * time.getMinutes() + time.getSeconds(),
};
}).get(function (data) {
d3.select('#canvas').on("touchmove mousemove", moved);
let pos;
function moved() {
pos = d3.mouse(this);
redraw();
}
const x = d3.scaleLinear().range([0, width]).domain(d3.extent(data.map(function (d) { return d.time; }))).nice();
const tickValues = d3.range(Math.floor(d3.min(data, function (d) { return d.time; }) / 60), Math.ceil(d3.max(data, function (d) { return d.time; }) / 60)).map(function (d) { return 60 * d; });
const tickFormat = function (d) { return d3.format('2d')(Math.floor(d / 60)) + ':' + d3.format('02d')(d % 60); }
const simulation = d3.forceSimulation(data)
.force('x', d3.forceX(function (d) { return x(d.time); }).strength(1))
.force('y', d3.forceY(250))
.force('collide', d3.forceCollide(5))
.stop();
for (var i = 0; i < 120; ++i) simulation.tick();
const voronoi = d3.voronoi()
.extent([[0, 200], [width + 1, height + 1]])
.x(function (d) { return d.x; })
.y(function (d) { return d.y; });
const diagram = voronoi(data);
redraw();
function redraw() {
Math.seedrandom('hello.');
context.clearRect(0, 0, width, height);
let found = null;
if (pos !== undefined) {
found = diagram.find(pos[0], pos[1], 50);
}
data.forEach(function (d, i) {
rc.line(x(d.time), 60, x(d.time), 85, { roughness: 0.4, stroke: 'rgba(0,0,0,0.3)', strokeWidth: 1 });
});
context.textAlign = 'center';
context.textBaseline = 'top';
context.fillStyle = 'darkgrey';
context.font = '20px Just Another Hand';
tickValues.forEach(function (d) {
context.fillText(tickFormat(d), x(d), 100);
});
data.forEach(function (d, i) {
let stroke = 'rgba(0,0,0,0.5)';
let fill = 'rgba(255,255,255,0)'
if (found !== null && found.index === i) {
stroke = 'rgba(255,0,0,1)';
fill = 'rgba(255,0,0,1)'
}
rc.circle(d.x, d.y, 10, {
stroke: stroke,
roughness: 0.4,
strokeWidth: 1,
fill: fill,
fillStyle: 'solid'
});
});
tickValues.forEach(function (d) {
context.fillText(tickFormat(d), x(d), 300 + 20);
});
}
});
}
</script>
</body>
</html>
Updated missing url https://cdn.rawgit.com/pshihn/rough/9be60b1e/dist/rough.min.js to https://cdn.jsdelivr.net/gh/pshihn/rough/9be60b1e/dist/rough.min.js
https://cdn.rawgit.com/pshihn/rough/9be60b1e/dist/rough.min.js
https://d3js.org/d3.v4.js
https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js
https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js