whisper-money/resources/js/components/charts
Víctor Falcón b9b507005f
feat(cashflow): expand income categories and fix Sankey label overlap (#672)
## Summary

Two improvements to the Cashflow Sankey chart, plus a fix reported for
real users whose chart rendered with overlapping labels.

### 1. Fix overlapping labels on small categories
recharts spaces same-column Sankey nodes by exactly `nodePadding` and
distributes the height **proportionally to value**, so tiny categories
end up separated by only that padding regardless of canvas height. It
was 24px while a two-line label is 30px tall, so adjacent labels
overlapped (e.g. *Regalos* / *Otros* in the monthly view, *Ingreso
desconocido* / *Pagos devueltos* in the yearly view).

Set `NODE_PADDING` above the label height so two adjacent labels can
never collide, whatever the bar size. This is independent of width, so
it fixes desktop and mobile alike.

### 2. Expand income categories (drill-down)
Income categories can now be drilled down into their subcategories,
mirroring the existing expense behaviour. The `sankey` endpoint already
returns both sides for a given `parent`, so this is frontend-only:

- The open drill-down is keyed by `{id, kind}` — a category can
legitimately appear on both the income and expense side.
- Income subcategories link `child -> parent` and form a column to the
**left** of the parent (expense subcategories stay on the right).
- The chart-height budget now accounts for the combined leftmost column
(income siblings + subcategories share it), so a many-source drill-down
can't drive recharts to a negative row scale and break the whole chart.
- The expand chevron points the way the column opens: income shows `<`
collapsed / `>` expanded; expense keeps `>` collapsed / `v` expanded.

The income/expense node-building was also de-duplicated into a single
helper.

## Test plan
- `sankey-chart.test.tsx`: 7 unit tests green (added income-expansion
coverage alongside the existing expense one).
- `tsc --noEmit`, `eslint`, `prettier` clean.
- Manual browser QA (Playwright) on a real account, desktop **and**
mobile: monthly + yearly views (overlap gone), expand income, switch to
expand expense (no regression), collapse, chevron direction, responsive
horizontal scroll.

## Demo

<!-- PLACEHOLDER: drag the demo video here -->
_📎 Attach the demo video here — file generated at
`~/Downloads/sankey-cashflow-demo.mp4`_
2026-07-13 07:28:14 +00:00
..
cashflow-trend-chart.tsx feat(cashflow): add savings and period views (#424) 2026-05-25 16:41:00 +02:00
chart-currency-toggle.test.tsx fix: default account charts to user currency (#271) 2026-04-10 14:41:36 +01:00
chart-currency-toggle.tsx fix: default account charts to user currency (#271) 2026-04-10 14:41:36 +01:00
chart-granularity-toggle.tsx fix(charts): use settings popover for chart controls on mobile (#137) 2026-02-19 16:53:00 +01:00
chart-settings-popover.tsx feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
chart-view-toggle.tsx fix(charts): use settings popover for chart controls on mobile (#137) 2026-02-19 16:53:00 +01:00
index.ts feat(settings): centralize currency options and split profile/account support (#256) 2026-04-02 19:23:10 +02:00
mom-chart.tsx fix: preserve cents in chart amounts (#270) 2026-04-10 15:41:24 +02:00
mom-percent-chart.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
sankey-chart.test.tsx feat(cashflow): expand income categories and fix Sankey label overlap (#672) 2026-07-13 07:28:14 +00:00
sankey-chart.tsx feat(cashflow): expand income categories and fix Sankey label overlap (#672) 2026-07-13 07:28:14 +00:00