Skip to content

Instantly share code, notes, and snippets.

@snaka
Created January 26, 2016 17:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snaka/f88d0540c46d50cf3eaf to your computer and use it in GitHub Desktop.
Save snaka/f88d0540c46d50cf3eaf to your computer and use it in GitHub Desktop.
Qiitaへの投稿アクティビティをGithubのように表示
/*
フォームの入力内容を元にAPIに問い合わせ
*/
$("#form").on("submit", function(e) {
$("#btn-submit").prop("disabled", true);
var user_id = $("#user_id").val()
$.ajax({
type: "GET",
url: "http://qiita.com/api/v2/users/" + user_id + "/items?page=1&per_page=100",
success: onSucceed
});
e.preventDefault();
});
// 日付のフォーマット
var format = d3.time.format("%Y-%m-%d");
/*
APIから受け取った情報を元にカレンダー描画
*/
function onSucceed(data) {
var item_dates = {};
$.each(data, function(idx, val) {
var created_at = format(d3.time.day.floor(new Date(val['created_at'])));
if (created_at in item_dates)
item_dates[created_at]++;
else
item_dates[created_at] = 1;
});
drawCalendar(item_dates);
$("#btn-submit").prop("disabled", false);
}
/*
カレンダーの描画
*/
var drawCalendar = (function() {
// セルの1辺のサイズ
var CELL_SIZE = 15;
// カレンダ表示のマージン
var MARGIN_LEFT = 25;
var MARGIN_TOP = 15;
var dataset = null;
var color = null;
var countScale = null;
// 日付の計算
var addDays = function(sourceDate, days) {
result = new Date(sourceDate);
result.setDate(sourceDate.getDate() + days);
return result;
};
// 表示する日付の範囲(過去1年間)
var rangeBegin = addDays(new Date, -365);
var rangeEnd = new Date;
var dateRange = d3.time.days(rangeBegin, rangeEnd);
var monthRange = d3.time.months(rangeBegin, rangeEnd);
// カレンダのオフセット値を算出する関数
var createOffsetFunc = function() {
var firstYearOffset = d3.time.weekOfYear(rangeBegin) * -1;
var bounderyDate = d3.time.years(rangeBegin, rangeEnd)[0];
var lastDayOfFirstYear = addDays(bounderyDate, -1);
var lastWeekOfFirstYear = d3.time.weekOfYear(lastDayOfFirstYear);
var lastYearOffset = d3.time.weekOfYear(lastDayOfFirstYear) + firstYearOffset;
return function(sourceDate) {
if (sourceDate.getFullYear() == rangeBegin.getFullYear())
return firstYearOffset;
return lastYearOffset;
}
};
// メイン処理:カレンダー描画
return function(dataset) {
// 件数を3段階に分類
var countScale = d3.scale.linear()
.domain([1, d3.max(d3.values(dataset))])
.rangeRound([1, 3]) // 3段階で色分け
.clamp(true);
// 分類ごとに色分け
var colorScale = d3.scale.ordinal()
.domain([1, 2, 3])
.range(["#f7fcb9","#addd8e","#31a354"]);
// 上記をまとめるスケール関数
var color = function(f) {
return colorScale(countScale(f));
};
// svg要素の作成
var svg = d3.select(".weed");
svg.selectAll("*").remove();
svg.append("g");
// 日毎の矩形を生成
var offset = createOffsetFunc();
var rect = svg.selectAll(".day")
.data(dateRange)
.enter()
.append("rect")
.attr("class", "day")
.attr("width", CELL_SIZE - 1)
.attr("height", CELL_SIZE - 1)
.attr("x", function(d){ return (d3.time.weekOfYear(d) + offset(d)) * CELL_SIZE + MARGIN_LEFT; })
.attr("y", function(d){ return d.getDay() * CELL_SIZE + MARGIN_TOP; })
.attr("fill", "rgb(230,230,230)")
.datum(format);
// ツールチップ設定
rect.append("title")
.text(function(d){ return d; });
// 投稿のあった日のツールチップと背景色を設定
rect.filter(function(d){ return d in dataset; })
.attr("fill", function(d){ return color(dataset[d]); })
.select("title")
.text(function(d){ return d + " (投稿:" + dataset[d] + "件)"; });
// 曜日のラベル
dayLabels = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
svg.selectAll(".dayLabel")
.data([0, 1, 2, 3, 4, 5, 6])
.enter()
.append("text")
.attr("class", "dayLabel")
.attr("x", 0)
.attr("y", function(d){ return d * CELL_SIZE + 11 + MARGIN_TOP; })
.attr("font-size", 11)
.attr("fill", "gray")
.text(function(d){ return dayLabels[d]; });
// 月のラベル
monthLabels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
svg.selectAll(".monthLabel")
.data(monthRange)
.enter()
.append("text")
.attr("class", "monthLabel")
.attr("x", function(d){ return (d3.time.weekOfYear(d) + offset(d)) * CELL_SIZE + MARGIN_LEFT; })
.attr("y", 11)
.attr("font-size", 11)
.attr("fill", "gray")
.text(function(d){ return monthLabels[d.getMonth()]; });
} // return function
})(); // drawCalendar
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment