diff --git a/src/app.js b/src/app.js index 93dd366..15d0e75 100644 --- a/src/app.js +++ b/src/app.js @@ -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">` + `${escapeText(title)}` ); - parts.push( - `` + - `${escapeText(dayLabel(d.date, isToday))}` - ); + if (showDayLabel(i, days.length)) { + parts.push( + `` + + `${escapeText(dayLabel(d.date, isToday))}` + ); + } }); 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( - `` + - `${escapeText(dayLabel(d.date, isToday))}` - ); + if (showDayLabel(i, days.length)) { + parts.push( + `` + + `${escapeText(dayLabel(d.date, isToday))}` + ); + } }); 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">` + `${escapeText(title)}` ); - parts.push( - `` + - `${escapeText(dayLabel(d.date, isToday))}` - ); + if (showDayLabel(i, days.length)) { + parts.push( + `` + + `${escapeText(dayLabel(d.date, isToday))}` + ); + } }); setChartSVG(svg, parts); diff --git a/src/changelog.json b/src/changelog.json index c9b0fe9..b136aad 100644 --- a/src/changelog.json +++ b/src/changelog.json @@ -1,4 +1,5 @@ [ + { "date": "2026-07-13", "text": "The sleep, daily counts and food charts now cover the last 14 days instead of 7" }, { "date": "2026-07-13", "text": "The awake/asleep timer lives in the frozen top bar" }, { "date": "2026-07-13", "text": "The day picker is a bar frozen at the top of the page" }, { "date": "2026-07-13", "text": "Attach multiple photos to an event — the photo picker now also offers the gallery with multi-select" }, diff --git a/src/index.html b/src/index.html index 9df038e..8f1cf9e 100644 --- a/src/index.html +++ b/src/index.html @@ -176,14 +176,14 @@
-

Last 7 days

+

Last 14 days

Sleep (hours)
- +
Daily counts
- +
Pees Poos @@ -192,7 +192,7 @@