182 lines
6.9 KiB
Markdown
182 lines
6.9 KiB
Markdown
# 财报图表 · 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 协议,数据仅供示例。
|