diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cab0d2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +test.html +activity.json diff --git a/assets/css/heatmap.css b/assets/css/heatmap.css new file mode 100644 index 0000000..9fcc765 --- /dev/null +++ b/assets/css/heatmap.css @@ -0,0 +1,6 @@ +:root{ + --color-empty: #F5F5F5; + --color-low: #BDD7EE; + --color-mid: #2E86C1; + --color-high: #1A5276 +} diff --git a/assets/js/build_heatmap.js b/assets/js/build_heatmap.js new file mode 100644 index 0000000..549374d --- /dev/null +++ b/assets/js/build_heatmap.js @@ -0,0 +1,73 @@ +export function flattenData(raw) { + const result = {}; + for (const [date, repos] of Object.entries(raw)) { + result[date] = Object.values(repos).reduce((sum, n) => sum + n, 0); + } + return result; +} + +export function constructWeeks() { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + const start = new Date(today); + start.setDate(today.getDate() - 52 * 7); + start.setDate(start.getDate() - start.getDay()); + + const weeks = []; + const cur = new Date(start); + while (cur <= today) { + const week = []; + for (let d = 0; d < 7; d++) { + const day = new Date(cur); + week.push(day <= today ? day : null); + cur.setDate(cur.getDate() + 1); + } + weeks.push(week); + } + return weeks; +} + +function getColor(count) { + if (count === 0) return "var(--color-empty)"; + if (count <= 3) return "var(--color-low)"; + if (count <= 10) return "var(--color-mid)"; + return "var(--color-high)"; +} + +export function render(weeks, counts) { + const CELL = 13; + const GAP = 2; + const SHIFT = CELL + GAP; + + const svgNS = "http://www.w3.org/2000/svg"; + const svg = document.createElementNS(svgNS, "svg"); + + svg.setAttribute("width", weeks.length * SHIFT + 30); + svg.setAttribute("height", SHIFT * 7 + 20); + + weeks.forEach((week, col) => { + week.forEach((day, row) => { + if (day === null) { + return; + } + const key = day.toISOString().slice(0, 10); // Get the key in yyyy-mm-dd format + + const count = counts[key] || 0; + + const rect = document.createElementNS(svgNS, "rect"); + rect.setAttribute("x", col * SHIFT + 30); + rect.setAttribute("y", row * SHIFT); + rect.setAttribute("height", CELL); + rect.setAttribute("width", CELL); + rect.setAttribute("fill", getColor(count)); + rect.setAttribute("rx", 2); + rect.setAttribute("data-date", key); + rect.setAttribute("data-count", count); + + svg.appendChild(rect); + }); + + document.getElementById("heatmap").appendChild(svg); + }); +}