Stack Pace/HR charts vertically at double height instead of side by side

Each chart now takes the full card width and 200px height (was 100px,
half-width side by side), making the phase bands, target range, and
per-second trace much easier to read.
This commit is contained in:
2026-07-19 16:41:30 +02:00
parent db4c76b558
commit 82f08c0c1e
2 changed files with 5 additions and 6 deletions

View File

@@ -228,14 +228,13 @@ button:disabled {
.expected-actual-charts { .expected-actual-charts {
display: flex; display: flex;
flex-direction: column;
gap: 1rem; gap: 1rem;
flex-wrap: wrap;
margin: 0.5rem 0; margin: 0.5rem 0;
} }
.mini-chart { .mini-chart {
flex: 1 1 220px; width: 100%;
min-width: 180px;
} }
.mini-chart-label { .mini-chart-label {

View File

@@ -67,7 +67,7 @@ function robustDomain(actualValues: Array<number | null | undefined>, targetValu
// Picks a small number of evenly-spaced ticks across the domain, each // Picks a small number of evenly-spaced ticks across the domain, each
// snapped to a round increment (30s for pace, 5-20bpm for HR depending on // snapped to a round increment (30s for pace, 5-20bpm for HR depending on
// range). A fixed, small count -- rather than every increment in range -- // range). A fixed, small count -- rather than every increment in range --
// keeps labels legible and non-overlapping in a ~100px-tall mini chart. // keeps labels legible and non-overlapping in a ~200px-tall mini chart.
// Recharts' own collision-avoidance would otherwise silently drop most of a // Recharts' own collision-avoidance would otherwise silently drop most of a
// denser tick set anyway. // denser tick set anyway.
function niceTicks([lo, hi]: [number, number], step: number, count = 3): number[] { function niceTicks([lo, hi]: [number, number], step: number, count = 3): number[] {
@@ -304,7 +304,7 @@ export function ExpectedVsActualChart({ laps, samples }: { laps: Lap[]; samples:
)} )}
<div className="mini-chart"> <div className="mini-chart">
<span className="mini-chart-label">Pace{hasPaceTarget ? " vs target" : ""}</span> <span className="mini-chart-label">Pace{hasPaceTarget ? " vs target" : ""}</span>
<ResponsiveContainer width="100%" height={100}> <ResponsiveContainer width="100%" height={200}>
<AreaChart data={points} margin={{ top: 4, right: 4, bottom: 0, left: 4 }}> <AreaChart data={points} margin={{ top: 4, right: 4, bottom: 0, left: 4 }}>
{phaseBands.map((b, i) => ( {phaseBands.map((b, i) => (
<ReferenceArea key={i} x1={b.x1} x2={b.x2} fill={b.color} fillOpacity={0.18} strokeOpacity={0} /> <ReferenceArea key={i} x1={b.x1} x2={b.x2} fill={b.color} fillOpacity={0.18} strokeOpacity={0} />
@@ -325,7 +325,7 @@ export function ExpectedVsActualChart({ laps, samples }: { laps: Lap[]; samples:
</div> </div>
<div className="mini-chart"> <div className="mini-chart">
<span className="mini-chart-label">HR{hasHRTarget ? " vs target" : ""}</span> <span className="mini-chart-label">HR{hasHRTarget ? " vs target" : ""}</span>
<ResponsiveContainer width="100%" height={100}> <ResponsiveContainer width="100%" height={200}>
<AreaChart data={points} margin={{ top: 4, right: 4, bottom: 0, left: 4 }}> <AreaChart data={points} margin={{ top: 4, right: 4, bottom: 0, left: 4 }}>
{phaseBands.map((b, i) => ( {phaseBands.map((b, i) => (
<ReferenceArea key={i} x1={b.x1} x2={b.x2} fill={b.color} fillOpacity={0.18} strokeOpacity={0} /> <ReferenceArea key={i} x1={b.x1} x2={b.x2} fill={b.color} fillOpacity={0.18} strokeOpacity={0} />