This is a graph of total scores, broken down by category, per game.
Testing new ideas for my 7 Wonders statistics site.
This is a graph of total scores, broken down by category, per game.
Testing new ideas for my 7 Wonders statistics site.
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>7 Wonders Streamgraph</title> | |
<style> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
margin: auto; | |
position: relative; | |
width: 960px; | |
} | |
button { | |
position: absolute; | |
right: 10px; | |
top: 10px; | |
} | |
</style> | |
<h1>Total scores, broken down by category, per game</h1> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var width = 960, | |
height = 400; | |
// Try converting the data into something stackable | |
var pointCategories = [ | |
'military', | |
'coindebt', | |
'wonder', | |
'civic', | |
'trade', | |
'guilds', | |
'science', | |
'leaders' | |
]; | |
var colors = [ | |
'red', | |
'brown', | |
'gray', | |
'blue', | |
'yellow', | |
'purple', | |
'green', | |
'pink' | |
]; | |
d3.json('/jugglingnutcase/raw/9992169/games.json', function(err, games) { | |
if (err) return console.error(err); | |
games = games.sort(function(game1, game2) { | |
var date1 = d3.time.format.iso.parse(game1.date); | |
var date2 = d3.time.format.iso.parse(game2.date); | |
return (date1 > date2) ? 1 : (date1 < date2) ? -1 : 0; | |
}).map(function(game, index) { | |
return { | |
id: index, | |
scores: game.players.map(function(player) { | |
return player.scores; | |
}).reduce(function(scoreAcc, scoreCurr) { | |
for (key in scoreAcc) { | |
scoreAcc[key] += scoreCurr[key]; | |
} | |
return scoreAcc; | |
}) | |
}; | |
}); | |
var n = pointCategories.length, // number of layers: these should be point categories | |
stack = d3.layout.stack().offset("wiggle"), | |
scoreLayers = stack(d3.range(pointCategories.length).map(function(cat) { | |
// Return x:y pairs for each game for each point category | |
return games.map(function(game, i) { | |
return { | |
x: i, | |
y: game.scores[pointCategories[cat]] | |
} | |
}) | |
})); | |
var x = d3.scale.linear() | |
.domain([0, games.length - 1]) | |
.range([0, width]); | |
var y = d3.scale.linear() | |
.domain([0, d3.max(scoreLayers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); })]) | |
.range([height, 0]); | |
var area = d3.svg.area() | |
.x(function(d) { return x(d.x); }) | |
.y0(function(d) { return y(d.y0); }) | |
.y1(function(d) { return y(d.y0 + d.y); }); | |
var svg = d3.select('body').append('svg') | |
.attr('width', width) | |
.attr('height', height) | |
var paths = svg.selectAll('path') | |
.data(scoreLayers) | |
.enter().append('path') | |
.attr('d', area) | |
.style('fill', function(d, i) { | |
return colors[i]; | |
}) | |
}); | |
</script> |