Skip to content

sleep: responsive round-hour time axis for the stepped hypnogram - #1130

Merged
ryanbr merged 2 commits into
mainfrom
feat/hypnogram-time-axis
Aug 7, 2026
Merged

sleep: responsive round-hour time axis for the stepped hypnogram#1130
ryanbr merged 2 commits into
mainfrom
feat/hypnogram-time-axis

Conversation

@ryanbr

@ryanbr ryanbr commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Follow-up to the Filled/Ribbon sleep chart — the axis was fixed at three labels (onset · midpoint · wake). This makes it the reference's richer axis:

  • Exact onset/wake anchor the edges, round-hour marks fill the middle (23:28 · 02:00 · 04:00 · 06:00 · 08:00 · 10:25).
  • Responsive to screen width — ~one label per 90 dp, so a Fold/tablet shows more marks, a phone fewer (as requested).

How

  • hypnogramAxisTicks (pure, unit-tested): picks a nice hour step (1/2/3/4/6/8/12) so the interior count fits maxLabels; drops marks within ~8 % of an edge so they can't collide with onset/wake; anchors the exact edges.
  • HypnogramTimeAxis: a Layout (not a weighted row) that centres each label on its true time fraction, clamped to stay on-screen — so labels line up with the axis hairlines drawn at the same fractions above.
  • Applies to both Filled and Ribbon (shared component); Classic's proportional strip is unchanged.

Scope

Android only; display-only. compileFullDebugKotlin + HypnogramAxisTicksTest (edges exact, interior strictly-between, wider→more marks, zero-span→single tick) pass.

ryanbr added 2 commits August 7, 2026 23:12
The Filled/Ribbon chart's axis was fixed at three labels (onset · midpoint ·
wake). Replace it with the reference's richer axis: the EXACT onset/wake at the
edges plus round-HOUR marks between (23:28 · 02:00 · 04:00 … · 10:25), and make
the number of marks RESPONSIVE to screen width (~one label per 90dp, so a Fold/
tablet shows more, a phone fewer).

hypnogramAxisTicks (pure, unit-tested) picks a nice hour step (1/2/3/4/6/8/12)
so the interior count fits maxLabels, drops marks within ~8% of an edge so they
can't collide with onset/wake, and anchors the exact edges. HypnogramTimeAxis
places each label CENTRED on its true time fraction via a Layout (not a weighted
row), clamped to stay on-screen, so labels line up with the axis hairlines drawn
at the same fractions. Applies to both Filled and Ribbon (shared component);
Classic's proportional strip is unchanged.

Android only. compileFullDebugKotlin + HypnogramAxisTicksTest pass.
- Read LocalConfiguration.current UNCONDITIONALLY (was inside the showsAxis if;
  it's @ReadOnlyComposable so it compiled, but the unconditional read is the
  safe idiom).
- Widen the interior edge-drop guard 0.08 -> 0.12: on a phone the onset/wake
  labels are ~a tenth of the width, so a round-hour mark landing at ~0.08-0.12
  could overlap them. 0.12 gives clearance.
@ryanbr
ryanbr merged commit 4ab29d1 into main Aug 7, 2026
3 checks passed
@ryanbr
ryanbr deleted the feat/hypnogram-time-axis branch August 7, 2026 11:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant