18 KiB
18 KiB
前端组件体系
**本文引用的文件列表** - [LifePlanChart.tsx](file://src/LifePlanChart.tsx) - [CashFlowChart.tsx](file://src/CashFlowChart.tsx) - [UnifiedHUD.tsx](file://src/UnifiedHUD.tsx) - [DualChartView.tsx](file://src/DualChartView.tsx) - [Composition.tsx](file://src/Composition.tsx) - [Root.tsx](file://src/Root.tsx) - [index.ts](file://src/index.ts) - [types.ts](file://src/types.ts) - [render-props-types.ts](file://frontend/src/render-props-types.ts) - [mock-data.json](file://src/mock-data.json) - [mock-cashflow.json](file://src/mock-cashflow.json) - [package.json](file://package.json) - [remotion.config.ts](file://remotion.config.ts)目录
简介
本文件系统性梳理了基于 Remotion 的视频画面构建前端组件体系,重点围绕以下核心组件展开:
- LifePlanChart.tsx:资产消耗趋势面积图,展示“资产余额”随时间变化的动态演进
- CashFlowChart.tsx:现金流组合图,展示“收入/支出明细”的堆叠柱状与线条
- UnifiedHUD.tsx:统一信息显示层,作为可复用的头部仪表盘
- DualChartView.tsx:双图表合成视图,同步播放资产与现金流两条时间线
- Composition.tsx:占位的视频合成结构(当前为空)
- Root.tsx 与 index.ts:注册根入口与 Remotion 合成配置
- 类型定义:types.ts 与 frontend/src/render-props-types.ts,确保数据契约一致
目标是帮助初学者快速理解组件职责与使用方式,同时为 UI 开发者提供样式覆盖、动画定制与扩展指导。
项目结构
该仓库采用“按功能模块组织”的前端结构,核心组件位于 src 目录;类型定义在 src 与 frontend/src 下分别维护,以满足前后端数据契约一致性。
graph TB
subgraph "前端源码(src)"
A["index.ts<br/>注册根入口"]
B["Root.tsx<br/>声明多个 Composition"]
C["LifePlanChart.tsx<br/>资产趋势图"]
D["CashFlowChart.tsx<br/>现金流图"]
E["UnifiedHUD.tsx<br/>统一信息显示层"]
F["DualChartView.tsx<br/>双图表合成视图"]
G["Composition.tsx<br/>占位合成结构"]
H["types.ts<br/>YearlySnapshot/LifePlanChartProps"]
I["mock-data.json<br/>资产模拟数据"]
J["mock-cashflow.json<br/>现金流模拟数据"]
end
subgraph "前端类型(frontend/src)"
K["render-props-types.ts<br/>render_props.json 类型定义"]
end
subgraph "配置"
L["package.json<br/>依赖与脚本"]
M["remotion.config.ts<br/>Remotion 配置"]
end
A --> B
B --> C
B --> D
B --> F
F --> C
F --> D
F --> E
C --> H
D --> H
F --> H
B --> I
B --> J
L --> A
M --> A
K --> B
图表来源
- index.ts
- Root.tsx
- LifePlanChart.tsx
- CashFlowChart.tsx
- UnifiedHUD.tsx
- DualChartView.tsx
- Composition.tsx
- types.ts
- render-props-types.ts
- mock-data.json
- mock-cashflow.json
- package.json
- remotion.config.ts
章节来源
核心组件
- LifePlanChart:基于 Recharts 的面积图,支持渐变填充、自定义 X 轴刻度(年份+年龄)、HUD 信息展示、帧级插值动画
- CashFlowChart:基于 Recharts 的组合图,支持堆叠柱状(生活/住房/教育/事件/税费)、线条(收入)、HUD 信息展示、年度内顺序增长动画
- UnifiedHUD:通用头部仪表盘,展示年份、年龄、收入、支出、净现金流、资产余额
- DualChartView:双图表合成容器,统一流程控制与数据转换,保证两条时间线同步
- Root/Composition:Remotion 合成注册与默认参数注入,连接 mock 数据与组件
章节来源
架构总览
Remotion 通过 Root.tsx 中的 Composition 声明多个视频片段,每个片段对应一个组件。组件内部使用 useCurrentFrame/useVideoConfig 进行动画插值,结合 Recharts 实现可视化。数据由 mock 文件或后端生成的 render_props.json 提供,类型定义在 frontend/src/render-props-types.ts 与 src/types.ts 中保持一致。
sequenceDiagram
participant Studio as "Remotion Studio"
participant Root as "Root.tsx"
participant Comp as "Composition"
participant CompA as "LifePlanChart"
participant CompB as "CashFlowChart"
participant CompC as "DualChartView"
participant HUD as "UnifiedHUD"
Studio->>Root : 加载入口
Root->>Comp : 注册多个 Composition
Comp->>CompA : 渲染资产趋势图
Comp->>CompB : 渲染现金流图
Comp->>CompC : 渲染双图表合成
CompA->>CompA : useCurrentFrame/useVideoConfig 插值
CompB->>CompB : useCurrentFrame/useVideoConfig 插值
CompC->>CompC : 统一进度计算
CompC->>HUD : 传递当前年/年龄/收支/资产
图表来源
组件详解
LifePlanChart.tsx(资产消耗图表)
- 视觉设计
- 面积图填充:根据当前可见数据的资产余额正负区间计算渐变分界,形成蓝(正)红(负)过渡
- X 轴刻度:每 5 年显示一次,包含“年份/本人年龄/配偶年龄(若存在)”
- Y 轴单位:货币单位,自动千位分隔与亿单位格式化
- HUD:展示当前年份、资产余额(正负颜色区分)、收入/支出数值
- 动画逻辑
- 使用插值将帧数映射到完整时间线索引,支持外部传入 dataIndex/fraction 以实现跨组件同步
- 对当前年与下一年进行线性插值,生成“当前年进度点”,使面积边界平滑过渡
- Y 轴域基于全量数据计算,避免资产余额剧烈波动导致的轴跳动
- 响应式行为
- 小于 10 年时固定 X 轴范围,避免标签拥挤
- 使用 ResponsiveContainer 自适应容器尺寸
- 关键 props
- timeline: YearlySnapshot[]
- meta: { currencyUnit, startYear }
- hideHeader: 是否隐藏 HUD
- externalDataIndex/externalFraction: 外部同步索引与小数进度
- 与 HUD 的关系
- 通过外部 props 或内部计算提供 HUD 所需的最新数据
flowchart TD
Start(["进入组件"]) --> GetFrame["useCurrentFrame/useVideoConfig 获取帧/时长"]
GetFrame --> Interp["插值计算 exactIndex"]
Interp --> Slice["确定 dataEndIndex 与 fraction"]
Slice --> BuildVisible["构建 visibleData含插值点"]
BuildVisible --> Grad["计算渐变分界 gradientOffset"]
Grad --> Domain["计算 Y 轴域全量数据"]
Domain --> Render["渲染图表与 HUD"]
Render --> End(["完成"])
图表来源
章节来源
CashFlowChart.tsx(现金流图表)
- 视觉设计
- 组合图:堆叠柱状表示各类支出(生活/住房/教育/事件/税费),线条表示收入
- 图例与工具提示启用,X 轴刻度包含“年份/年龄”
- HUD:展示当前年份、年龄、总收入、总支出、净现金流、资产余额
- 动画逻辑
- 统一流程:插值映射到完整时间线,支持外部传入 dataIndex/yearProgress
- 年度内顺序增长:将一年拆分为 6 段(5 个支出类别 + 收入线),按段落顺序逐步显示
- 当前年份插值:在下一年方向延伸一个“进度点”,使线条平滑过渡
- 固定域模式:小于 10 年时补齐空年份,防止坐标偏移
- 响应式行为
- 小于 10 年时固定 X 轴范围
- Y 轴域基于全量数据计算,避免退休等极端波动导致的轴跳动
- 关键 props
- timeline: CashFlowData[]
- meta: { currencyUnit }
- hideHeader: 是否隐藏 HUD
- externalDataIndex/externalYearProgress: 外部同步索引与年内进度
flowchart TD
StartCF(["进入组件"]) --> CF_GetFrame["useCurrentFrame/useVideoConfig 获取帧/时长"]
CF_GetFrame --> CF_Interp["插值计算 exactProgress"]
CF_Interp --> CF_Slice["确定 dataEndIndex 与 yearProgress"]
CF_Slice --> CF_Flatten["扁平化数据并计算 totalExpense"]
CF_Flatten --> CF_Grow["按段落计算增长倍率"]
CF_Grow --> CF_BuildVisible["构建 visibleData含插值点"]
CF_BuildVisible --> CF_Domain["计算 Y 轴域全量数据"]
CF_Domain --> CF_Render["渲染组合图与 HUD"]
CF_Render --> EndCF(["完成"])
图表来源
章节来源
UnifiedHUD.tsx(统一信息显示层)
- 设计定位:作为独立的 HUD 组件,可被任意图表或合成视图复用
- 内容构成:当前年份与年龄、收入、支出、净现金流、资产余额,带单位与图标
- 样式要点:渐变背景、卡片式布局、对齐与间距统一、大号资产余额突出显示
- 使用建议:在外部组件中直接传入最新年份数据即可复用
classDiagram
class UnifiedHUD {
+year : number
+age : number
+income : number
+expense : number
+netCashFlow : number
+assetBalance : number
+currencyUnit : string
}
class MetricCard {
+label : string
+value : number
+unit : string
+color : string
+icon : string
+isLarge : boolean
}
UnifiedHUD --> MetricCard : "组合多个指标卡片"
图表来源
章节来源
DualChartView.tsx(双图表合成结构)
- 组合模式:上层资产趋势图(LifePlanChart),下层现金流图(CashFlowChart)
- 同步策略:统一插值进度,将 CashFlowData 转换为 LifePlanChart 所需的 YearlySnapshot 结构
- 元数据传递:将货币单位与起始年份透传给资产图
- 外部同步:向两个子组件传递 dataEndIndex 与 yearProgress,确保动画完全一致
- 边框与标题:为两个图表容器添加边框、圆角与标题栏,提升可读性
sequenceDiagram
participant DCV as "DualChartView"
participant LP as "LifePlanChart"
participant CF as "CashFlowChart"
participant HUD as "UnifiedHUD"
DCV->>DCV : 计算统一进度 exactProgress
DCV->>DCV : 转换 CashFlowData -> YearlySnapshot
DCV->>LP : 传入 timeline/meta/hideHeader/同步索引
DCV->>CF : 传入 timeline/meta/hideHeader/同步索引
DCV->>HUD : 传入当前年/年龄/收支/资产
图表来源
章节来源
Composition.tsx(视频合成结构)
- 当前实现:占位组件,返回空内容
- 建议用途:可作为顶层合成容器,承载全局背景、遮罩或全局 HUD;也可保留为空以便后续扩展
章节来源
依赖关系分析
- 组件间依赖
- DualChartView 依赖 LifePlanChart、CashFlowChart、UnifiedHUD
- LifePlanChart 与 CashFlowChart 依赖 Recharts 与 Remotion hooks
- Root.tsx 通过 Composition 注册多个合成片段,并注入默认数据
- 类型契约
- YearlySnapshot 与 CashFlowData 在 src/types.ts 与 frontend/src/render-props-types.ts 中保持一致,确保前后端数据结构匹配
- 外部依赖
- react、remotion、recharts、@types/react 等
graph LR
Root["Root.tsx"] --> LP["LifePlanChart.tsx"]
Root --> CF["CashFlowChart.tsx"]
Root --> DCV["DualChartView.tsx"]
DCV --> LP
DCV --> CF
DCV --> HUD["UnifiedHUD.tsx"]
LP --> Types["types.ts"]
CF --> Types
DCV --> Types
Root --> MockA["mock-data.json"]
Root --> MockB["mock-cashflow.json"]
Root --> Pkg["package.json"]
Root --> RConf["remotion.config.ts"]
图表来源
- Root.tsx
- LifePlanChart.tsx
- CashFlowChart.tsx
- DualChartView.tsx
- UnifiedHUD.tsx
- types.ts
- mock-data.json
- mock-cashflow.json
- package.json
- remotion.config.ts
章节来源
性能与优化建议
- 避免不必要的重渲染
- 使用 React.memo 包裹图表组件
- 使用 React.useMemo 缓存 xAxisDomain、yAxisDomain、转换后的 timeline 等昂贵计算结果
- 控制动画复杂度
- Recharts 默认动画关闭,避免额外开销;如需自定义动画,建议仅在必要元素上启用
- 数据切片与插值
- 仅渲染可见数据片段,减少 DOM 数量
- 插值计算尽量在组件外完成或缓存
- 响应式容器
- 使用 ResponsiveContainer 时,尽量固定宽高比,减少频繁测量
- Y 轴域稳定性
- 基于全量数据计算 Y 轴域,避免动画过程中的轴跳动
[本节为通用性能建议,不直接分析具体文件]
故障排查指南
- 数据类型不匹配
- 若出现运行时报错,检查 frontend/src/render-props-types.ts 与 src/types.ts 的接口是否与实际 JSON 数据一致
- 动画不同步
- 确认 DualChartView 是否向子组件传递了相同的 externalDataIndex 与 externalYearProgress
- Y 轴抖动
- 确保 LifePlanChart 与 CashFlowChart 的 yAxisDomain 基于全量 timeline 计算
- HUD 显示异常
- 检查 UnifiedHUD 的输入字段是否正确传入(year/age/income/expense/netCashFlow/assetBalance/currencyUnit)
章节来源
结论
该组件体系以 Remotion 为核心,结合 Recharts 实现了高质量的财务可视化动画。LifePlanChart 与 CashFlowChart 分别聚焦“资产趋势”与“收支明细”,DualChartView 则提供了统一的双轨同步体验。通过明确的类型契约与稳定的动画插值策略,组件具备良好的可维护性与扩展性。建议在生产环境中进一步完善错误处理、日志记录与性能监控。
[本节为总结性内容,不直接分析具体文件]
附录:使用示例与定制指南
如何使用组件(初学者预览)
- 直接渲染单个图表
- 在 Root.tsx 中注册对应的 Composition,并通过 defaultProps 传入 mock 数据
- 示例路径参考:
- 在合成视图中组合
- 使用 DualChartView 将资产与现金流同步展示
- 示例路径参考:
章节来源
组件组合模式
- 双图表合成
- 上层:LifePlanChart(资产余额趋势)
- 下层:CashFlowChart(收入/支出明细)
- 共享:统一进度、货币单位、起始年份
- HUD 复用
- 可在任意场景使用 UnifiedHUD 展示关键指标
章节来源
定制化与扩展指导(UI 开发者)
- 样式覆盖
- 通过 props 传入 meta(currencyUnit/startYear)与 hideHeader 控制 HUD 显示
- 在外部容器中设置统一的字体、间距与背景色
- 动画修改
- 修改插值区间与插值函数,调整动画节奏
- 在 LifePlanChart 中调整 gradientOffset 的计算逻辑,改变渐变分界
- 在 CashFlowChart 中调整 yearly growth 的段落数与倍率曲线
- 数据适配
- 若后端数据结构变化,优先更新 frontend/src/render-props-types.ts 与 src/types.ts
- 在 DualChartView 中补充必要的字段映射(如 totalExpense/netCashFlow/assetBalance)
章节来源