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

204 lines
9.9 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 页只计算现金流估值。预计 IRR、利润增长门槛和退出 PE 情景使用单独的「收益反推」Tab。现有公司的 DCF 记录沿用原有 LocalStorage 键,旧版额外字段不会参与 DCF 计算。
标题栏右侧的问号打开「估值概念说明」,包含 FCFF、FCFE、口径选择、折现率、永续终值、安全边际与区间说明,支持目录定位和键盘关闭。