- {t("insights.subPage.stats.selectedRange")}
-
- ) : undefined
- }
- />
+
) : null}
{cells.map((cell) => (
diff --git a/src/components/insights/sub-page-shell.tsx b/src/components/insights/sub-page-shell.tsx
index c4dc0a8d1..32bfaac3a 100644
--- a/src/components/insights/sub-page-shell.tsx
+++ b/src/components/insights/sub-page-shell.tsx
@@ -262,11 +262,11 @@ export function SubPageShell({
brand-new-metric paths. Numbers-first is the Apple-Health /
Withings / Oura detail-screen convention.
- v1.12.7 — the stats are chart-reactive: when the user brushes a
- window in the chart below, the page lifts the chart's per-type
- windowed Min / Max / Median / Mean and threads it back into the
- strip, which swaps the header to a "selected range" pill. No
- selection falls back to the cheap full-range summary. */}
+ v1.12.8 — the stats are chart-reactive: the chart reports the
+ per-type Min / Max / Median / Mean for the data under its active
+ range tab (7 / 30 / 90 / All), and the page threads it back into the
+ strip so the numbers always reflect the range the chart paints. No
+ drag, no pill — the range tab is the single selector. */}
{statStrip}
{/* v1.12.6 — the canonical spine body: intro (header) → stat strip
(above) → chart → target card → assessment. The page renders
diff --git a/src/hooks/use-chart-domain-stats.ts b/src/hooks/use-chart-domain-stats.ts
index 90f06361d..a243d0b65 100644
--- a/src/hooks/use-chart-domain-stats.ts
+++ b/src/hooks/use-chart-domain-stats.ts
@@ -5,38 +5,34 @@ import { useCallback, useRef, useState } from "react";
import type { MetricWindowStats } from "@/lib/charts/window-stats";
/**
- * v1.12.7 — chart-reactive metric statistics.
+ * v1.12.8 — chart-reactive metric statistics.
*
- * A metric sub-page lifts this hook so its ``
- * (which mounts a Recharts ``) and its `` read the
- * same brushed window. The chart reports the per-type Min / Max / Median /
- * Mean for the selected domain through `onDomainStats`; the strip reads
- * `statsByType[type]` and, when present, renders the windowed numbers in
- * place of the full-range summary.
+ * A metric sub-page lifts this hook so its `` and its
+ * `` read the same window. The chart reports the per-type
+ * Min / Max / Median / Mean for the data currently visible under its active
+ * range tab (the 7 / 30 / 90 / All selector) through `onVisibleStats`; the
+ * strip reads `statsByType[type]` and renders those windowed numbers.
*
- * `null` (no selection, or a selection that collapsed to under one point)
- * means "show the full range" — the strip falls back to the precomputed
- * summary, so the default is unchanged and costs no extra work. The chart
- * owns the maths (it already holds the bucketed series), so the hook only
- * stores what it is handed and exposes a stable callback.
+ * `null` (no data, or mini mode) means "show the full range" — the strip
+ * falls back to the precomputed summary. The chart owns the maths (it already
+ * holds the bucketed series), so the hook only stores what it is handed and
+ * exposes a stable callback.
*
* The callback is referentially stable across renders so it can sit in the
- * chart's effect dependency list without re-firing. A shallow guard skips
- * the state write when the chart reports the same window twice in a row,
- * keeping a drag that lands on the same indices from thrashing the strip.
+ * chart's effect dependency list without re-firing. A shallow guard skips the
+ * state write when the chart reports the same window twice in a row, keeping a
+ * re-render that recomputes the same slice from thrashing the strip.
*/
export interface ChartDomainStats {
/**
- * Per-type windowed stats, keyed by `MeasurementType`. Null means no
- * active selection (full range). A type may be absent from the map when
- * its series has no readings inside the brushed window — the strip falls
- * back to the full-range summary for that series.
+ * Per-type windowed stats, keyed by `MeasurementType`. Null means the chart
+ * has not reported a slice yet (or has no data). A type may be absent from
+ * the map when its series has no readings in the visible range — the strip
+ * falls back to the full-range summary for that series.
*/
statsByType: Record | null;
- /** True while a sub-range is selected (drives the "selected range" label). */
- isWindowed: boolean;
- /** Stable callback handed to ``. */
- onDomainStats: (stats: Record | null) => void;
+ /** Stable callback handed to ``. */
+ onVisibleStats: (stats: Record | null) => void;
}
export function useChartDomainStats(): ChartDomainStats {
@@ -46,11 +42,11 @@ export function useChartDomainStats(): ChartDomainStats {
> | null>(null);
const lastRef = useRef("null");
- const onDomainStats = useCallback(
+ const onVisibleStats = useCallback(
(stats: Record | null) => {
- // Cheap shallow signature so an identical brush window (a drag that
- // settles on the same indices, or a re-render that recomputes the
- // same slice) doesn't re-set state and re-render the strip.
+ // Cheap shallow signature so an identical window (a re-render that
+ // recomputes the same slice) doesn't re-set state and re-render the
+ // strip.
const signature = stats === null ? "null" : JSON.stringify(stats);
if (signature === lastRef.current) return;
lastRef.current = signature;
@@ -61,7 +57,6 @@ export function useChartDomainStats(): ChartDomainStats {
return {
statsByType,
- isWindowed: statsByType !== null,
- onDomainStats,
+ onVisibleStats,
};
}