Skip to content

feat(ui): trend chart polish + metric switcher (rant 2026-08-23T16:17:18) - #133

Merged
argszero merged 1 commit into
mainfrom
feat/trend-chart-polish
Aug 24, 2026
Merged

argszero merged 1 commit into
mainfrom
feat/trend-chart-polish

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Polish the transaction-page trend chart and add a metric switcher (host rant 2026-08-23T16:17:18):

Requirement 1 — chart aesthetics:

  • Smooth Catmull-Rom → cubic Bézier line (replaces angular polyline)
  • Optional gradient area fill under the line (per-metric translucent fade)
  • Theme-consistent per-metric colors (Spend=danger, Income=ok, Net=accent, Tokens=warn) — adapts to dark/light themes via CSS variables
  • Dashed grid + cleaner axis labels
  • Hover tooltip with precise value + vertical guide line (replaces native <title>)
  • Adaptive y-axis scale: nice steps (1/2/5×10^n); Net uses a symmetric ±max axis so the zero line stays visible

Requirement 2 — selectable metric:

  • Metric switcher buttons: 消费点数 Spend / 收入点数 Income / 净变化 Net / Token 用量 Tokens
  • Default shows 消费点数 (Spend); switching re-renders instantly (no extra API call — /api/transactions/trend already returns all metrics)
  • Legend shows the selected metric's period total

Related Issue

Host rant 2026-08-23T16:17:18 (trend chart polish + metric switcher) — no GitHub issue.

Changes

  • ui/js/app.js: renderTxTrend rewrite (switcher, smooth path, gradient area, adaptive scale, tooltip context) + delegated click/mousemove/mouseleave bindings + txTrendMetric state
  • ui/css/style.css: switcher, chart wrapper, guide line, tooltip, gradient stops, per-metric colors
  • ui/js/i18n.js: zh/en keys tx.trend.metric.*
  • ui/index.html: cache-bust 20260823-3 → 20260824-1

Tests

  • cargo test all pass (146/146)
  • cargo fmt --check pass
  • cargo clippy --all-targets -- -D warnings pass (no new warnings)
  • node --check on app.js / i18n.js

Checklist

  • Branch naming follows convention (feat/trend-chart-polish)
  • Commit message uses Conventional Commits
  • Single responsibility, minimal change

…:18)

- Metric switcher (Spend/Income/Net/Tokens, default Spend) with delegated click binding
- Smooth Catmull-Rom line, gradient area fill, per-metric theme colors
- Adaptive nice-scale axis (1/2/5x10^n; symmetric zero-axis for Net)
- Hover tooltip + guide line (replaces <title>), dashed grid, legend total
- i18n keys zh+en, cache-bust 20260824-1
@argszero
argszero merged commit 40fc2f2 into main Aug 24, 2026
1 check passed
@argszero
argszero deleted the feat/trend-chart-polish branch August 24, 2026 02:09
argszero added a commit that referenced this pull request Sep 25, 2026
…raws (#301)

The dashboard card "Consumption & earnings, last 14 days" binds its green bar
to the backend `income` series -- the direction whitelist `earn + topup + gift`
(`TX_INCOME_TYPES`, src/routes/wallet.rs) -- but labelled that bar
`dash.trend.earn` = "共享收益" / "Sharing earnings". On the same screen the
`dash.earnings` stat card uses that same name for a different fact: true
`earn` only (`month_earn`, SQL `type = 'earn'`). So one screen carries two
facts under one name: a user with a top-up sees the green bar at 5000 while the
card beside it reads 0.

The transactions page already calls this series "收入" / "Income"
(`tx.trend.metric.income`), and its own subtitle for the total says
"共享分成**等**收益" -- it states that the total is a superset of earnings.
Birth order agrees this is drift, not a tradeoff: "收入" dates from #133, and
#155 gave the same series a narrower name 22 PRs later, in a commit whose
comment claimed the same scope as the transactions page.

Fix is a name, not the data: key `dash.trend.earn` -> `dash.trend.income`,
values "收入" / "Income". The bar still draws `income`; no series, query or
number changed. All three carriers of that series in this card (legend in
`index.html`, tooltip in `renderDashTrend`, transactions-page legend) now
share one key, whose pack values are identical to the transactions page's.

Gate `state_gate::the_dashboard_trend_names_its_series_the_way_the_transactions_trend_names_it`
pins four derived rules: the bar reads `income` (not `.earn`), the three
carriers are one key, that key's values equal the transactions page's, and the
earn-only card keeps its own name and its own `month_earn` supply. The gate is
lexical by design -- it proves the declaration, not the pixel; the jsdom probe
side is out of scope here.

Co-authored-by: argszero <argszero@argszerodeMac-mini.local>
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