From 8dfbbea0bac7b32d62309ff79b3618552327098b Mon Sep 17 00:00:00 2001
From: Joel Brock
Date: Thu, 11 Jun 2026 13:39:42 -0700
Subject: [PATCH] =?UTF-8?q?Report:=20drop=20Stage=200=20lane,=20flip=205?=
=?UTF-8?q?=E2=86=921=20axis,=20fix=20Actual=20label=20clipping?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DateTimeline now skips section rank 0 (intake) and renders stage lanes
top-to-bottom 5→1, matching how the framework actually numbers stages.
MembershipChart's latest-Actual label was placed at the circle's
x + 6, which overflowed the SVG when the most-recent point landed near
the right padding. Anchor it to xOf(maxT) - 4 with textAnchor="end",
mirroring the Goal label so both endpoint labels stay inside the chart.
---
components/report/DateTimeline.tsx | 19 ++++++++++---------
components/report/MembershipChart.tsx | 7 +++++--
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/components/report/DateTimeline.tsx b/components/report/DateTimeline.tsx
index 14e5299..a538175 100644
--- a/components/report/DateTimeline.tsx
+++ b/components/report/DateTimeline.tsx
@@ -5,13 +5,14 @@ import { formatShortDate } from "./FieldHistory";
/**
* Date-grouped timeline strip at the top of the report. Walks every
- * date-type field across all stage sections (0–5), pulls each field's
- * most-recent entered date, and plots events into six horizontal swim
- * lanes — one per stage. Stage 5's `Date_Opened` gets visual emphasis
- * as the journey's anchor at the right end of the time axis. A faint
- * "Today" tick anchors the reader if today falls within the range, and
- * an adaptive month/year axis runs beneath the lanes. Each dot exposes
- * a tooltip on hover or keyboard focus.
+ * date-type field across stage sections 1–5, pulls each field's
+ * most-recent entered date, and plots events into five horizontal swim
+ * lanes — one per stage, Stage 5 on top down to Stage 1 at the bottom.
+ * Stage 5's `Date_Opened` gets visual emphasis as the journey's anchor
+ * at the right end of the time axis. A faint "Today" tick anchors the
+ * reader if today falls within the range, and an adaptive month/year
+ * axis runs beneath the lanes. Each dot exposes a tooltip on hover or
+ * keyboard focus.
*/
export function DateTimeline({
sections,
@@ -28,7 +29,7 @@ export function DateTimeline({
};
const events: Event[] = [];
for (const section of sections) {
- if (section.rank < 0 || section.rank > 5) continue;
+ if (section.rank < 1 || section.rank > 5) continue;
for (const f of section.fields) {
if (f.type !== "date") continue;
const history = fieldHistory[f.name];
@@ -80,7 +81,7 @@ export function DateTimeline({
- {[0, 1, 2, 3, 4, 5].map((rank) => {
+ {[5, 4, 3, 2, 1].map((rank) => {
const rowEvents = events.filter((e) => e.rank === rank);
const isEmpty = rowEvents.length === 0;
return (
diff --git a/components/report/MembershipChart.tsx b/components/report/MembershipChart.tsx
index 1aae037..beff998 100644
--- a/components/report/MembershipChart.tsx
+++ b/components/report/MembershipChart.tsx
@@ -281,11 +281,14 @@ export function MembershipChart({
/>
))}
- {/* Most-recent point value labels */}
+ {/* Most-recent point value labels. Both anchor to the chart's right
+ edge so the carry-forward endpoint label stays inside the viewBox
+ instead of overflowing past the right padding. */}
{actualCoords.length > 0 && (
{numberFmt.format(actualCoords[actualCoords.length - 1].v)}