Extend the daily charts from 7 to 14 days

Sleep, daily counts and food grams now share a 14-day window like the
pattern charts. Bar gaps tighten to fit 14 columns and the x-axis
labels today plus every second day so labels don't collide; tooltips
and click-through per bar are unchanged.
This commit is contained in:
Alexander Heldt
2026-07-13 20:45:22 +00:00
parent c103082ca5
commit a0e084dae8
3 changed files with 37 additions and 22 deletions
+32 -18
View File
@@ -814,12 +814,14 @@
if (e.target === lightbox) lightbox.close();
});
// ---------- weekly charts ----------
// ---------- daily charts (last 14 days) ----------
const CHART_DAYS = 14;
function weeklyData(events) {
const today = startOfDay(new Date());
const now = Date.now();
const days = [];
for (let i = 6; i >= 0; i--) {
for (let i = CHART_DAYS - 1; i >= 0; i--) {
const d = new Date(today);
d.setDate(d.getDate() - i);
const from = startOfDay(d).getTime();
@@ -846,6 +848,12 @@
return date.toLocaleDateString(undefined, { weekday: "short" });
}
// With 14 columns there is no room for a label under every bar, so label
// today and every second day counting back from it.
function showDayLabel(i, len) {
return (len - 1 - i) % 2 === 0;
}
// Pick a chart Y maximum and tick count so every tick label is a clean
// whole number (avoids 0, 0, 1, 1, 2 from rounding fractional steps):
// 1-unit gridlines up to 10, 2-unit up to 20, 5-unit beyond.
@@ -911,7 +919,7 @@
const rawMax = Math.max(...days.map(d => d.sleepHours));
const { yMax, steps: ySteps } = niceAxisSleepHours(rawMax);
const gap = 6;
const gap = 4;
const barW = (innerW - (days.length - 1) * gap) / days.length;
const parts = [];
@@ -934,10 +942,12 @@
`x="${x}" y="${y}" width="${barW}" height="${Math.max(0, h)}" rx="3">` +
`<title>${escapeText(title)}</title></rect>`
);
parts.push(
`<text x="${x + barW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
if (showDayLabel(i, days.length)) {
parts.push(
`<text x="${x + barW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
}
});
setChartSVG(svg, parts);
@@ -953,8 +963,8 @@
const rawMax = Math.max(...days.flatMap(d => [d.pees, d.poos, d.meals]));
const { yMax, steps: ySteps } = niceAxis(rawMax);
const groupGap = 6;
const innerBarGap = 2;
const groupGap = 4;
const innerBarGap = 1.5;
const groupW = (innerW - (days.length - 1) * groupGap) / days.length;
const barW = (groupW - 2 * innerBarGap) / 3;
@@ -989,10 +999,12 @@
);
});
parts.push(
`<text x="${groupX + groupW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
if (showDayLabel(i, days.length)) {
parts.push(
`<text x="${groupX + groupW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
}
});
setChartSVG(svg, parts);
@@ -1013,7 +1025,7 @@
const { yMax, steps: ySteps } = niceAxisGrams(Math.max(...days.map(d => d.grams)));
const gap = 6;
const gap = 4;
const barW = (innerW - (days.length - 1) * gap) / days.length;
const parts = [];
@@ -1036,10 +1048,12 @@
`x="${x}" y="${y}" width="${barW}" height="${Math.max(0, h)}" rx="3">` +
`<title>${escapeText(title)}</title></rect>`
);
parts.push(
`<text x="${x + barW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
if (showDayLabel(i, days.length)) {
parts.push(
`<text x="${x + barW / 2}" y="${H - MB + 14}" text-anchor="middle">` +
`${escapeText(dayLabel(d.date, isToday))}</text>`
);
}
});
setChartSVG(svg, parts);