Report: drop Stage 0 lane, flip 5→1 axis, fix Actual label clipping
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.
This commit is contained in:
@@ -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({
|
||||
</p>
|
||||
</div>
|
||||
<ol className="mt-4 space-y-2">
|
||||
{[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 (
|
||||
|
||||
Reference in New Issue
Block a user