Repository navigation
fix(purchases): Savings History chart x-axis start, tooltip decimals, y-axis tick instability (QA 2.2/2.3/2.4) #1252
Description
Summary
Three visual bugs in the Purchases page Savings History chart, identified in QA session 596.
QA 2.2 -- x-axis starts at purchase date, not period start
Symptom: The leftmost tick on the Savings History chart is the date of the first data point returned by the API, not the start of the selected period. Selecting "Last 30 days" with a recent first purchase shows a chart that starts mid-period, making the empty left portion invisible.
Root cause: The chart used a default category x-axis with a labels array derived from data point timestamps. Chart.js category axes position the first tick at the first label, ignoring the period start entirely.
Fix: Converted datasets to {x: timestamp_ms, y: value} objects and switched the x-axis to type:'linear' with min = period start (ms) and max = now (ms), mirroring the Home dashboard chart fix from PR #746. A tick.callback formats timestamps using the shared formatTrendAxisTick helper (extracted to frontend/src/modules/chart-utils.ts).
QA 2.3 -- Period Savings tooltip shows 4 decimal places vs Cumulative 2
Symptom: Hovering over the chart shows "Period Savings: $25.5678/mo" (4 decimals) while "Cumulative Savings: $25.57" shows 2 decimals. The KPI box above uses 2 decimals. Inconsistent presentation.
Root cause: The tooltip label callback used value.toFixed(4) for dataset index 0 (Period Savings) but value.toFixed(2) for dataset index 1 (Cumulative).
Fix: Changed toFixed(4) to toFixed(2) for Period Savings so both series and the KPI use the same 2-decimal precision.
QA 2.4/2.5 -- y-axis tick behavior changes oddly when toggling series
Symptom: Clicking the legend to toggle a dataset causes the y-axis tick step to change (e.g. 0.2 -> 0.1) and the cumulative y1-axis to show duplicate integer labels (e.g. "$0", "$0", "$1", "$1") when the domain is narrow.
Root cause: Neither y-axis had a maxTicksLimit, so Chart.js re-autoscaled freely on every toggle. The y1 tick formatter used toFixed(0) which collapses nearby float ticks to the same integer string.
Fix: Added maxTicksLimit: 6 to both y and y1 tick configs. Updated the y1 formatter to distinguish integer ticks (no decimals) from float ticks (2 decimals), preventing label collision when the autoscaled domain is narrow.
Testing
- New regression tests added in
frontend/src/__tests__/savings-history.test.ts:- QA 2.2: asserts
x-axis type === 'linear'with numericminequal to period start - QA 2.3: asserts Period Savings tooltip has exactly 2 decimal places matching Cumulative
- QA 2.4: asserts both y-axes have
maxTicksLimit - QA 2.5: asserts y1 formatter does not collapse distinct float ticks to the same integer label
- QA 2.2: asserts
All 83 tests in savings-history.test.ts pass. npx tsc --noEmit reports no errors.
Activity
fix(purchases): correct Savings History chart axis, tooltip decimals,…
fix(purchases): correct Savings History chart axis, tooltip decimals,…
fix(purchases): correct Savings History chart axis, tooltip decimals,…
fix(purchases): correct Savings History chart axis, tooltip decimals,…
fix(purchases): correct Savings History chart axis, tooltip decimals,…