Files
smart-fin-chart/README.md
T
2026-10-22 15:43:17 +08:00

206 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 财报图表 · Joey 谨制
基于 **ECharts 5.5** 的财报数据可视化项目,采用“Joey 风格”。
修改 CSV 数据,刷新页面即可更新图表;每张图表都可独立导出为高清 PNG。
---
## 快速开始
首次使用时,在项目根目录安装依赖:
```bash
pnpm install
```
### 1. 启动开发服务器(支持热更新)
```bash
# 方案 A:Vite 开发服务器
pnpm dev
# 方案 B:直接双击项目根目录的 `.start.command`
# 脚本会启动 Vite 并自动打开浏览器
```
### 2. 打开浏览器
访问 **http://localhost:8899**。页面左侧选择公司,中间用 Tab 切换分析维度,右侧可跳转到当前分类的图表。
修改 `js/` 或 `css/` 后页面会热更新;修改 `manifest.json` 或 `data/**/*.csv` 后页面会自动整页刷新。
需要生成静态发布文件时:
```bash
pnpm build
pnpm preview
```
构建结果位于 `dist/`,其中包含运行所需的 manifest 与 CSV,不包含 `data/ppmt/raw/` 中的原始 PDF/XLSX。
当前 manifest 内登记了 5 张示例图表和 22 张泡泡玛特财报图表:
**示例图表:**
1. **存货、营收与存货周转天数** — 双柱 + 折线,双 Y 轴
2. **利润率与费用率拆解** — 四条率线对比
3. **毛利率与非国际净利率** — 两条主要率线
4. **营收到利润的增速对比** — 四条增速线
5. **人民币汇率两种口径** — 中间价 vs 在岸即期,带说明卡片
**泡泡玛特财报分析:**
6. **资产结构演变** — 堆叠柱状图展示类现金、应收账款、投资、经营资产
7. **盈利能力分析** — 营收、毛利、净利润及毛利率变化
8. **主要 IP 收入趋势** — 多条折线展示 MOLLY、SKULLPANDA、CRYBABY 等 IP 表现
9. **品类收入结构** — 毛绒、手办、MEGA、衍生品的占比和增长
10. **利润流向(2026H1)** — 桑基图,营收拆到成本、费用、净利
11. **区域渠道同比增速** — 分区域 × 渠道的增速对比
12. **营收到利润的增速对比** — 泡泡玛特口径
13. **利润率与费用率拆解** — 毛利率、销售/管理费用率、非 GAAP 净利率
14. **净利率同比拆解** — 瀑布图,含税盾换算与税率单列项
15. **核心利润及同比增速** — 柱 + 折线
16. **核心利润率** — 毛利率 − 销售费用率 − 管理费用率
17. **主要 IP 收入占比(2026H1)** — 饼图,右侧图例带收入与占比
18. **各 IP 半年收入占比(21H1-26H1)** — 归一化堆叠柱状图,看收入结构变迁
19. **除 THE MONSTERS 外的 IP 收入及同比** — 柱 + 折线双轴,剔掉爆款看其余盘子
20. **区域渠道分布(2026H1)** — 左右堆叠条形图,对比各区域线上与线下渠道收入
21. **区域渠道同比增速趋势** — 热力图查看区域 × 渠道的历史同比变化
### 3. 修改数据
编辑对应公司的 CSV,保存后点击页面右上角的 **「重新加载数据」** 按钮。数据目录按公司划分,例如 `data/ppmt/ppmt_profit.csv`、`data/demo/inventory.csv`。
CSV 格式:首行是表头,逗号分隔,数字列会自动转换。示例:
```csv
period,inventory,revenue,turnover_days
22H1,9.6,23.6,160
22年,8.7,46.2,154
```
### 4. 导出图表
每张图表右上角都有 **「导出 PNG」** 按钮,点击即可下载 2 倍分辨率的图片(适合微信公众号等场景)。
---
## 项目结构
```
smart-fin-chart/
├── index.html # 主页面
├── manifest.json # 公司、Tab、图表、CSV 的唯一配置来源
├── data/ # 数据文件(按公司划分)
│ ├── demo/
│ └── ppmt/
│ └── raw/ # 用户提供的原始 xlsx / PDF
├── js/
│ ├── main.js # 入口:读取 manifest、渲染、导出 PNG
│ ├── ui.js # 三栏 UI 构建
│ ├── csv.js # CSV 解析工具
│ ├── theme.js # 主题:配色、字体、水印、共享系列构造器
│ └── charts/ # 图表构建函数与 registry
├── test/
│ └── regress.mjs # 回归测试:遍历 manifest + 样式规范断言
└── css/
└── style.css # 页面样式
```
## 测试
```bash
pnpm test
```
用 ECharts 的 SSR 模式遍历 manifest 中的图表并渲染成 SVG,断言:
- `legend.top` = 85、`grid.top` = 145(统一间距)
- 折线 `symbolSize` = 9、`borderWidth` = 2.5(空心圆点规范)
- SVG 属性未被字体名里的引号提前闭合
回归测试会遍历 `manifest.json`,不用再手工维护图表清单。
---
## 设计原则
### 统一的视觉语言
所有图表共用 `js/theme.js` 的配色、字体、坐标轴样式,确保视觉一致性:
- **配色**:低饱和莫兰迪系(棕色、沙色、珊瑚红、海军蓝等)
- **字体**:苹方 / 微软雅黑,中文友好
- **坐标轴**:只留浅灰网格线,去掉轴线的存在感
- **水印**:全画布平铺"Joey 谨制",旋转 20°,透明度 0.10
### 数据标签全标注
每个数据点都显示标签,避免读者"猜数值"。密集时上下交错放置(见图 2),不用 hover tooltip 替代。
### 底部注释
重要的计算口径、数据来源写在图表底部(用 `graphic.text`),不依赖外部文档。
---
## 常见问题
**Q:为什么必须用本地服务器,不能直接双击 `index.html`?**
A:浏览器的同源策略禁止 `file://` 协议读取 CSV,会报 CORS 错误。启动服务器后用 `http://` 访问即可。
**Q:修改 CSV 后刷新页面,图表没变化?**
A:点击页面右上角的 **「重新加载数据」** 按钮。普通刷新可能吃到浏览器缓存,按钮会加时间戳绕过缓存。
**Q:如何添加新图表?**
A:
1. 在 `data/` 下创建新 CSV
2. 在 `js/charts/` 下创建新 `.js`,从 `theme.js` 取共享配置(`lineSeries()`、`barSeries()`、`standardLegend()`、`periodAxis`),不要手写等价值
3. 在 `js/charts/index.js` 注册 chart key
4. 在 `manifest.json` 对应公司的 `chartCatalog` 中登记图表配置,再在需要展示的 Tab 的 `chartRefs` 中引用它;概览可直接引用同一图表 ID,无需复制配置
5. 跑 `node test/regress.mjs <chart-id>`;浏览器检查标签、颜色和脚注
**Q:能改水印文字吗?**
A:编辑 `js/theme.js` 的 `WATERMARK_TEXT` 常量。
**Q:能改配色吗?**
A:编辑 `js/theme.js` 的 `PALETTE` 对象,所有图表自动同步。
---
## 技术细节
- **ECharts 5.5.1**:从 jsDelivr CDN 加载,无需额外安装 ECharts
- **ES6 Modules**:用原生 `<script type="module">`,无构建步骤
- **Canvas 渲染**:页面用 canvas(性能好),导出时用 ECharts 自带的 `getDataURL` 生成 PNG
- **响应式**:window resize 时重绘(水印数量跟着画布尺寸变化)
---
## 许可
本项目代码采用 MIT 协议,数据仅供示例。
## 估值工具
左侧选择「估值工具」,打开「目标收益反推增长率」Tab。支持反推所需归母利润年复合增长率、计算预期年化 IRR、反推最高买入价;可调整安全边际、股息、股本变化率、基期和币种汇率。参数自动保存在当前浏览器,点击「恢复示例参数」可重置。
入口:`#/valuation-tools/stock-return-valuation`。默认数字是教学情景假设,不是实时行情或财报。计算口径来自 `stock-return-valuation` 技能 v1.2.0,浏览器引擎位于 `js/tools/stock-return-math.js`,界面位于 `js/tools/stock-return-calculator.js` 和同名 HTML 模板。
单独运行估值检查:`npm run test:valuation`;`npm test` 同时运行图表回归与估值检查。
「DCF 估值」Tab(`#/valuation-tools/dcf`)采用分段工作台,可设置 1—5 个增长阶段,每段输入年数与现金流年增长率,总预测期不超过 30 年。支持 FCFF/WACC 与 FCFE/股权资本成本两种口径、永续增长终值、股权价值调整和逐年折现明细。
总股本在基础参数区单独填写,单位为亿股;每股价值 = 股权价值(亿元)÷ 当前总股本(亿股)。每家公司的股本、股本日期、现金流和增长假设独立保存在当前浏览器,也可新增公司。真实公司初次使用时,现金流与股本留空,需自行核实后填写;教学示例的 10 亿股仅为假设。当前模型使用人民币金额与预测期内不变的股本。
公司以按钮形式展示,点击即可切换;当前股价、股价日期和区间阈值也按公司自动保存到 LocalStorage,兼容原有 DCF 本地记录。股价需要手动输入,不自动请求行情。未填或填错股价不影响已完成的 DCF 计算,也不会保留上次股价标记。
ECharts 区间图以 DCF 每股价值为基准,默认低于其 80% 为低估、高于其 120% 为高估,两端边界均包含在合理区间内。「区间设置」可分别修改低估折价(同时作为安全边际)与高估溢价阈值。这是当前假设下的自定义价格分区,不是独立的投资结论;无正股权价值时不显示区间。
「目标收益交叉验证」共用当前公司的股价、股本、基期和 DCF 参考价。输入独立的归母净利润及预计利润增速后,可比较现价、DCF 含安全边际参考价两种买入情景的所需利润 CAGR 与预计 IRR,并查看悲观/基准/乐观退出 PE 情景。计算复用独立「目标收益反推增长率」工具的数学引擎。
首屏顶部并列展示当前股价、按现价计算的预计年化 IRR、达到目标收益所需的利润年增速;后两项采用基准退出 PE,与下方现价情景结果同步。修改参数或切换公司后即时更新,参数不完整或无效时清除旧值。
FCFE 模式可选择以用户提供的基期现金转化率(FCFE ÷ 归母净利润)估算利润;该值会明确标注为估算,不作为独立财报验证。FCFF 模式要求单独填写归母净利润。真实公司的利润、转化率和预计利润增速默认留空,新增验证参数仍按公司保存在原有 LocalStorage 记录中。
双买入价格表按各自实际买入价反推增速及计算 IRR,不额外叠加安全边际。「共同参考买入上限」取 DCF 参考价和目标收益模型参考价的较低值,两边各应用一次安全边际。分红按独立路径计算;交叉验证中的股本变化仅影响收益模型,DCF 仍采用固定股本假设。验证参数缺失或无效时只隐藏验证结果,不影响有效的 DCF 结果。