JSFiddle - React, Tailwind, and code Playground

by devgru

CSS

body {
    margin: 0;
}
svg {
    width: 100%;
    height: 240px;
}

g text {
    font-size: 0.8em;
    text-anchor: middle;
}
g text.first {
    text-anchor: start;
}
g text.last {
    text-anchor: end;
}

JavaScript

var url = "https://api.github.com/repos/mbostock/d3/stats/punch_card"
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
var color = d3.scale.linear()
    .range(['#FEFEFF', 'blue'])
    .interpolate(d3.interpolateHcl)

d3.json(url, function (data) {
    var counts = data.map(function (d) {
        return d[2]
    })
    color.domain(d3.extent(counts))
    var dates = d3.nest()
        .key(function (d) { return d[0] })
        .entries(data)
    var hours = d3.nest()
        .key(function (d) { return d[1] })
        .entries(data)
    var daysMean = dates.map(function (v) { return d3.mean(v.values, function(d) { return d[2] }) })
    var hoursMean = hours.map(function (v) { return d3.mean(v.values, function(d) { return d[2] }) })
    var body = d3.select('body')
    var svg = body.append('svg')
    var heatmap = svg
        .append('g')
        .attr('transform', 'translate(30,30)')
        
    var span = svg
        .append('text')
        .attr('y', 11.5 * 20)
        .attr('x', 30)
    var head = svg
        .append('g')
        .attr('transform', 'translate(30,22)')
    head
        .append('text')
        .classed('first', true)
        .text('midnight')
    head
        .append('text')
        .attr('x', 12 * 20)
        .text('noon')
    head
        .append('text')
        .classed('last', true)
        .attr('x', 24 * 20)
        .text('midnight')
    
    var rows = heatmap
        .selectAll('g')
        .data(dates)
        .enter()
        .append('g')
    var cells = rows
        .selectAll('rect')
        .data(function (d) { return d.values })
        .enter()
        .append('rect')
        .attr('x', function (d, i) { return i * 20 })
        .attr('y', function (d, i, j) { return j * 20 })
        .attr('width', 20)
        .attr('height', 20)
        .style('fill', function (d) { return color(d[2]) })
        .on('mouseover', function (d) {
            span.text(d[2] + ' commits between ' + d[1] + ':00...