用户故事:收益归因图表可视化
创建日期: 2025-01-11
更新日期: 2025-01-11
状态: 待开发
优先级: P2
依赖:
- 真实收益追踪功能(已完成)
- 单资产级别收益归因表格(建议先完成)
1. 用户故事
作为个人投资者,
我希望通过可视化图表直观地看到收益趋势和归因分布,
以便我能快速理解收益如何随时间变化,以及哪些资产/类别贡献最大。
2. 背景与问题
用户场景
- 用户每月盘点一次
- 每次盘点都有新投入和收益变化
- 想要直观地看到:
- 收益趋势:这几个月收益是上涨还是下跌?
- 收益归因:哪个类别/资产贡献了主要收益?
- 真实 vs 账面:资金流入对收益数字的影响有多大?
当前状态
目前收益归因只有表格形式,用户需要阅读数字来理解收益情况。
用户痛点
| 痛点 | 影响 |
|---|---|
| 纯数字表格不直观 | 难以快速把握整体趋势 |
| 没有时间维度的可视化 | 看不出收益是在改善还是恶化 |
| 正负收益混合时信息过载 | 整体情况不清晰 |
3. 功能需求
3.1 图表类型总览
| 优先级 | 图表 | 用途 | Phase |
|---|---|---|---|
| ⭐ P0 | 收益趋势折线图 | 展示每期累计收益变化 | 1 |
| P1 | 收益对比条形图 | 对比各类别/资产的收益 | 1 |
| P2 | 账面vs真实对比图 | 展示资金流入的影响 | 2 |
| P3 | 收益贡献环形图 | 展示贡献占比 | 2 |
| P4 | 收益瀑布图 | 展示收益分解路径 | 3 |
3.2 图表 1:收益趋势折线图 ⭐ 核心
用途:展示累计收益随时间的变化,回答"我的投资整体表现如何"。
数据维度:
- X 轴:盘点日期(月份)
- Y 轴:累计真实收益(¥)
- 可选叠加:累计账面收益
UI 设计:
累计收益
│
+4k├────────────────────────────────● 真实收益
│ ╱
+3k├────────────────────────────╱
│ ╱
+2k├────────────────────────●╱
│ ╱
+1k├────────────────────●
│ ╱
0├────────────────●─────────────────────────
│ ╱ ○ 账面收益
-1k├────────────○─────○─────○─────○─────○
│
└──────┬──────┬──────┬──────┬──────┬──────
1月 2月 3月 4月 5月
● 真实收益: +¥4,000 (+25.0%)
○ 账面收益: +¥8,000 (+50.0%)
差额由资金流入解释: ¥4,000
交互:
- 悬停显示具体数值
- 可切换:总收益 / 按类别分组 / 单资产
- 可选时间范围
3.3 图表 2:收益对比条形图
用途:横向对比各类别/资产的收益表现,识别表现好/差的部分。
UI 设计(按真实收益排序):
┌─────────────────────────────────────────────────────────────┐
│ 📊 收益贡献排行 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 沪深300ETF ████████████████████████ +¥2,000 (+17.4%) │
│ 余额宝 ███ +¥100 (+0.2%) │
│ 朝朝宝 │ ¥0 (0%) │
│ 中证500ETF ▓▓▓▓▓▓▓▓ -¥2,000 (-16.0%) │
│ │
│ ─────────────────┼───────────────── │
│ -¥3k -¥1.5k 0 +¥1.5k +¥3k │
│ │
│ █ 正收益 ▓ 负收益 │
└─────────────────────────────────────────────────────────────┘
特点:
- 正收益向右(绿色),负收益向左(红色)
- 按收益额排序,表现好的在上
- 支持按类别/资产切换
3.4 图表 3:账面 vs 真实收益对比
用途:直观展示资金流入对收益数字的影响。
UI 设计:
┌─────────────────────────────────────────────────────────────┐
│ 📊 账面收益 vs 真实收益 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 现金类 账面 █████████████████████████ +¥25,700 │
│ 真实 ░ ¥0 │
│ │
│ 权益类 账面 ████████ +¥8,000 │
│ 真实 ███████ +¥3,000 │
│ │
│ 固收类 账面 ▓▓ -¥2,000 │
│ 真实 ▓▓ -¥2,000 │
│ │
│ █ 账面收益 ░ 被资金流入抵消部分 ▓ 负收益 │
└─────────────────────────────────────────────────────────────┘
解读:
- 现金类账面 +¥25,700,但真实 ¥0 → 说明全是资金流入
- 权益类账面 +¥8,000,真实 +¥3,000 → 有 ¥5,000 是资金流入
3.5 图表 4:收益贡献环形图
用途:展示各类别对总收益的贡献占比。
⚠️ 负值处理:环形图不适合展示负值,采用以下策略:
- 仅展示正收益贡献:负收益类别单独标注
- 或使用分离扇区:负收益部分用虚线边框
UI 设计:
┌─────────────────────────────────────────┐
│ 📊 正收益贡献分布 │
├─────────────────────────────────────────┤
│ │
│ ╭───────────────╮ │
│ ╱ ╲ │
│ │ 权益类 60% │ │
│ │ ╭─────────╮ │ │
│ │ │ 现金类 │ │ │
│ │ │ 40% │ │ │
│ │ ╰─────────╯ │ │
│ ╲ ╱ │
│ ╰───────────────╯ │
│ │
│ 📍 负收益类别:固收类 -¥2,000 │
│ │
└─────────────────────────────────────────┘
3.6 图表 5:单资产收益趋势图
用途:配合"资产级别收益归因表格",点击资产后展示该资产的历史收益趋势。
UI 设计:
┌─────────────────────────────────────────────────────────────┐
│ 📈 沪深300ETF 收益趋势 [← 返回] │
├─────────────────────────────────────────────────────────────┤
│ │
│ 累计收益 │
│ │ │
│ +4k├────────────────────────────────● │
│ │ ╱ │
│ +2k├────────────────────────────● │
│ │ ╱ │
│ +1k├────────────────────────● │
│ │ ╱ │
│ 0├────────────────────●────────────────────── │
│ │ │
│ └──────┬──────┬──────┬──────┬────── │
│ 1月 2月 3月 4月 │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ 本期收益柱状图 │ │
│ │ +3k│ ████ │ │
│ │ +2k│ ████ ████ │ │
│ │ +1k│ ▓▓▓▓ │ │
│ │ └──┬──────┬──────┬──────┬── │ │
│ │ 2月 3月 4月 5月 │ │
│ └──────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
4. 技术方案
4.1 图表实现方式
| 图表 | 实现方式 | 理由 |
|---|---|---|
| 折线图 | 纯 SVG | 路径简单,易于实现 |
| 条形图 | CSS + div | 最简单,无需 SVG |
| 环形图 | SVG | 需要 arc 路径 |
| 瀑布图 | SVG | 结构复杂,Phase 3 |
4.2 组件设计
src/components/analysis/
├── charts/
│ ├── mod.rs
│ ├── line_chart.rs # 折线图(趋势)
│ ├── bar_chart.rs # 条形图(对比)
│ ├── comparison_bar.rs # 双条对比图(账面vs真实)
│ ├── donut_chart.rs # 环形图(占比)
│ └── waterfall_chart.rs # 瀑布图(Phase 3)
└── ...
4.3 数据接口
#![allow(unused)] fn main() { /// 趋势图数据点 pub struct TrendPoint { pub date: NaiveDate, pub cumulative_return: Decimal, pub period_return: Decimal, } /// 收益趋势数据 pub struct ReturnTrend { pub points: Vec<TrendPoint>, pub min_value: Decimal, pub max_value: Decimal, } /// 生成趋势数据 fn calculate_return_trend( snapshots: &[Snapshot], scope: Option<AssetScope>, category: Option<Category>, asset_id: Option<Uuid>, ) -> ReturnTrend; }
5. 移动端适配
5.1 布局调整
- 图表全宽显示,垂直堆叠
- 折线图支持左右滑动查看历史
- 条形图改为垂直方向
5.2 交互调整
| 桌面端 | 移动端 |
|---|---|
| 鼠标悬停 | 长按显示 |
| 点击跳转 | 点击跳转 |
| 缩放 | 双指缩放 |
6. 验收标准
Phase 1(基础图表)
- 收益趋势折线图展示累计收益变化
- 支持切换:全部 / 按类别 / 单资产
- 收益对比条形图展示各资产排行
- 正负收益有明确的颜色区分
- 移动端适配良好
Phase 2(进阶图表)
- 账面 vs 真实收益对比图
- 收益贡献环形图(正确处理负值)
- 图表交互(悬停显示数值)
Phase 3(高级图表)
- 收益瀑布图
- 动画效果
7. 工作量估算
Phase 1(核心图表)- 2 天
| 任务 | 估算 |
|---|---|
| 折线图组件(SVG) | 0.75 天 |
| 条形图组件(CSS) | 0.5 天 |
| 数据接口(ReturnTrend) | 0.25 天 |
| 移动端适配 | 0.25 天 |
| 集成到收益分析页 | 0.25 天 |
Phase 2(对比图表)- 1.5 天
| 任务 | 估算 |
|---|---|
| 双条对比图组件 | 0.5 天 |
| 环形图组件(SVG) | 0.5 天 |
| 交互优化 | 0.5 天 |
Phase 3(高级图表)- 1 天
| 任务 | 估算 |
|---|---|
| 瀑布图组件 | 0.75 天 |
| 动画效果 | 0.25 天 |
总计:4.5 天
8. 设计规范
8.1 配色方案(Catppuccin Mocha)
| 元素 | 颜色 | 色值 |
|---|---|---|
| 正收益 | Green | #a6e3a1 |
| 负收益 | Red | #f38ba8 |
| 中性/零 | Overlay0 | #6c7086 |
| 现金类 | Green | #a6e3a1 |
| 固收类 | Blue | #89b4fa |
| 权益类 | Mauve | #cba6f7 |
| 另类 | Yellow | #f9e2af |
| 折线(真实收益) | Green | #a6e3a1 |
| 折线(账面收益) | Overlay1 | #7f849c |
8.2 动画
| 场景 | 动画 |
|---|---|
| 图表加载 | 从左到右渐入(折线),从下到上生长(条形) |
| 数值变化 | 300ms ease-out 过渡 |
| 悬停反馈 | 放大 1.05x + 阴影 |
9. 后续扩展
- 支持自定义时间范围
- 支持导出图表为图片
- 支持历史收益归因对比(本期 vs 上期 vs 去年同期)
- 与大盘指数叠加对比(相对收益)