mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
feat(charts): storyboard annotations on HealthChart
Add an additive annotations[] prop to <HealthChart> that paints a vertical Recharts <ReferenceLine> per AI-narrated event on the underlying timeline. The line + tooltip + comparison overlay remain untouched — annotations sit between the cartesian grid and the data lines so they read as orientation, never as data. The /insights page wires advisor.payload.insights.storyboardAnnotations into the 90-day BP chart, mapping the four canonical categories to Dracula colours (medication=pink, event=cyan, milestone=green, warning=orange). Pure helper resolveAnnotationPositions() handles the date->pointIndex mapping with a 7-day snap window (so annotations don't stack on monthly buckets) and a 24-char truncation for the small-viewport label. The unit suite pins exact-day pinning, near-day snapping, out-of-window dropping, and label truncation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f1868453af
commit
ff1e335c19
3 files changed
+279
No files matched your search
@@ -890,6 +890,33 @@ export default function InsightsPage() {
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// v1.4.20 phase B4 — storyboard annotations for the 90-day BP chart.
|
||||
// The advisor payload may carry up to 20 entries; we transform them
|
||||
// into the {date, label, color} shape <HealthChart> consumes. The
|
||||
// colour map mirrors the four canonical categories. Cached payloads
|
||||
// from before PROMPT_VERSION 4.20.2 simply produce an empty array.
|
||||
const STORYBOARD_COLOR_BY_CATEGORY: Record<string, string> = {
|
||||
medication: "var(--dracula-pink)",
|
||||
event: "var(--dracula-cyan)",
|
||||
milestone: "var(--dracula-green)",
|
||||
warning: "var(--dracula-orange)",
|
||||
};
|
||||
const rawStoryboard = (
|
||||
advisor.payload?.insights as
|
||||
| { storyboardAnnotations?: Array<{
|
||||
date: string;
|
||||
label: string;
|
||||
category: string;
|
||||
}> }
|
||||
| undefined
|
||||
)?.storyboardAnnotations;
|
||||
const bpStoryboardAnnotations = (rawStoryboard ?? []).map((entry) => ({
|
||||
date: entry.date,
|
||||
label: entry.label,
|
||||
color:
|
||||
STORYBOARD_COLOR_BY_CATEGORY[entry.category] ?? "var(--dracula-purple)",
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<HeroStrip
|
||||
@@ -997,6 +1024,7 @@ export default function InsightsPage() {
|
||||
yAxisUnit="Hg"
|
||||
targetZones={bpTargetZones}
|
||||
compareBaseline={compareBaseline}
|
||||
annotations={bpStoryboardAnnotations}
|
||||
/>
|
||||
|
||||
<div className="grid gap-4 xl:grid-cols-2">
|
||||
|
||||
Reference in new issue
Block a user