From 103a5f993707cad3fa4ae7ffccbb4315063ef35a Mon Sep 17 00:00:00 2001 From: Alexander Heldt Date: Fri, 4 Sep 2026 15:11:30 +0000 Subject: [PATCH] Mark now on the day-long charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hour heatmap and the two actograms all run midnight to midnight, and none of them said where in that span you currently are. On the heatmap that made the darkest block ambiguous: a column at 18h is either a habit or simply the hour you are standing in with the rest of the day not yet lived. On the actograms it hid the reason today's row stops early — it stops at now, not at bedtime. One rule serves all three. drawActogram already draws both timelines, so the line lands there once, and the heatmap appends the same parts after its hit rects. Ink over a surface-coloured underlay, the same treatment the timing chart's "since the last one" marker uses, so it stays readable crossing a shaded sleep window, a dark cell or bare track. A caret hangs above the track to keep it from reading as one more hour gridline, and the whole thing is pointer-events: none so it cannot swallow a tap meant for the row underneath. Deliberately not the accent colour: on these charts accent already means "the selected day", and now is a different kind of fact. The captions gain a clause naming the marker, which runs against the last few commits taking captions away. Those removed lines restated what the picture already said. This one does not: a thin vertical line has no inherent meaning, and unlike darker-means-more there is nothing to infer it from. --- src/app.js | 28 +++++++++++++++++++++++++++- src/changelog.json | 1 + src/index.html | 6 +++--- src/style.css | 7 +++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/app.js b/src/app.js index aba96a8..87b702f 100644 --- a/src/app.js +++ b/src/app.js @@ -1587,6 +1587,28 @@ // ---------- pattern charts ---------- + // Where "now" falls in the day, 0..1 — the shared x for the charts that run + // midnight to midnight. + function nowDayFraction() { + const now = new Date(); + return (now.getTime() - startOfDay(now).getTime()) / 86_400_000; + } + + // Vertical "now" rule for those charts: ink over a surface-coloured underlay + // so it stays legible whatever bar or cell it crosses, with a caret hung + // above the track so it doesn't read as one more gridline. Append the parts + // last so the rule sits on top; it ignores pointer events, so the rows and + // cells underneath stay tappable. + function nowRuleParts(x, yTop, yBottom) { + const xs = x.toFixed(1); + return [ + ``, + ``, + ``, + ]; + } + // Actogram: one row per day (oldest at top), a midnight-to-midnight track // with the given windows shaded. Windows are clipped to each day, so one that // crosses midnight shows correctly split across two rows, and an open one @@ -1647,6 +1669,10 @@ parts.push(`${escapeText(title)}`); } + // The window always ends today, so one rule marks both the live edge of the + // bottom row and the same time of day on every row above it. + parts.push(...nowRuleParts(xOf(nowDayFraction()), MT, H - MB)); + setChartSVG(svg, parts); // wires the .bar[data-day] click → select that day } @@ -1894,7 +1920,7 @@ } parts.push(`24h`); - svg.innerHTML = parts.concat(hits).join(""); + svg.innerHTML = parts.concat(hits, nowRuleParts(ML + nowDayFraction() * innerW, MT, H - MB)).join(""); // tooltips only ever show on a pointer, which left phones with no // way to read a block's count. Tapping (or hovering) a block names it in diff --git a/src/changelog.json b/src/changelog.json index e1c4b45..70fb1df 100644 --- a/src/changelog.json +++ b/src/changelog.json @@ -1,4 +1,5 @@ [ + { "date": "2026-09-04", "text": "The three day-long charts — “By hour of day”, “When sleeping” and “When walking” — now mark the current time with a small vertical line and caret. On the sleeping and walking rows it also shows where today's row stops, and it lines the same clock position up across every day above it" }, { "date": "2026-09-01", "text": "Removed the walking goal from the Walk trend — the dashed target line, its legend chip and the ✓ that marked a day as met. It came from the “five-minute rule” (five minutes per month of age, twice a day), which is a widely repeated rule of thumb rather than veterinary guidance, and the app was stating it more confidently than it deserved. The chart is now just a record of what you walked, against yesterday and the average" }, { "date": "2026-09-01", "text": "The 7d / 14d / 30d buttons have moved out of the Sleep panel onto their own “Charts cover” row, just under the Log event buttons. They always set the window for every chart on the page — training, timing, sleep, walks, pees/poos/meals — but sitting inside the Sleep panel made them look like a sleep setting" }, { "date": "2026-09-01", "text": "Dropped the “Darker = more sessions that day” caption under the training consistency grid. Tapping a cell still opens that day" }, diff --git a/src/index.html b/src/index.html index a4c4b20..9927d24 100644 --- a/src/index.html +++ b/src/index.html @@ -251,7 +251,7 @@ <section class="patterns" data-panel="sleep-timeline"> <h2><span id="sleep-timeline-title">When sleeping</span> <span class="muted-note" data-chart-days-label>(last 7 days)</span></h2> <svg id="chart-sleep-timeline" class="chart-svg" viewBox="0 0 320 125" role="img" aria-label="Sleep periods per day"></svg> - <p class="muted-note">Each row is a day, midnight to midnight; shaded = asleep. Tap a row to open that day.</p> + <p class="muted-note">Each row is a day, midnight to midnight; shaded = asleep. The marker is now. Tap a row to open that day.</p> </section> <section class="patterns" data-panel="sleep-trend"> @@ -288,7 +288,7 @@ <div class="chart-title">By hour of day</div> <svg id="chart-hour-heatmap" class="chart-svg" viewBox="0 0 320 120" role="img" aria-label="Pee, poo and meal frequency by hour of day"></svg> <p id="hour-heatmap-info" class="muted-note hour-point-info" aria-live="polite"></p> - <p class="muted-note">Darker = happens more often at that hour.</p> + <p class="muted-note">Darker = happens more often at that hour; the marker is now.</p> </div> </section> @@ -308,7 +308,7 @@ <section class="patterns" data-panel="walk-timeline" hidden> <h2><span id="walk-timeline-title">When walking</span> <span class="muted-note" data-chart-days-label>(last 7 days)</span></h2> <svg id="chart-walk-timeline" class="chart-svg" viewBox="0 0 320 125" role="img" aria-label="Walks per day"></svg> - <p class="muted-note">Each row is a day, midnight to midnight; shaded = out on a walk. Tap a row to open that day.</p> + <p class="muted-note">Each row is a day, midnight to midnight; shaded = out on a walk. The marker is now. Tap a row to open that day.</p> </section> <section class="patterns" data-panel="walk-trend" hidden> diff --git a/src/style.css b/src/style.css index 51c2361..c3f2e93 100644 --- a/src/style.css +++ b/src/style.css @@ -1109,6 +1109,13 @@ input.switch:checked::after { transform: translateX(18px); } .chart-svg .stl-hit { fill: transparent; cursor: pointer; } .chart-svg .stl-hit:hover { fill: var(--accent); fill-opacity: 0.08; } +/* "Now" rule on the midnight-to-midnight charts (actograms + hour heatmap): + ink over a surface-coloured underlay so it reads over any shaded window or + cell, and never eats a tap meant for the row underneath. */ +.chart-svg .now-rule-ring { stroke: var(--surface); stroke-width: 3; pointer-events: none; } +.chart-svg .now-rule { stroke: var(--text); stroke-width: 1; opacity: 0.75; pointer-events: none; } +.chart-svg .now-rule-cap { fill: var(--text); opacity: 0.75; pointer-events: none; } + /* Sleep trend lines: today strongest, the reference curves lighter/dashed. */ .chart-svg .trend-today { stroke: var(--sleep);