Files
smart-fin-chart/docs/方案设计.md
T

11 KiB
Raw Blame History

智能财报分析平台 · 方案设计

版本:v0.3(P0 已落地)

状态:与当前代码同步 范围:本仓库负责「规范化 CSV → ECharts 图表展示」。原始财报的抽取、整理与复核在仓库外完成。


1. 当前目标

这是一个以“够用、易维护”为优先级的多公司财报图表工具,而不是一个预先建设完整数据平台的项目。

  1. 多公司浏览:左侧选择公司,中间按分析主题查看图表,右侧可跳转当前栏目的图表。
  2. 概览优先:概览只展示最值得先看的跨主题图表;它是精选入口,不是新的数据或图表副本。
  3. 确定性渲染:CSV 相同,图表结果相同;AI 只协助将原始财报整理成 CSV,或一次性生成经 review 后固化的新增图表代码。
  4. 低维护成本:更新已有图表时只替换 CSV;新增专属图时才增加图表构建文件与注册项。

第一阶段不建设自动累计转单季、通用指标平台、完整财务勾稽或运行期聊天机器人。这些只在第二家公司接入后,确实出现重复劳动时再考虑。


2. 当前架构

原始财报 / PDF / XLSX(仓库外保存)
   │ 人工、AI 或脚本:抽取、归一化、口径确认
   ▼
data/{company}/*.csv                 ← 运行时数据
   ▼
manifest.json                        ← 展示编排与图表配置的唯一事实来源
   ├─ chartCatalog                   ← 每张图只定义一次
   └─ tabs[].chartRefs               ← 各栏目仅引用图表并决定顺序
   ▼
js/charts/index.js                   ← chart key → ECharts option 构建函数
js/main.js + js/ui.js                ← 解析引用、渲染三栏、导出和刷新

2.1 图表定义与页面编排分离

每家公司拥有一份 chartCatalog。一张图的 key、CSV、标题、高度与导出名只在这里维护一次;Tab 只使用 chartRefs 引用它。

{
  "id": "ppmt",
  "chartCatalog": {
    "ppmt-growth": {
      "key": "ppmt-growth",
      "title": "营收到利润的增速对比",
      "csv": "data/ppmt/ppmt_growth.csv",
      "height": 700,
      "filename": "泡泡玛特营收到利润增速对比"
    }
  },
  "tabs": [
    { "id": "overview", "name": "概览", "chartRefs": ["ppmt-growth"] },
    { "id": "profitability", "name": "盈利能力", "chartRefs": ["ppmt-growth"] }
  ]
}

这保证概览与原分类使用同一数据源、同一图表构建函数、同一份展示配置。修改图表只需改 chartCatalog 一处。

页面在每次展示时生成 公司 + Tab + 图表 ID 的实例 ID,供 DOM 和 ECharts 使用。因此,同一图既能出现在概览,也能出现在原分类,不会发生画布或导出实例冲突。URL 中仍使用稳定的图表 ID,例如:#/ppmt/profitability/ppmt-growth。

2.2 图表代码职责

  • manifest.json:图表定义在哪里展示、读哪个 CSV、卡片尺寸和导出名。
  • js/charts/index.js:注册 key → build 函数。
  • js/charts/*.js:只处理该图的业务字段与 ECharts 表达。
  • js/theme.js:字体、配色、图例、坐标轴、脚注和水印等统一视觉规范。
  • data/{company}/:图表需要的规范化 CSV。

3. 页面与交互

┌──────────┬────────────────────────────────────┬──────────┐
│ 公司列表  │ [概览][盈利能力][费用率][资产负债]… │ 当前图表  │
│ 泡泡玛特  │ ┌────────────────────────────────┐ │ · 图表 A │
│ 示例     │ │ 图表卡片:标题、数据路径、导出   │ │ · 图表 B │
│          │ └────────────────────────────────┘ │          │
└──────────┴────────────────────────────────────┴──────────┘
  • 左栏切换公司;顶部 Tab 切换该公司的分析栏目;仅渲染当前栏目,切走后释放 ECharts 实例。
  • 右栏显示当前栏目锚点,点击后平滑定位到相应图表。
  • 右上角固定刷新按钮重新读取 manifest 与 CSV;导出按钮按当前卡片导出 PNG。
  • 宽度 ≤1040px 时隐藏右侧锚点;宽度 ≤880px 时公司栏改为页面顶部横向菜单,图表卡片允许横向滚动以保持可读性。
  • Vite 开发环境中,JS/CSS 修改热更新;manifest.json 或 CSV 修改会自动整页刷新。

4. 泡泡玛特当前栏目设计

4.1 概览:精选入口

概览用四张图快速回答“公司是否仍在增长、增长是否转化为利润、增长来自哪里、海外/渠道结构如何”。它们同时保留在原分析栏目中。

  1. 营收到利润的增速对比:经营增长和利润兑现。
  2. 盈利能力:主要利润率趋势。
  3. 主要 IP 收入占比:IP 集中度与核心 IP 贡献。
  4. 区域渠道分布:区域、渠道的收入结构。

4.2 详细栏目

Tab 当前内容 设计意图
概览 上述 4 张精选图 进入公司后的快速判断
盈利能力 营收到利润的增速对比、核心利润及同比、核心利润率、净利率同比拆解、利润流向、经营现金流与净利润(年度)、三大现金流与现金净增加(年度) 将“增长是否兑现为利润”与利润质量放在同一叙事中
费用率 利润率与费用率拆解、费用结构与费用率(年度) 从费率和金额两个角度拆解利润率变化
资产负债 资产结构演变、现金、负债与净营运资本、营运资本效率 观察资本与资产结构、流动性、资金占用和现金转换周期
IP 与品类 IP 收入趋势/占比、非 THE MONSTERS IP、品类结构 观察 IP 集中度与品类演变
区域渠道 区域渠道分布、同比增速、同比增速趋势、渠道收入结构与增速 观察全球化与渠道驱动

成长性不是泡泡玛特的独立 Tab。 目前它只有“营收到利润的增速对比”一张图,且目标是解释利润增长,因此归入“盈利能力”。未来若有多张独立增长主题图(如收入、门店、海外、分部增速),再恢复单独的“成长性”Tab。

“利润流向”是单期的利润结构细节,放在“盈利能力”而非概览。


5. 数据与时间维度

5.1 CSV 约定

  • 每图一份 CSV;同一图的年度、半年、季度视图使用各自 CSV。
  • 一份 CSV 只表达一种期间口径,禁止混合累计和单期含义。
  • CSV 保留四位年份;显示层可简写。H2 的含义必须以数据口径为准:若为下半年单期,不得显示成全年累计。
  • 同比、环比、核心利润等需要计算的指标,应在 CSV 整理阶段明确生成;前端不自动从累计值推导单季或下半年。
  • CSV 至少包含 period 和该图需要的指标列;单位、口径与重要计算方式通过图表脚注说明。

5.2 可选周期切换

需要切换年度、半年、季度的图,可在 chartCatalog 中使用 views 替代单个 csv:

{
  "key": "some-chart",
  "title": "净利润与同比",
  "defaultView": "annual",
  "views": {
    "annual": "data/company/net_profit_annual.csv",
    "halfyear": "data/company/net_profit_halfyear.csv",
    "quarter": "data/company/net_profit_quarter.csv"
  }
}

页面仅在声明多个视图时显示切换按钮,并将选择写入 URL query。当前泡泡玛特图表没有强制启用这一功能;基础能力已保留,等真实数据需要时再登记。


6. 视觉一致性与新增图表

新增图表必须复用 theme.js 的 FONT、PALETTE、LAYOUT、periodAxis()、standardLegend()、lineSeries()、barSeries()、footnote() 与 watermarks(),而不是在单个图表中重复手写基础样式。

  • 财务含义相同的系列应使用固定语义色;IP、区域、品类等多分类数据使用统一分类色板。
  • 柱线组合图采用已确认的“轻快消费”色板:柱状系列用不同色相承载分类,折线只保留一条高辨识度强调色。现金流、利润与同比使用 FINANCIAL_COLORS,渠道使用 CHANNEL_COLORS;瀑布图使用 BRIDGE_COLORS(蓝色基准、青绿色正向、珊瑚红负向)。新图不得在图表文件内散落同等语义的十六进制颜色。
  • 一张图只保留一个视觉主角。辅助柱使用中等饱和度,避免多个红、橙、紫同时争夺注意力;分类图的相邻系列须同时拉开色相与明度。
  • 颜色不是唯一编码:折线还须依靠线宽、实虚线、空心圆点和标签优先级;柱线混合图的折线标签使用 lineDataWithSafeLabels() 等通用避让规则,避免文字压在柱端。
  • 新图的业务差异由 chart 文件表达;统一视觉由主题文件表达;展示位置与 CSV 由 manifest 表达。
  • 新增或调整图表后,必须检查标签、图例、脚注和控制器是否重叠,以及颜色与文字是否有足够对比度。

通用图表模板仍然后置。只有至少两家公司需要相同图型、字段映射与口径已稳定时,才抽取 template(rows, meta, { width, height }) => option;在此之前,保留一图一文件更低风险。


7. 校验、发布与维护

7.1 当前校验

pnpm test 会遍历每家公司的 chartCatalog,以 ECharts SSR 渲染所有图表并检查:

  • 图表 key 已在 registry 注册;
  • CSV 可读取;
  • Tab 的 chartRefs 都存在,且同一 Tab 不重复;
  • 图例、网格、折线圆点等共享视觉规范;
  • SVG 导出没有字体引号导致的非法属性。

截至当前,仓库登记 27 张图表(泡泡玛特 22 张、示例 5 张)。概览中的重复展示不增加图表定义或测试数量。

7.2 日常工作流

  1. 更新已有数据:替换对应 CSV,检查口径与脚注,运行 pnpm test。
  2. 新增图表:新增 CSV → 新增图表构建文件 → 在 registry 注册 key → 在公司的 chartCatalog 登记一次 → 在需要的 Tab 增加 chartRefs。
  3. 调整首页:只调整 overview.chartRefs 的选择与顺序,不复制任何图表配置。
  4. 发布静态文件:运行 pnpm build;产物只包含运行需要的 manifest 和 CSV,不包含 data/*/raw/ 中的原始文件。

8. 明确后置的能力

  • 原始 PDF 自动抽取与全自动财务勾稽;
  • 自动将累计半年/季度数据拆分为单期;
  • 全公司统一指标库与 schema 强校验;
  • 现金流、人效、偿债等通用模板;
  • 截图像素级视觉回归。

这些能力并非不需要,而是在当前“先把现有公司稳定用起来”的阶段不应抢占开发成本。出现第二家公司、稳定重复的数据与图型后,再按实际痛点逐项引入。