Skip to content

fix(reports): let the charts say which line is which, and what they measured - #153

Merged
KenTaniguchi-R merged 1 commit into
mainfrom
fix/147-charts
Sep 2, 2026
Merged

fix(reports): let the charts say which line is which, and what they measured#153
KenTaniguchi-R merged 1 commit into
mainfrom
fix/147-charts

Conversation

@KenTaniguchi-R

Copy link
Copy Markdown
Owner

The charts third of #147, built to the treatments picked from the chart decisions mock. Information design (PR C) follows.

Stacked on #152#151#150.

Trends: the palette cannot carry ten lines — or eight

The visible bug: up to 10 categories selectable, 8 palette slots, CHART_COLORS[i % 8] — the 9th and 10th lines repeat the 1st and 2nd outright.

The measured bug is worse. I ran the palette through a CVD validator:

check adjacent pairs all pairs
CVD separation pass, worst ΔE 9.2 deutan fail, worst ΔE 1.6 deutan
normal vision pass fail, worst ΔE 7.1 (floor is 15)

The eight slots are spaced for adjacent pairs — a legend read top to bottom, like the donut's. Overlapping lines are read against every other line. I tested all 28 five-colour and 28 six-colour subsets in both light and dark: none passes. Four is the ceiling, measured rather than preferred. MAX_TREND_SERIES = 4, and the checkbox row says Comparing 4 of 4 with the rest dimmed instead of silently ignoring clicks.

Second defect, unreported: colour came from position in the filtered list, so unchecking one category repainted every remaining line — a line changed colour without changing meaning. It keys off the category now. Since 18 categories share 8 slots, two selected eight apart can still collide; every line is labelled at its right-hand end, so identity never rests on colour alone.

Third defect: type="monotone" smoothed a curve through three monthly totals, drawing spending on days no money moved. Straight segments now, with a dot at each month — the dots are the measurement, the line between them is inference.

Net Worth: no legend, and a headline made of noise

Three series (net worth area, assets dashed, liabilities solid) and no <Legend> — identity by colour alone, and only on hover. Added.

The Change tile divided by any non-zero opening balance. A $5.15 opening turned a $534 gain into +10381.3% as the tile's secondary figure. Below a $100 base the tile now shows the absolute change with "from a near-zero opening balance" instead of a silent gap. A single snapshot yields no percentage either — "0%" would describe a period the data doesn't cover.

Money Flow: nodes with no amounts

The Sankey named its nodes and never said how much flowed through them — the one question the diagram exists to answer. Values sit beside the name in muted ink, not the node's own colour, which would read as a fourth encoding. Nodes too thin for a label keep their value in the tooltip.

Tests

Two pure modules, colocated:

  • src/lib/net-worth-change.test.ts — 9 tests: the +10381.3% case suppressed, a meaningful base kept, magnitude cutoff so a negative opening still qualifies, boundary at and one cent under the cutoff, zero opening, single point, no points.
  • src/lib/series-colors.test.ts — 4 tests: a category's colour doesn't depend on what else is selected, the first eight take the palette in published order, an unknown category gets the neutral rather than a guessed hue, and the cap stays within what the palette separates.

Full suite: 1086 passed, 1 failed — investment-queries.test.ts > returns dayChange from holdings_history, pre-existing date rot on clean main.

Verification

  • Trends draws four distinct hues with end labels. Unchecking Rent/Mortgage left the survivors on chart-2/3/4 rather than shifting them to chart-1/2/3 — measured before and after in the DOM.
  • Net Worth legend reads Assets / Liabilities / Net Worth; the tile keeps +2.1% on a base that earns one.
  • Sankey reads Salary · $23,100.00, Rent/Mortgage · $6,750.00, Groceries · $1,891.26, Car Payment · $1,389.53, Savings · $9,694.67 — matching the mock's proposal table exactly.

🤖 Generated with Claude Code

…easured

The charts half of #147.

Trends selected up to ten categories from a palette of eight and took
`CHART_COLORS[i % 8]`, so the 9th and 10th lines repeated the 1st and 2nd
outright. Running the palette through a CVD validator showed the deeper
problem: its eight slots are spaced for *adjacent* pairs — a legend read top
to bottom, like the donut's — and overlapping lines are read against every
other line. Under the all-pairs check the palette fails hard, worst ΔE 1.6
deutan and 7.1 for normal vision against a floor of 15. Every five- and
six-colour subset was tested in both themes and none passes, so the limit is
four. That is measured, not preferred.

Colour was also assigned by position in the *filtered* list, so unchecking
one category repainted every line that remained — a line changed colour
without changing meaning. It now keys off the category itself. More
categories exist than the palette has slots, so two selected eight apart can
still share a hue; each line is labelled at its right-hand end, so identity
never rests on colour alone.

The lines were drawn with `type="monotone"`, smoothing a curve through three
monthly totals and describing spending on days no money moved. Straight
segments now, with a dot at each month: the dots are the measurement, the
line between them is inference.

Net Worth drew three series — net worth, assets, liabilities — and shipped
no legend at all, so identity was colour alone and only on hover. It has
one. Its Change tile divided by any non-zero opening balance, which turned a
$534 gain on a $5.15 opening into "+10381.3%" as the headline figure. A
ratio needs a base worth dividing by; below $100 the tile shows the absolute
change and says why the percentage is absent, rather than leaving a silent
gap. A single snapshot now yields no percentage either — "0%" would describe
a period the data does not cover.

The Money Flow Sankey named its nodes but never said how much flowed through
them, which is the one question a money-flow diagram exists to answer. Nodes
carry their value beside the name, in muted ink rather than the node's own
colour, which would read as another encoding. Nodes too thin for a label
keep their value in the tooltip.

Verified against demo data: Trends draws four distinct hues with end labels,
and unchecking Rent/Mortgage left the survivors on chart-2/3/4 instead of
shifting them down; Net Worth shows an Assets / Liabilities / Net Worth
legend and keeps +2.1% on a base that earns one; the Sankey reads
Salary · $23,100.00 through to Savings · $9,694.67.

Refs #147
@KenTaniguchi-R
KenTaniguchi-R merged commit b4d1bbe into main Sep 2, 2026
5 checks passed
@KenTaniguchi-R
KenTaniguchi-R deleted the fix/147-charts branch September 2, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant