Fluid-github-contributions

本文最后更新于:2020年7月10日 下午

写在前面

之前推荐了一波echarts,寻思着做点什么,就想在about页面添加一个github的contributions的日历热力表,做个echarts很简单,不过数据咋来呢?

  • 直接扒GitHub官网的数据,格式如下,替代用户名即可
https://github.com/users/githubname/contributions

但是数据不太会弄,所以搜了下API接口。

https://github-contributions-api.now.sh/v1/githubname

再使用getJSON获取数据,其中存在一个异步问题,设置$.ajaxSettings.async = false;。下面在html中添加echart图表,需要修改$.getJSON( 'https://github-contributions-api.now.sh/v1/githubname')中的用户名。

使用echarts添加

<script src="https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js"></script>
<script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<div id="main" style="width:450px;height:200px;margin:0 auto;"></div>
<script>
    var myChart = echarts.init(document.getElementById('main'));

    function getVirtulData(year) {
        var date = +echarts.number.parseDate(year + '-01-01');
        var end = +echarts.number.parseDate((+year + 1) + '-01-01');
        var dayTime = 3600 * 24 * 1000;
        var data = [];
        var kk = 0;
        $.ajaxSettings.async = false;
        var jqxhr = $.getJSON( 'https://github-contributions-api.now.sh/v1/pxxyyz');
        console.log(jqxhr);
        for (var time = end; time >= date; time -= dayTime) {
            data.push([
                echarts.format.formatTime('yyyy-MM-dd', time),
                jqxhr.responseJSON.contributions[kk].count
                ]);
            kk = kk + 1;
        }
        return data;
    }

    var data = getVirtulData(2020);

    var option = {
        title: {
            text: 'github-contributions',
            link: 'https://github.com/pxxyyz',
            top: '0',
            left: '250',
            textStyle: {
                color: '#fff'
            }
        },
        backgroundColor: '#404a59',
        tooltip: {
            trigger: 'item'
        },
        legend: {
            top: '0',
            left: '30',
            data: ['contributions', 'Top 3'],
            textStyle: {
                color: '#fff'
            }
        },
        calendar: [{
            top: 80,
            left: 'center',
            range: ['2020-01-01', '2020-6-30'],
            cellSize: [15, 15],
            splitLine: {
                show: true,
                lineStyle: {
                    color: '#000',
                    width: 2,
                    type: 'solid'
                }
            },
            yearLabel: {
                position: 'top',
                formatter: '{start}',
                textStyle: {
                    color: '#fff'
                }
            },
            itemStyle: {
                normal: {
                    color: '#323c48',
                    borderWidth: 1,
                    borderColor: '#111'
                }
            }
        }],
        series: [
        {
            name: 'contributions',
            type: 'scatter',
            coordinateSystem: 'calendar',
            data: data,
            symbolSize: function (val) {
                return val[1]/3 ;
            },
            itemStyle: {
                normal: {
                    color: '#ddb926'
                }
            }
        },
        {
            name: 'Top 3',
            type: 'effectScatter',
            coordinateSystem: 'calendar',
            data: data.sort(function (a, b) {
                return b[1] - a[1];
            }).slice(0, 3),
            symbolSize: function (val) {
                return val[1]/3 ;
            },
            showEffectOn: 'render',
            rippleEffect: {
                brushType: 'stroke'
            },
            hoverAnimation: true,
            itemStyle: {
                normal: {
                    color: '#f4e925',
                    shadowBlur: 10,
                    shadowColor: '#333'
                }
            },
            zlevel: 1
        }
        ]
    };

    myChart.setOption(option);

        // 刷新调整
        window.onresize = function () {
            myChart.resize();
        }
    </script>

js 正则表达式

可能是直接用了别人的API,这两天发现我的贡献图出错,所以就自己做了一个数据处理方法,结果是一致的,不过就是比较慢。关键代码也贴出来

function getGithubContributions() {
    var dayTime = 3600 * 24 * 1000;
    var data = [];
    var kk = 0;
    $.ajaxSettings.async = false;
    var jqxhr = $.getJSON('https://gist.github.com.ru/pxxyyz/1a950e45a96c7308c7528658d44b5ecd?username=pxxyyz');
    var getstr = jqxhr.responseJSON.result.calendar;
    var numList = getstr.match(/(data-count="(.*?)(\"))/g);
    var numDate = getstr.match(/(\d{4})[-](\d{2})[-](\d{2})/g);
    var date = +echarts.number.parseDate(numDate[0]);
    var end = +echarts.number.parseDate(numDate[numDate.length - 1]);

    for (var time = date; time <= end; time += dayTime) {
        data.push([
            echarts.format.formatTime('yyyy-MM-dd', time),
            parseInt(numList[kk].match(/\d+/g)),
            ]);
        kk = kk + 1;
    }
    return [data, numDate[0], numDate[numDate.length - 1]];
}

代码也放到github-contributions上了。

效果

echart的好处是可以交互,不过这种方法比较耗时。下面给一种不可交互但能快速载入的方法。

gh-widget

简单的加入这两行代码[1]

<div id="github-widget" data-user="githubname" data-display="pop_repos,calendar"></div>
<script src="https://gh-widget.oyanglul.us/index.js"></script>

分析

Github Gist上新建一个文件。

require "nokogiri"
require "open-uri"
url = "https://github.com/users/#{params['username']}"+ "/contributions"
document = Nokogiri::HTML(open(url))
{
  :pop_repos => document.css('.js-pinned-items-reorder-list').to_html,
  :calendar => document.css('.js-calendar-graph-svg').to_html
}

配合js文件

var r = new XMLHttpRequest();
var widget = document.getElementById('github-widget');
var username, pathname = location.pathname.split('/');
if (location.hostname == 'gh-widget.oyanglul.us' && !!pathname[1]) username = pathname[1];
else if (widget.dataset.user) username = widget.dataset.user;
r.overrideMimeType("application/json");
r.open("GET", "https://gist.github.com.ru/jcouyang/aec5210828043d5505bd?username=" + username);
r.onreadystatechange = function() {
	if (r.readyState != 4 || r.status != 200) return;
	var response = JSON.parse(r.response.replace(/href=\\"\//g, 'href=\\"https://github.com/'));
	if (response.error) {
		widget.innerHTML = 'Oooooops, please make sure your name in "data-user" is a real person on github';
		return;
	}
	var result = response.result;
	var display = widget.dataset.display.split(',').forEach(function(d) {
		widget.innerHTML += result[d];
	})
};
r.send();
function appendCSS(name) {
	var stylesheet = document.createElement("link") stylesheet.setAttribute("rel", "stylesheet") stylesheet.setAttribute("href", name) document.getElementsByTagName("head")[0].appendChild(stylesheet)
}
appendCSS('//gh-widget.oyanglul.us/main.css');
appendCSS('//cdnjs.cloudflare.com/ajax/libs/octicons/3.1.0/octicons.css')

效果

上面的方法不能改变尺寸。此外该作者jcouyang还提供了一步产生svg图片。在Github Gist上新建一个文件。

require "nokogiri"
require "open-uri"
url = "https://github.com/users/#{params['username']}"+ "/contributions"
document = Nokogiri::HTML(open(url))
contrib_boxes = document.css('svg.js-calendar-graph-svg')[0]
contrib_boxes['xmlns']="http://www.w3.org/2000/svg"
width = (params['width']||54*13-2).to_i
height = (params['height']||89).to_i
contrib_boxes.css('text').remove
contrib_boxes['width']=(width+11).to_s+'px'
contrib_boxes['height']=(height+11).to_s+'px'
contrib_boxes.at_css('>g')['transform']='translate(0, 0)'
day_boxes = contrib_boxes.css('g>g')
day_boxes.each_with_index{|box, m|
  box['transform']="translate(#{m*((width-53*2)/54+2)}, 0)"
  box.css('rect.day').each_with_index{|col,n|
    col['height']=(height-12)/7
    col['width']=(width-53*2)/54
    col['y'] = col['y'].to_i-(11-(height-12)/7)*col['y'].to_i/13
  }
}
{
  :body => contrib_boxes.to_html,
  :content_type => 'image/svg+xml;charset=utf-8'
}

在调用如下网址得到

https://gist.github.com.ru/jcouyang/6336168ecbbf4fbdc46e.svg?username=githubname&width=400&height=60
https://gist.github.com.ru/jcouyang/6336168ecbbf4fbdc46e.png?username=pxxyyz&width=400&height=60;.png

效果

Github contribution

Github Chart API

找到一个类似的仓库:Github Chart API

<img src="https://ghchart.rshah.org/pxxyyz" alt="pxxyyz's Github chart" />

pxxyyz's Github chart

也可以改变颜色,如

<img src="https://ghchart.rshah.org/<HEX-COLOR>/2016rshah" alt="2016rshah's Blue Github Chart" />

pxxyyz's Blue Github Chart

Repository-Hunter

此外,Repository-Hunter仓库可返回svg文件

Github contribution

参考


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!