League of Legends players by rank - a simple bar chart with D3.js
Sep 3, 2019
Still experimenting with D3.js, this time I wanted to make a simple bar chart. Since it’s always nice to show actual, informative data, I decided to reproduce the distribution of players in the different ranks in League of Legends as shown on this website: https://www.esportstales.com/league-of-legends/rank-distribution-percentage-of-players-by-tier.
Like last time, here is the result:
Whenever I find the time, I’ll have to do this again in D3.js v4 or v5. Anyway, you probably already know how to extract the HTML and JavaScript code from this website but I’ll make it easier and post it below. Please excuse the vague and potentially incorrect comments, I’m still in the process of learning the D3.js framework.
<html>
<head>
<meta charset="utf-8">
<title>League of Legends: players by rank</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<style>
body {
font: 11px sans-serif;
}
.axis {
font-size: 12px;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.dot {
stroke: #000;
}
.tooltip {
position: absolute;
text-align: center;
width: auto;
height: auto;
padding: 2px;
background: white;
border: 1px;
border-radius: 2px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="graphic"></div>
<script>
// define data
var data = [
{group: "Iron", rank: "Iron IV", percentage: 0.07},
{group: "Iron", rank: "Iron III", percentage: 0.38},
{group: "Iron", rank: "Iron II", percentage: 0.84},
{group: "Iron", rank: "Iron I", percentage: 1.13},
{group: "Bronze", rank: "Bronze IV", percentage: 2.84},
{group: "Bronze", rank: "Bronze III", percentage: 3.23},
{group: "Bronze", rank: "Bronze II", percentage: 4.38},
{group: "Bronze", rank: "Bronze I", percentage: 6.09},
{group: "Silver", rank: "Silver IV", percentage: 9.56},
{group: "Silver", rank: "Silver III", percentage: 7.91},
{group: "Silver", rank: "Silver II", percentage: 9.01},
{group: "Silver", rank: "Silver I", percentage: 7.17},
{group: "Gold", rank: "Gold IV", percentage: 12.52},
{group: "Gold", rank: "Gold III", percentage: 7.31},
{group: "Gold", rank: "Gold II", percentage: 6.31},
{group: "Gold", rank: "Gold I", percentage: 3.95},
{group: "Platinum", rank: "Platinum IV", percentage: 6.98},
{group: "Platinum", rank: "Platinum III", percentage: 2.82},
{group: "Platinum", rank: "Platinum II", percentage: 1.96},
{group: "Platinum", rank: "Platinum I", percentage: 1.85},
{group: "Diamond", rank: "Diamond IV", percentage: 2.23},
{group: "Diamond", rank: "Diamond III", percentage: 0.77},
{group: "Diamond", rank: "Diamond II", percentage: 0.37},
{group: "Diamond", rank: "Diamond I", percentage: 0.21},
{group: "Top", rank: "Master", percentage: 0.05},
{group: "Top", rank: "GrandMaster", percentage: 0.04},
{group: "Top", rank: "Challenger", percentage: 0.02}
];
// define margins and size of plotting area
var margin = {top: 20, right: 20, bottom: 80, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// define X and Y axes as well as the scales
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
x.domain(data.map(function(d) { return d["rank"] }));
y.domain([0, d3.max(data, function(d) { return d["percentage"]} )+1]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10)
.tickFormat( function(d) { return d + "%" } );
// create plotting area
var svg = d3.select("#graphic")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// create function which assign colors to tiers
var color = d3.scale.ordinal()
.domain(["Iron","Bronze","Silver","Gold","Platinum","Diamond","Top"])
.range(["#3b3c40","#523233","#7f7f7f","#fed800","#e5e4e4","#9bc5db","#826f93"]);
// create tooltip box
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// draw X axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "0.5em")
.attr("transform", "rotate(-45)" );
// draw Y axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Percentage of players");
// draw bars
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("x", function(d) { return x(d["rank"]); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d["percentage"]); })
.attr("height", function(d) { return height - y(d["percentage"]); })
.style("fill", function(d) { return color(d["group"]); })
.style("stroke", "black")
.style("stroke-width", 0.5)
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(d["rank"] + ": " + d["percentage"] + "%")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
</script>
</body>
</html>