fix heatmap months legend

This commit is contained in:
Davide Scaini
2026-03-29 11:11:54 +02:00
parent ee98704562
commit eadfb1a0fa
+33 -46
View File
@@ -106,6 +106,10 @@
const now = new Date(); const now = new Date();
const years = [now.getFullYear(), now.getFullYear()-1, now.getFullYear()-2, now.getFullYear()-3]; const years = [now.getFullYear(), now.getFullYear()-1, now.getFullYear()-2, now.getFullYear()-3];
function localISO(d: Date): string {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}
function getWeeks(year: number): string[][] { function getWeeks(year: number): string[][] {
const jan1 = new Date(year, 0, 1); const jan1 = new Date(year, 0, 1);
const dec31 = new Date(year, 11, 31); const dec31 = new Date(year, 11, 31);
@@ -118,8 +122,7 @@
while (cur <= end) { while (cur <= end) {
const week: string[] = []; const week: string[] = [];
for (let d = 0; d < 7; d++) { for (let d = 0; d < 7; d++) {
const iso = cur.toISOString().slice(0, 10); week.push(cur.getFullYear() === year ? localISO(cur) : '');
week.push(cur.getFullYear() === year ? iso : '');
cur.setDate(cur.getDate() + 1); cur.setDate(cur.getDate() + 1);
} }
weeks.push(week); weeks.push(week);
@@ -130,18 +133,6 @@
const DOW = ['M', 'T', 'W', 'T', 'F', 'S', 'S']; const DOW = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function monthLabels(weeks: string[][]): Array<{ month: string; col: number }> {
const seen = new Set<string>();
return weeks.flatMap((week, i) => {
const day = week.find(d => d);
if (!day) return [];
const m = MONTHS[parseInt(day.slice(5, 7)) - 1];
if (seen.has(m)) return [];
seen.add(m);
return [{ month: m, col: i }];
});
}
function cellTitle(date: string): string { function cellTitle(date: string): string {
if (!date) return ''; if (!date) return '';
const sportMap = byDateBySport.get(date); const sportMap = byDateBySport.get(date);
@@ -205,7 +196,6 @@
<!-- Heatmaps per year --> <!-- Heatmaps per year -->
{#each years as year} {#each years as year}
{@const weeks = getWeeks(year)} {@const weeks = getWeeks(year)}
{@const labels = monthLabels(weeks)}
{@const yt = totalsByYear.get(year)} {@const yt = totalsByYear.get(year)}
{#if yt} {#if yt}
<div class="mb-8"> <div class="mb-8">
@@ -217,41 +207,38 @@
</div> </div>
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<div class="inline-block"> <div class="inline-flex gap-[3px]">
<!-- Month labels --> <!-- Day-of-week labels: blank slot at top to align with month row -->
<div class="flex mb-1 ml-6"> <div class="flex flex-col gap-[3px] mr-1">
{#each labels as { month, col }} <div class="h-4" />
<span {#each DOW as d, i}
class="text-xs text-zinc-500 absolute" <span class="text-[9px] text-zinc-600 h-[10px] leading-[10px] w-3 text-right">
style="left: calc({col} * 13px)" {i % 2 === 1 ? d : ''}
>{month}</span> </span>
{/each} {/each}
<div style="width:{weeks.length * 13}px" />
</div> </div>
<!-- Week columns: month label at top, day cells below -->
<!-- Grid --> {#each weeks as week, wi}
<div class="flex gap-[3px]"> {@const firstDay = week.find(d => d)}
<!-- Day-of-week labels --> {@const prevFirstDay = wi > 0 ? weeks[wi - 1].find(d => d) : null}
<div class="flex flex-col gap-[3px] mr-1"> {@const showMonth = firstDay && (!prevFirstDay || prevFirstDay.slice(5, 7) !== firstDay.slice(5, 7))}
{#each DOW as d, i} <div class="flex flex-col gap-[3px]">
<span class="text-[9px] text-zinc-600 h-[10px] leading-[10px] w-3 text-right"> <div class="h-4 relative">
{i % 2 === 1 ? d : ''} {#if showMonth}
</span> <span class="text-[10px] text-zinc-500 absolute left-0 top-0 whitespace-nowrap">
{MONTHS[parseInt(firstDay.slice(5, 7)) - 1]}
</span>
{/if}
</div>
{#each week as date}
<div
class="w-[10px] h-[10px] rounded-[2px]"
style="background:{cellColors.get(date) ?? '#27272a'}"
title={cellTitle(date)}
/>
{/each} {/each}
</div> </div>
<!-- Weeks --> {/each}
{#each weeks as week}
<div class="flex flex-col gap-[3px]">
{#each week as date}
<div
class="w-[10px] h-[10px] rounded-[2px]"
style="background:{cellColors.get(date) ?? '#27272a'}"
title={cellTitle(date)}
/>
{/each}
</div>
{/each}
</div>
</div> </div>
</div> </div>