Skip to content

Instantly share code, notes, and snippets.

@jrsconfitto
Forked from mbostock/.block
Last active August 29, 2015 13:58
Show Gist options
  • Save jrsconfitto/9993335 to your computer and use it in GitHub Desktop.
Save jrsconfitto/9993335 to your computer and use it in GitHub Desktop.
7 Wonder's score streamgraphs
<!DOCTYPE html>
<meta charset="utf-8">
<title>7 Wonders players' streamgraphs</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>
<p>Select a player to see their scores
<select id="players"></select>
</p>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
// To make my life easier for now...
var gameData;
d3.json('/jugglingnutcase/raw/9992169/games.json', function(err, games) {
if (err) return console.error(err);
// Save this for access anywhere
gameData = games;
// Set up all the players (with more than one game)
var players = d3.nest()
.key(function(player) { return player.name })
.sortKeys(d3.ascending)
.entries(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) {
return game.players
}).reduce(function(a, b) {
return a.concat(b)
})
)
.filter(function(player) {
return player.values.length > 1
});
d3.select('#players').selectAll('option')
.data(players)
.enter().append('option')
.attr('value', function(d) { return d.key })
.text(function(d) { return d.key })
d3.select('#players')
.on('change', stackThePlayer);
// 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'
];
if (players.length > 0) {
// Kick off the graph
stackThePlayer();
}
function stackThePlayer() {
var selectedPlayer = d3.select('option:checked').node().value;
console.log('stacking ' + selectedPlayer);
var playersGames = games.map(function(game) {
return game.players.filter(function(player) {
return player.name == selectedPlayer
})
}).reduce(function(a, b) {
return a.concat(b)
});
var n = pointCategories.length, // number of layers: these should be point categories
stack = d3.layout.stack().offset("wiggle"),
gameLayers = stack(d3.range(pointCategories.length).map(function(cat) {
// Return x:y pairs for each game for each point category
return playersGames.map(function(game, i) {
return {
x: i,
y: game.scores[pointCategories[cat]]
}
})
}));
var width = 960,
height = 400;
var x = d3.scale.linear()
.domain([0, playersGames.length - 1])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, d3.max(gameLayers, 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); });
// Remove the previous svg and replace it with every player switch
if (!d3.select('svg').empty()) {
d3.select('svg').remove()
}
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height)
var paths = svg.selectAll('path')
.data(gameLayers)
.enter().append('path')
.attr('d', area)
.style('fill', function(d, i) {
return colors[i];
})
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment