fix: make Max wait readable in chart tooltip and legend
Build and Deploy / Lint, typecheck, test (push) Successful in 31s
Build and Deploy / Build & Push (push) Successful in 1m6s

The Max bar uses a dark fill with bright stroke for the outlined look,
but Recharts pulled tooltip/legend text color from the dark fill — making
the Max row unreadable against the dark tooltip background. Render the
tooltip via a custom content fn and recolor the legend's Max label so
both pick up the bright stroke color instead.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 09:38:20 -04:00
parent 0dc84c7597
commit 2e9cec0b56
+38 -14
View File
@@ -27,6 +27,9 @@ function shortDay(localDate: string): string {
export default function WeeklyStatsChart({ data, hasFastLane, mode }: Props) {
const showFastLane = mode === "fastLane" && hasFastLane;
const avgColor = showFastLane ? "#ff4d8d" : "#4ade80";
const maxColor = showFastLane ? "#ff4d8d" : "#22c55e";
const maxFill = showFastLane ? "#3d0f22" : "#0a1a0d";
const chartData = data.map((d) => ({
day: shortDay(d.localDate),
avg: showFastLane
@@ -43,22 +46,43 @@ export default function WeeklyStatsChart({ data, hasFastLane, mode }: Props) {
<XAxis dataKey="day" stroke="#737373" tick={{ fontSize: 11, fill: "#737373" }} tickLine={false} />
<YAxis stroke="#737373" tick={{ fontSize: 11, fill: "#737373" }} tickLine={false} axisLine={false} />
<Tooltip
contentStyle={{
background: "#1c1c1c",
border: "1px solid #333",
borderRadius: 6,
fontSize: "0.75rem",
color: "#f5f5f5",
}}
labelStyle={{ color: "#b0b0b0" }}
formatter={(value, name) => {
if (value === null || value === undefined) return ["—", name];
return [`${value} min`, name];
cursor={{ fill: "rgba(255,255,255,0.04)" }}
content={({ active, payload, label }) => {
if (!active || !payload || payload.length === 0) return null;
return (
<div
style={{
background: "#1c1c1c",
border: "1px solid #333",
borderRadius: 6,
fontSize: "0.75rem",
padding: "8px 12px",
lineHeight: 1.5,
}}
>
<div style={{ color: "#b0b0b0", marginBottom: 2 }}>{label}</div>
{payload.map((entry) => {
const color = entry.dataKey === "max" ? maxColor : avgColor;
const v = entry.value;
const display = v === null || v === undefined ? "—" : `${v} min`;
return (
<div key={String(entry.dataKey)} style={{ color }}>
{entry.name} : {display}
</div>
);
})}
</div>
);
}}
/>
<Legend wrapperStyle={{ fontSize: "0.72rem", paddingTop: 4 }} />
<Bar name="Avg" dataKey="avg" fill={showFastLane ? "#ff4d8d" : "#4ade80"} radius={[3, 3, 0, 0]} isAnimationActive={false} />
<Bar name="Max" dataKey="max" fill={showFastLane ? "#3d0f22" : "#0a1a0d"} stroke={showFastLane ? "#ff4d8d" : "#22c55e"} strokeWidth={1} radius={[3, 3, 0, 0]} isAnimationActive={false} />
<Legend
wrapperStyle={{ fontSize: "0.72rem", paddingTop: 4 }}
formatter={(value) =>
value === "Max" ? <span style={{ color: maxColor }}>{value}</span> : value
}
/>
<Bar name="Avg" dataKey="avg" fill={avgColor} radius={[3, 3, 0, 0]} isAnimationActive={false} />
<Bar name="Max" dataKey="max" fill={maxFill} stroke={maxColor} strokeWidth={1} radius={[3, 3, 0, 0]} isAnimationActive={false} />
</BarChart>
</ResponsiveContainer>
</div>