2019-12-24 15:02 — By Erik van Eykelen

Recreating GitHub's Punch Card With SVG and Ruby

Recently I searched for GitHub's punch card feature which used to be part of the Graphs aka Insights tab. It seems it's no longer available from the user interface. Luckily the GitHub API still offers an endpoint which spits out the data used by the punch card.

This is how my punch card looks like:

The data can be obtained by calling the API:

curl --request GET \
    --url https://api.github.com/repos/{username}/{reponame}/stats/punch_card \
    --header 'authorization: Bearer {personal-access-token}'

Set username to your GitHub user name, reponame to the repository name, and create a Personal Access Token.

The result of curl will be something like this:

[
  [
    0,
    0,
    0
  ],
  [
    0,
    1,
    0
  ],
  [
    0,
    2,
    0
  ],
  [
    0,
    3,
    0
  ],
  ...

The punch card statistics are delivered as an array of tuples. Each tuple looks like like [weekday, hour, nr_commits].

In order to visualize the data I looked for a way to generate SVG programmatically. The Victor Ruby gem is exactly what I needed.

A link to the full source code can be found below. It's cool though to see how easy it is to render an SVG using Ruby and Victor:

Create a new SVG:

svg = Victor::SVG.new(width: '1120', height: '370', viewBox: "0 0 1120 370")

Render the weekdays:

xoff = 130
yoff = 80
g(font_size: 18, font_family: 'Helvetica', fill: '#555') do
  %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday].each_with_index do |day, idx|
    text(day, x: xoff, y: yoff + (idx * 40), 'text-anchor': 'end')
  end
end

Render a circle:

circle(cx: 10, cy: 20, r: 10, fill: '#ccc')

The least trivial thing was to display tooltips containing the number of commits when hovering over a cell. It turns out you need to create a rect containing a title to do this. Since each circle has a different radius I decided to draw a transparent rect on top of each cell making the hit box for each tooltip as big as possible.

Full source code

Check out my products Releasewise, a project inbox for product owners and Sprouted, easy and encrypted user management.