Wouldst Thou Like to Github Language Stats Deliciously?

Ok, so this post will be a bit shorter because it is basically an update that adds real data to a script from a previous post here.  Here’s the updated bl.ock.

Basically, the D3 bar chart (D3js rules, other chart libraries drool) went from this:


To this (gifs by recordit.co):


Here’s the new JSFiddle and here’s the updated gist and here’s the updated bl.ock.

Note: I originally thought the numbers provided via Github’s ‘languages_url’ were lines of code.  Turns out they are bytes of code.  The gif above has the old labels which say ‘lines’, but I have updated the actual code.

I added a nested xmlhttprequest (aka, AJAX request) to get my github repo stats.  The language data requires an extra call per repo in order to get the byte count:

var respData = {};

/* put in your Github username! */
var urls = ['https://api.github.com/users/<username>/repos'];
/* **************************** */

var requester = function(url, flag, callback) {
var gitReq = new XMLHttpRequest();
gitReq.onload = function() {
if ((gitReq.status >= 200) && (gitReq.status <= 400)) {
var gitJson = JSON.parse(gitReq.response);
if (flag) {
var langArray = gitJson.map(function(repo) {
return repo.languages_url;

langArray.forEach(function(langUrl, i) {
if (i < langArray.length-1) {
return requester(langUrl, false, false);
if (i === langArray.length-1) {
return requester(langUrl, false, function(rawData) {
return grapher(rawData);
} else {
var keys = Object.keys(respData);
for (let lang in gitJson) {
if (keys.includes(lang)) {
respData[lang] = respData[lang] + gitJson[lang];
} else {
respData[lang] = gitJson[lang];
if (callback) {
return callback(respData);
} else {
return alert('Response status:', gitReq.status);
gitReq.open('GET', url);
urls.forEach(function(url) {
requester(url, true, false);

And then I changed the y-axis scale from a linear scale to a logarithmic scale because the difference between the number of bytes of code per language was too great:

/* set y to scaleLinear() if you prefer */
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLog().rangeRound([height, 0]);
/* ********************************** */

x.domain(data.map(function(d) { return d.language; }));

/* set the beginning of your scale if you need to */
y.domain([750, d3.max(data, function(d) { return d.frequency; })]);
/* ********************************************** */

And I also added these tooltips on mouseover (there’s some CSS too that I won’t show here):

// Define the div for the tooltip
var tip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);

var bars = d3.selectAll(".bar");
bars.each(function(d, i) {
var self = d3.select(this);
self.on('mouseover', function() {
let color = self.style('fill');
self.style('opacity', 0.45);
.style("opacity", 1.0);
tip.html(d.language + ":
"  + d.frequency + ' bytes')
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 90) + "px")
.style('color', color);
}).on('mouseout', function() {
self.style('opacity', 1.0);
.style("opacity", 0);

One thought on “Wouldst Thou Like to Github Language Stats Deliciously?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s