mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
feat(charts): drop the explanatory line under day-linked charts
This commit is contained in:
1 parent
3c4e053dcd
commit
b7eef0dff4
15 files changed
+13
-119
No files matched your search
@@ -84,12 +84,9 @@ test.describe("every chart drawn in days opens its days", () => {
|
||||
.locator('[data-slot="chart-plot"][data-day-links="true"]')
|
||||
.first();
|
||||
await expect(plot).toBeVisible();
|
||||
// Under the chart: the caption and the row of day dots, which draws the
|
||||
// Under the chart: the row of day dots, which draws the
|
||||
// days the index names, one of them ringed as notable.
|
||||
const rug = page.locator('[data-slot="day-rug"]').first();
|
||||
await expect(
|
||||
page.locator('[data-slot="chart-day-caption"]').first(),
|
||||
).toBeVisible();
|
||||
await expect(rug.locator("[data-day]").first()).toBeAttached();
|
||||
await expect(rug.locator('[data-notable="true"]')).toHaveCount(1);
|
||||
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Einige Bereiche sind für dich nicht freigegeben.",
|
||||
"inTimeline": "In der Zeitleiste",
|
||||
"askCoach": "Im Coach nach diesem Tag fragen",
|
||||
"chartHint": "Klick auf einen Punkt öffnet den Tag.",
|
||||
"loadFailed": "Dieser Tag konnte nicht geladen werden.",
|
||||
"dayOf": "Tag {n} von {m}",
|
||||
"dayN": "Tag {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Erfassen",
|
||||
"inTimelineShort": "Zeitleiste",
|
||||
"askCoachPrompt": "Was war am {date}?",
|
||||
"chartHintTouch": "Antippen zeigt den Wert.",
|
||||
"chartHintBar": "Klick auf einen Balken öffnet den Tag.",
|
||||
"chartHintTouchBar": "Antippen zeigt die Werte.",
|
||||
"chartHintCell": "Klick auf einen Tag öffnet ihn.",
|
||||
"chartHintTouchCell": "Antippen zeigt den Wert des Tages.",
|
||||
"coachChips": "Tage in dieser Antwort",
|
||||
"description": "Alles, was deine Einträge für diesen Tag enthalten.",
|
||||
"openDocument": "Dokument öffnen",
|
||||
"previousReading": "Vorher, {date}",
|
||||
"rugLegend": "Punkte unter der Achse markieren Tage mit Einträgen, ein Ring einen auffälligen Tag.",
|
||||
"sheetExpand": "Auf volle Höhe aufziehen",
|
||||
"sheetShrink": "Verkleinern",
|
||||
"valuesLegend": "Punkt für diesen Tag, Strich für die 30 Tage davor",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Some areas are not shared with you.",
|
||||
"inTimeline": "In the timeline",
|
||||
"askCoach": "Ask the Coach about this day",
|
||||
"chartHint": "Click a point to open its day.",
|
||||
"loadFailed": "This day could not be loaded.",
|
||||
"dayOf": "Day {n} of {m}",
|
||||
"dayN": "Day {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Log",
|
||||
"inTimelineShort": "Timeline",
|
||||
"askCoachPrompt": "What happened on {date}?",
|
||||
"chartHintTouch": "Tap a point to see its value.",
|
||||
"chartHintBar": "Click a bar to open its day.",
|
||||
"chartHintTouchBar": "Tap a bar to see its values.",
|
||||
"chartHintCell": "Click a day to open it.",
|
||||
"chartHintTouchCell": "Tap a day to see its value.",
|
||||
"coachChips": "Days in this answer",
|
||||
"description": "Everything your records hold for this day.",
|
||||
"openDocument": "Open document",
|
||||
"previousReading": "Before, {date}",
|
||||
"rugLegend": "Dots under the axis mark days with entries, a ring marks a notable day.",
|
||||
"sheetExpand": "Expand to full height",
|
||||
"sheetShrink": "Shrink",
|
||||
"valuesLegend": "Dot for this day, bar for the 30 days before",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Algunas áreas no están compartidas contigo.",
|
||||
"inTimeline": "En la cronología",
|
||||
"askCoach": "Preguntar al Coach por este día",
|
||||
"chartHint": "Haz clic en un punto para abrir su día.",
|
||||
"loadFailed": "No se pudo cargar este día.",
|
||||
"dayOf": "Día {n} de {m}",
|
||||
"dayN": "Día {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Registrar",
|
||||
"inTimelineShort": "Cronología",
|
||||
"askCoachPrompt": "¿Qué pasó el {date}?",
|
||||
"chartHintTouch": "Toca un punto para ver su valor.",
|
||||
"chartHintBar": "Haz clic en una barra para abrir su día.",
|
||||
"chartHintTouchBar": "Toca una barra para ver sus valores.",
|
||||
"chartHintCell": "Haz clic en un día para abrirlo.",
|
||||
"chartHintTouchCell": "Toca un día para ver su valor.",
|
||||
"coachChips": "Días en esta respuesta",
|
||||
"description": "Todo lo que tus registros contienen para este día.",
|
||||
"openDocument": "Abrir documento",
|
||||
"previousReading": "Antes, {date}",
|
||||
"rugLegend": "Los puntos bajo el eje marcan días con entradas, y un anillo, un día destacado.",
|
||||
"sheetExpand": "Ampliar a toda la altura",
|
||||
"sheetShrink": "Reducir",
|
||||
"valuesLegend": "Punto para este día, barra para los 30 días anteriores",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Certaines rubriques ne sont pas partagées avec vous.",
|
||||
"inTimeline": "Dans la chronologie",
|
||||
"askCoach": "Interroger le Coach sur ce jour",
|
||||
"chartHint": "Cliquez sur un point pour ouvrir son jour.",
|
||||
"loadFailed": "Impossible de charger ce jour.",
|
||||
"dayOf": "Jour {n} sur {m}",
|
||||
"dayN": "Jour {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Enregistrer",
|
||||
"inTimelineShort": "Chronologie",
|
||||
"askCoachPrompt": "Que s’est-il passé le {date} ?",
|
||||
"chartHintTouch": "Touchez un point pour voir sa valeur.",
|
||||
"chartHintBar": "Cliquez sur une barre pour ouvrir son jour.",
|
||||
"chartHintTouchBar": "Touchez une barre pour voir ses valeurs.",
|
||||
"chartHintCell": "Cliquez sur un jour pour l’ouvrir.",
|
||||
"chartHintTouchCell": "Touchez un jour pour voir sa valeur.",
|
||||
"coachChips": "Jours dans cette réponse",
|
||||
"description": "Tout ce que vos entrées contiennent pour ce jour.",
|
||||
"openDocument": "Ouvrir le document",
|
||||
"previousReading": "Avant, {date}",
|
||||
"rugLegend": "Les points sous l’axe marquent les jours avec entrées, un anneau un jour remarquable.",
|
||||
"sheetExpand": "Agrandir en pleine hauteur",
|
||||
"sheetShrink": "Réduire",
|
||||
"valuesLegend": "Point pour ce jour, barre pour les 30 jours précédents",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Alcune aree non sono condivise con te.",
|
||||
"inTimeline": "Nella cronologia",
|
||||
"askCoach": "Chiedi al Coach di questo giorno",
|
||||
"chartHint": "Fai clic su un punto per aprire il suo giorno.",
|
||||
"loadFailed": "Impossibile caricare questo giorno.",
|
||||
"dayOf": "Giorno {n} di {m}",
|
||||
"dayN": "Giorno {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Registra",
|
||||
"inTimelineShort": "Cronologia",
|
||||
"askCoachPrompt": "Cosa è successo il {date}?",
|
||||
"chartHintTouch": "Tocca un punto per vederne il valore.",
|
||||
"chartHintBar": "Fai clic su una barra per aprire il suo giorno.",
|
||||
"chartHintTouchBar": "Tocca una barra per vederne i valori.",
|
||||
"chartHintCell": "Fai clic su un giorno per aprirlo.",
|
||||
"chartHintTouchCell": "Tocca un giorno per vederne il valore.",
|
||||
"coachChips": "Giorni in questa risposta",
|
||||
"description": "Tutto ciò che le tue voci contengono per questo giorno.",
|
||||
"openDocument": "Apri documento",
|
||||
"previousReading": "Prima, {date}",
|
||||
"rugLegend": "I punti sotto l’asse indicano i giorni con voci, un anello un giorno rilevante.",
|
||||
"sheetExpand": "Espandi a tutta altezza",
|
||||
"sheetShrink": "Riduci",
|
||||
"valuesLegend": "Punto per questo giorno, barra per i 30 giorni precedenti",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "일부 영역은 공유되지 않았어요.",
|
||||
"inTimeline": "타임라인에서 보기",
|
||||
"askCoach": "이 날에 대해 코치에게 묻기",
|
||||
"chartHint": "점을 클릭하면 그날이 열려요.",
|
||||
"loadFailed": "이 날을 불러오지 못했어요.",
|
||||
"dayOf": "{m}일 중 {n}일째",
|
||||
"dayN": "{n}일째",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "기록",
|
||||
"inTimelineShort": "타임라인",
|
||||
"askCoachPrompt": "{date}에 무슨 일이 있었나요?",
|
||||
"chartHintTouch": "점을 탭하면 값이 보여요.",
|
||||
"chartHintBar": "막대를 클릭하면 그날이 열려요.",
|
||||
"chartHintTouchBar": "막대를 탭하면 값이 보여요.",
|
||||
"chartHintCell": "날짜 칸을 클릭하면 그날이 열려요.",
|
||||
"chartHintTouchCell": "날짜 칸을 탭하면 값이 보여요.",
|
||||
"coachChips": "이 답변에 쓰인 날",
|
||||
"description": "이 날에 대한 모든 기록이에요.",
|
||||
"openDocument": "문서 열기",
|
||||
"previousReading": "이전, {date}",
|
||||
"rugLegend": "축 아래 점은 기록이 있는 날을, 고리는 눈에 띄는 날을 표시해요.",
|
||||
"sheetExpand": "전체 높이로 펼치기",
|
||||
"sheetShrink": "줄이기",
|
||||
"valuesLegend": "점은 이 날, 막대는 직전 30일",
|
||||
|
||||
@@ -12254,7 +12254,6 @@
|
||||
"notShared": "Niektóre obszary nie są Ci udostępnione.",
|
||||
"inTimeline": "Na osi czasu",
|
||||
"askCoach": "Zapytaj Coacha o ten dzień",
|
||||
"chartHint": "Kliknij punkt, aby otworzyć jego dzień.",
|
||||
"loadFailed": "Nie udało się wczytać tego dnia.",
|
||||
"dayOf": "Dzień {n} z {m}",
|
||||
"dayN": "Dzień {n}",
|
||||
@@ -12276,16 +12275,10 @@
|
||||
"captureShort": "Zapisz",
|
||||
"inTimelineShort": "Oś czasu",
|
||||
"askCoachPrompt": "Co się działo {date}?",
|
||||
"chartHintTouch": "Dotknij punktu, aby zobaczyć wartość.",
|
||||
"chartHintBar": "Kliknij słupek, aby otworzyć jego dzień.",
|
||||
"chartHintTouchBar": "Dotknij słupka, aby zobaczyć wartości.",
|
||||
"chartHintCell": "Kliknij dzień, aby go otworzyć.",
|
||||
"chartHintTouchCell": "Dotknij dnia, aby zobaczyć jego wartość.",
|
||||
"coachChips": "Dni w tej odpowiedzi",
|
||||
"description": "Wszystko, co Twoje wpisy zawierają dla tego dnia.",
|
||||
"openDocument": "Otwórz dokument",
|
||||
"previousReading": "Wcześniej, {date}",
|
||||
"rugLegend": "Punkty pod osią oznaczają dni z wpisami, pierścień dzień godny uwagi.",
|
||||
"sheetExpand": "Rozwiń na pełną wysokość",
|
||||
"sheetShrink": "Zmniejsz",
|
||||
"valuesLegend": "Punkt to ten dzień, pasek to 30 dni wcześniej",
|
||||
|
||||
@@ -52,11 +52,10 @@ describe("<HealthChart> day links", () => {
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it("a metric page's chart opens its days: plot, caption and table", async () => {
|
||||
it("a metric page's chart opens its days: plot and table", async () => {
|
||||
const html = await renderChart({ dayLinks: true, showDataTable: true });
|
||||
expect(html).toContain('data-day-links="true"');
|
||||
expect(html).toContain('data-slot="chart-day-caption"');
|
||||
expect(html).toContain("Click a point to open its day.");
|
||||
expect(html).not.toContain('data-slot="chart-day-caption"');
|
||||
const links = html.match(/data-slot="day-link"/g) ?? [];
|
||||
expect(links).toHaveLength(10);
|
||||
expect(html).toMatch(/href="[^"]*\?day=\d{4}-\d{2}-\d{2}"/);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { ChartDayCaption } from "@/components/day/chart-day";
|
||||
import { dayAnchor } from "@/components/day/chart-day-links";
|
||||
import { OPEN_DAY_CELL, useHeatmapDay } from "@/components/day/heatmap-day";
|
||||
import { useCalendarDate } from "@/hooks/use-calendar-date";
|
||||
@@ -368,7 +367,6 @@ export function ComplianceHeatmap({
|
||||
</div>
|
||||
{activeCells.length > 0 ? (
|
||||
<>
|
||||
<ChartDayCaption coarse={heatmapDay.coarse} mark="cell" rug={false} />
|
||||
{/* The keyboard and screen-reader way to each active day's doses,
|
||||
and to the day itself. */}
|
||||
<ChartDataTable
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { ChartDayCaption, useCoarsePointer } from "@/components/day/chart-day";
|
||||
import { dayAnchor } from "@/components/day/chart-day-links";
|
||||
import { OPEN_DAY_CELL, useHeatmapDay } from "@/components/day/heatmap-day";
|
||||
import { useCalendarDate } from "@/hooks/use-calendar-date";
|
||||
@@ -102,14 +101,13 @@ export function MoodHeatmapBody({
|
||||
/**
|
||||
* The loading shape of the stretched heatmap, at exactly the height the
|
||||
* painted heatmap takes: the reserved grid box, the legend line, the day
|
||||
* caption and the data-table toggle. `days` is the window when it is already
|
||||
* data-table toggle. `days` is the window when it is already
|
||||
* known; without it the shape assumes a window short enough to reach the cell
|
||||
* ceiling on every width down to 360 px (eight weeks), the height most
|
||||
* calendars settle at.
|
||||
*/
|
||||
export function MoodHeatmapSkeleton({ days = 56 }: { days?: number }) {
|
||||
const timeZone = useDisplayTimezone();
|
||||
const coarse = useCoarsePointer();
|
||||
return (
|
||||
<div
|
||||
data-slot="mood-heatmap-skeleton"
|
||||
@@ -120,7 +118,6 @@ export function MoodHeatmapSkeleton({ days = 56 }: { days?: number }) {
|
||||
<div className="bg-muted/50 h-full w-full animate-pulse rounded-md motion-reduce:animate-none" />
|
||||
</MoodHeatmapBody>
|
||||
<div className="mt-2 h-4" />
|
||||
<ChartDayCaption coarse={coarse} mark="cell" rug={false} />
|
||||
<div className="border-border mt-3 border-t pt-3">
|
||||
<div className="min-h-11" />
|
||||
</div>
|
||||
@@ -411,7 +408,6 @@ export function MoodHeatmap({
|
||||
</div>
|
||||
{loggedCells.length > 0 ? (
|
||||
<>
|
||||
<ChartDayCaption coarse={heatmapDay.coarse} mark="cell" rug={false} />
|
||||
{/* The keyboard and screen-reader way to each logged day's value,
|
||||
and to the day itself. */}
|
||||
<ChartDataTable
|
||||
|
||||
@@ -173,7 +173,6 @@ export function NutrientDailyBarChart({
|
||||
links={chartDays}
|
||||
points={points.map((p) => ({ timestamp: dayAnchor(p.day) }))}
|
||||
axis="band"
|
||||
mark="bar"
|
||||
// The y axis (44) on the left, the margin (12) on the right.
|
||||
insetLeft={44}
|
||||
insetRight={12}
|
||||
|
||||
@@ -6,12 +6,10 @@ import type { DateKey } from "@/lib/day/contract";
|
||||
import { prefersReducedMotion } from "@/lib/charts/reduced-motion";
|
||||
|
||||
import {
|
||||
ChartDayCaption,
|
||||
DayRug,
|
||||
TooltipDayAction,
|
||||
useCoarsePointer,
|
||||
type ChartDayAxis,
|
||||
type ChartDayMark,
|
||||
} from "./chart-day";
|
||||
import { openDay, useOpenDay, type DayFocus } from "./day-layer-controller";
|
||||
import { isOpenableDay } from "./day-url";
|
||||
@@ -35,7 +33,7 @@ import { useTodayKey } from "./use-today-key";
|
||||
* days by accident;
|
||||
* - the open day is marked with `OPEN_DAY_LINE` (a dashed vertical line)
|
||||
* at `openIndex`;
|
||||
* - `ChartDayFooter` draws the row of day dots and the one-line caption.
|
||||
* - `ChartDayFooter` draws the row of day dots.
|
||||
*
|
||||
* The caller says, per drawn point and in data order, which calendar day the
|
||||
* point stands for, or `null` when it stands for none (a week or month
|
||||
@@ -190,7 +188,7 @@ export function useChartDayLinks({
|
||||
}
|
||||
|
||||
/**
|
||||
* The row of day dots and the caption under a day-linked chart. Nothing when
|
||||
* The row of day dots under a day-linked chart. Nothing when
|
||||
* the chart is not day-linked or draws no points.
|
||||
*/
|
||||
export function ChartDayFooter({
|
||||
@@ -199,7 +197,6 @@ export function ChartDayFooter({
|
||||
axis = "index",
|
||||
insetLeft,
|
||||
insetRight,
|
||||
mark = "point",
|
||||
}: {
|
||||
links: Pick<ChartDayLinks, "active" | "coarse"> &
|
||||
Partial<Pick<ChartDayLinks, "days">>;
|
||||
@@ -208,20 +205,16 @@ export function ChartDayFooter({
|
||||
axis?: ChartDayAxis;
|
||||
insetLeft: number;
|
||||
insetRight: number;
|
||||
mark?: ChartDayMark;
|
||||
}) {
|
||||
if (!links.active || points.length === 0) return null;
|
||||
return (
|
||||
<>
|
||||
<DayRug
|
||||
points={points}
|
||||
pointDays={links.days}
|
||||
axis={axis}
|
||||
insetLeft={insetLeft}
|
||||
insetRight={insetRight}
|
||||
/>
|
||||
<ChartDayCaption coarse={links.coarse} mark={mark} />
|
||||
</>
|
||||
<DayRug
|
||||
points={points}
|
||||
pointDays={links.days}
|
||||
axis={axis}
|
||||
insetLeft={insetLeft}
|
||||
insetRight={insetRight}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -257,41 +257,3 @@ export function DayRug({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* What a day-linked surface is made of, which names the thing to click in
|
||||
* the caption: a point on a line, a bar, or a cell of a calendar.
|
||||
*/
|
||||
export type ChartDayMark = "point" | "bar" | "cell";
|
||||
|
||||
const HINT_KEYS: Record<ChartDayMark, { fine: string; coarse: string }> = {
|
||||
point: { fine: "day.chartHint", coarse: "day.chartHintTouch" },
|
||||
bar: { fine: "day.chartHintBar", coarse: "day.chartHintTouchBar" },
|
||||
cell: { fine: "day.chartHintCell", coarse: "day.chartHintTouchCell" },
|
||||
};
|
||||
|
||||
/**
|
||||
* The one line under a day-linked chart: what the dots mean (when the chart
|
||||
* has the row of dots), and the click.
|
||||
*/
|
||||
export function ChartDayCaption({
|
||||
coarse,
|
||||
mark = "point",
|
||||
rug = true,
|
||||
}: {
|
||||
coarse: boolean;
|
||||
mark?: ChartDayMark;
|
||||
rug?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslations();
|
||||
const hint = HINT_KEYS[mark];
|
||||
return (
|
||||
<p
|
||||
data-slot="chart-day-caption"
|
||||
className="text-muted-foreground mt-1 flex flex-wrap justify-between gap-x-4 gap-y-1 text-xs"
|
||||
>
|
||||
{rug ? <span>{t("day.rugLegend")}</span> : null}
|
||||
<span>{coarse ? t(hint.coarse) : t(hint.fine)}</span>
|
||||
</p>
|
||||
);
|
||||
}
|
||||
@@ -606,7 +606,6 @@ export function SleepStageStackedBar({ breakdown }: SleepStageStackedBarProps) {
|
||||
: 0,
|
||||
}))}
|
||||
axis="band"
|
||||
mark="bar"
|
||||
// The plot's margin (8) + the y axis (60) on the left, the
|
||||
// margin (16) on the right.
|
||||
insetLeft={8 + 60}
|
||||
|
||||
Reference in new issue
Block a user