epic-016-mini-charts-package.md 15 KB

史诗016 - mini小程序图表组件包(mini-charts)

史诗目标

docs/小程序图表库示例/ 目录下的 u-charts 图表库(约7700行代码)迁移为独立的 mini-ui-packages 共享包 mini-charts,为 Taro 小程序提供完整的图表解决方案,支持柱状图、折线图、K线图等多种图表类型。

史诗描述

现有系统上下文

当前相关功能:

  • u-charts 图表库:位于 docs/小程序图表库示例/u-charts小程序图表库.js,是一个高性能跨平台图表库
  • 支持平台:H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台
  • 示例代码docs/小程序图表库示例/使用示例.md 提供了完整的 React + Taro 使用示例
  • 版本信息:v2.5.0-20230101

技术特性:

  • 支持多种图表类型:柱状图(column)、折线图(line)、K线图(candle)、饼图、雷达图等
  • 支持Canvas绘制,高性能渲染
  • 支持触摸交互:tooltip显示、拖拽滚动
  • 支持数据标签、图例、动画效果
  • 高度可配置:颜色、字体、网格、坐标轴等
  • 响应式设计,支持多种屏幕尺寸和像素比

集成点:

  • Taro Canvas API
  • React 18组件系统
  • 小程序平台适配(微信小程序为主)
  • 与现有 mini-ui-packages 包结构保持一致
  • 与现有测试框架(Jest)集成

当前架构分析:

  1. 图表库未模块化:u-charts 库文件位于文档目录下,未形成可复用的包
  2. 缺少类型定义:原库为纯JavaScript,缺少TypeScript类型支持
  3. 缺少React组件封装:示例代码展示的是类组件使用方式,需要现代函数式组件封装
  4. 缺少测试:没有针对图表组件的测试套件
  5. 缺少文档:只有使用示例,缺少完整的API文档

增强详情

改造范围: 本次史诗将完成以下工作:

阶段1:创建 mini-charts 包基础结构(故事016.001)

  1. 创建新的包 mini-ui-packages/mini-charts
  2. 配置 package.json,依赖 Taro 相关包
  3. 设置 TypeScript 配置和类型定义
  4. 配置构建和测试脚本
  5. 迁移 u-charts 核心库文件

阶段2:重构 u-charts 核心库模块化(故事016.006)

  1. 分析当前 u-charts.ts 文件结构(7719行)
  2. 按功能模块拆分为多个文件
  3. 保持向后兼容性
  4. 确保拆分后功能完整性

阶段3:添加 TypeScript 类型定义(故事016.002)

  1. 为重构后的 u-charts 库添加完整的 TypeScript 类型定义
  2. 定义图表配置接口(ChartConfig、SeriesConfig、AxisConfig等)
  3. 定义图表类型枚举(ChartType)
  4. 导出类型供使用者使用

阶段4:创建 React 组件封装(故事016.003)

  1. 创建现代函数式图表组件:
    • ColumnChart(柱状图)
    • LineChart(折线图)
    • CandleChart(K线图)
    • PieChart(饼图)
    • RadarChart(雷达图)
  2. 使用 Taro Canvas API 封装底层绘图逻辑
  3. 支持触摸事件处理(tooltip、拖拽)
  4. 支持响应式尺寸计算

阶段5:创建使用示例和文档(故事016.004)

  1. 在包内创建 examples 目录
  2. 提供完整的示例代码
  3. 创建 API 文档
  4. 更新使用示例.md

阶段6:创建测试套件(故事016.005)

  1. 设置 Jest 测试环境
  2. 创建图表组件单元测试
  3. 创建 Canvas mock 用于测试
  4. 验证组件渲染和交互

迁移策略:

  1. 保留原始逻辑:保持 u-charts 核心绘制逻辑不变
  2. 渐进式封装:先迁移核心库,再添加类型定义,最后创建 React 组件
  3. 向后兼容:提供直接使用 u-charts 类的接口
  4. 测试驱动:为每个组件编写测试

成功标准:

  1. mini-charts 包创建成功,可通过 workspace 引用
  2. u-charts 核心库成功迁移,功能完整
  3. TypeScript 类型定义完整,无 any 类型
  4. 提供至少5种常用图表组件(柱状图、折线图、K线图、饼图、雷达图)
  5. 组件可以独立测试(类型检查和 Jest 测试通过)
  6. 提供完整的示例和文档
  7. 可以被 mini 项目或其他 mini-ui-packages 引用

故事列表

故事016-001:创建 mini-charts 包基础结构

背景: u-charts 图表库目前位于文档目录下,需要迁移为独立的共享包,以便在多个小程序项目中复用。

任务列表:

  1. 创建新的包 mini-ui-packages/mini-charts
    • 配置 package.json,依赖 Taro 相关包
    • 设置 TypeScript 配置(tsconfig.json)
    • 配置构建和测试脚本
  2. 迁移 u-charts 核心库文件:
    • docs/小程序图表库示例/u-charts小程序图表库.js 迁移到 src/lib/u-charts.ts
    • 保持原始逻辑不变
    • 将文件转换为 TypeScript 格式(添加基础类型)
  3. 创建包的导出配置:
    • 建立 src/index.ts 主入口
    • 导出 u-charts 核心类
    • 配置 package.json 的 exports 字段

验收标准:

  • mini-charts 包目录结构创建完成
  • package.json 配置正确,包含所有必需依赖
  • tsconfig.json 配置正确
  • u-charts 核心库迁移成功,无语法错误
  • 包可以成功构建(tsc 编译通过)
  • 类型检查通过(pnpm typecheck)

故事016-006:重构 u-charts 核心库模块化

背景: 当前 u-charts.ts 文件包含7719行代码,所有功能都在一个文件中,包括42个绘制函数、约60个工具/数据处理函数以及2个类。这种结构不利于代码维护、测试和后续的类型定义添加。

任务列表:

  1. 分析当前 u-charts.ts 文件结构:
    • 识别所有函数和类的职责
    • 分析函数之间的依赖关系
    • 确定模块划分方案
  2. 创建模块化目录结构:

    src/lib/
    ├── index.ts                    # 统一导出,保持向后兼容
    ├── config.ts                   # 配置常量(config、assign等)
    ├── utils/                      # 工具函数模块
    │   ├── index.ts
    │   ├── color.ts                # 颜色工具(hexToRgb等)
    │   ├── math.ts                 # 数学工具(findRange、normalInt等)
    │   ├── coordinate.ts           # 坐标转换(convertCoordinateOrigin等)
    │   ├── text.ts                 # 文本测量(measureText等)
    │   └── collision.ts            # 碰撞检测(avoidCollision等)
    ├── data-processing/            # 数据处理模块
    │   ├── index.ts
    │   ├── series-calculator.ts    # 系列数据处理
    │   ├── axis-calculator.ts      # 坐标轴计算
    │   ├── categories-calculator.ts # 分类数据处理
    │   └── tooltip-calculator.ts   # 提示框数据计算
    ├── charts-data/                # 图表数据点计算
    │   ├── index.ts
    │   ├── basic-charts.ts         # 基础图表数据点
    │   ├── pie-charts.ts           # 饼图数据点
    │   ├── radar-charts.ts         # 雷达图数据点
    │   ├── map-charts.ts           # 地图数据点
    │   └── other-charts.ts         # 其他图表数据点
    ├── renderers/                  # 绘制函数模块
    │   ├── index.ts
    │   ├── common-renderer.ts      # 通用绘制(drawPointShape、drawToolTip等)
    │   ├── axis-renderer.ts        # 坐标轴绘制
    │   ├── column-renderer.ts      # 柱状图绘制
    │   ├── line-renderer.ts        # 折线图绘制
    │   ├── candle-renderer.ts      # K线图绘制
    │   ├── pie-renderer.ts         # 饼图绘制
    │   ├── radar-renderer.ts       # 雷达图绘制
    │   ├── map-renderer.ts         # 地图绘制
    │   └── special-renderer.ts     # 特殊图表绘制(词云、漏斗等)
    └── charts/                     # 核心类模块
       ├── index.ts
       ├── u-charts-event.ts       # 事件类
       └── u-charts.ts             # 主类(重构后)
    
  3. 拆分文件(按优先级):

    • 第一批:配置和工具函数(低依赖)
      • 创建 config.ts,导出 config、assign、util
      • 创建 utils/ 目录下的文件
    • 第二批:数据处理函数(中依赖)
      • 创建 data-processing/ 目录
      • 创建 charts-data/ 目录
    • 第三批:绘制函数(高依赖)
      • 创建 renderers/ 目录
    • 第四批:核心类重构
      • 重构 u-charts.ts,导入所有模块
      • 移动 uChartsEvent 类到独立文件
  4. 更新 src/index.ts:

    • 导出所有公共API
    • 保持向后兼容性(默认导出 uCharts 类)
    • 导出各个模块供高级用户使用
  5. 验证拆分结果:

    • 确保所有导出正确
    • 运行类型检查
    • 如果有现有测试,确保测试通过

验收标准:

  • u-charts.ts 成功拆分为多个模块文件
  • 每个模块职责单一、边界清晰
  • 所有函数和类正确导出
  • src/index.ts 保持向后兼容,默认导出 uCharts 类
  • 类型检查通过(pnpm typecheck)
  • 包可以成功构建
  • 代码组织清晰,易于维护和测试
  • 模块间依赖关系合理,无循环依赖

技术注意事项:

  • 拆分时保持函数逻辑完全不变,只改变文件组织
  • 使用相对导入确保模块间正确引用
  • 注意 TypeScript 的类型导出
  • 保持原有的代码风格
  • 拆分后每个文件控制在500行以内

风险缓解:

  • 在拆分前备份原始文件
  • 分批拆分,每批完成后进行验证
  • 使用 Git 版本控制,便于回滚
  • 拆分过程中保持构建可运行状态

故事016-002:添加 TypeScript 类型定义

背景: 在故事016.006完成模块化重构后,需要为重构后的 u-charts 库添加完整的 TypeScript 类型定义。原库为纯JavaScript,缺少类型支持。模块化后的结构更容易添加类型,提高开发体验和代码安全性。

任务列表:

  1. 分析重构后的 u-charts 库结构:
    • 理解各模块的导出内容
    • 识别公共 API 和内部 API
    • 参考使用示例.md 中的配置
  2. 定义核心 TypeScript 接口(types/ 目录):
    • ChartConfig:图表总配置接口
    • ChartType:图表类型枚举('column' | 'line' | 'candle' | 'pie' | 'radar' 等)
    • SeriesConfig:数据系列配置
    • AxisConfig:坐标轴配置(X轴、Y轴)
    • ExtraConfig:各种图表的额外配置
    • ColorConfig:颜色配置
  3. 为各模块添加类型定义:
    • utils/ 模块的函数类型
    • data-processing/ 模块的函数类型
    • renderers/ 模块的函数类型
    • uCharts 和 uChartsEvent 类的类型
  4. 导出所有类型供使用者使用
  5. 创建 types/index.ts 统一导出所有类型

验收标准:

  • 所有配置选项都有对应的类型定义
  • ChartType 枚举包含所有支持的图表类型
  • 类型定义完整,无 any 类型(除非必要)
  • 类型导出正确,可以被使用者导入
  • 类型检查通过,无类型错误

故事016-003:创建 React 图表组件封装

背景: u-charts 原库需要手动管理 Canvas 上下文和事件处理。需要创建现代 React 函数式组件,简化使用方式。

任务列表:

  1. 创建基础图表组件 BaseChart:
    • 封装 Canvas 创建和销毁逻辑
    • 处理响应式尺寸计算
    • 处理像素比适配
    • 封装事件处理(触摸、点击)
  2. 创建具体图表组件:
    • ColumnChart(柱状图)
    • LineChart(折线图)
    • CandleChart(K线图)
    • PieChart(饼图)
    • RadarChart(雷达图)
  3. 每个组件包含:
    • Props 接口定义
    • 默认配置
    • Canvas 绘制逻辑
    • 事件处理(tooltip、拖拽等)
  4. docs/小程序图表库示例/使用示例.md 迁移示例代码作为参考

验收标准:

  • BaseChart 基础组件创建完成
  • 至少5种图表组件实现完成
  • 组件支持 Props 配置
  • 组件支持触摸事件(tooltip)
  • 组件支持响应式尺寸
  • 类型定义完整,无类型错误

故事016-004:创建使用示例和文档

背景: 需要提供完整的使用示例和 API 文档,帮助开发者快速上手使用 mini-charts 包。

任务列表:

  1. 创建 examples 目录:
    • 迁移并更新 docs/小程序图表库示例/使用示例.md 中的示例
    • 为每种图表类型创建独立示例
    • 创建复杂场景示例(混合图表、多轴图表等)
  2. 创建 README.md:
    • 包简介和特性
    • 安装说明
    • 快速开始指南
    • API 文档
    • 配置选项说明
    • 常见问题解答
  3. 更新原使用示例文档,指向新包的使用方式

验收标准:

  • examples 目录创建完成,包含至少3个示例
  • README.md 文档完整,包含所有必需章节
  • API 文档详细,覆盖所有公共接口
  • 配置选项说明清晰,包含示例
  • 原使用示例文档已更新

故事016-005:创建测试套件

背景: 需要为图表组件创建完整的测试套件,确保组件质量和稳定性。

任务列表:

  1. 设置 Jest 测试环境:
    • 配置 jest.config.js
    • 创建 Taro 和 Canvas 的 mock
  2. 创建工具函数:
    • createMockCanvasContext:创建模拟 Canvas 上下文
    • waitForChartRender:等待图表渲染完成
  3. 编写组件测试:
    • 测试组件渲染
    • 测试 Props 传递
    • 测试事件处理
    • 测试响应式尺寸
  4. 编写集成测试:
    • 测试图表数据更新
    • 测试图表交互

验收标准:

  • Jest 测试环境配置完成
  • Canvas mock 创建完成
  • 每个图表组件都有单元测试
  • 测试覆盖率达到 60% 以上
  • 所有测试通过

兼容性要求

  • 保持 u-charts 原库功能完整性
  • 支持微信小程序平台
  • 支持 Taro 4.1.4 框架
  • 支持 React 18
  • 向后兼容,支持直接使用 u-charts 类

风险缓解

  • 主要风险:u-charts 库文件较大(约7700行),迁移过程中可能遗漏功能
  • 缓解措施:保留原始文件,迁移后进行功能对比测试
  • 回滚计划:如果迁移导致问题,可以从文档目录重新使用原文件
  • 类型定义风险:原库没有类型,可能存在类型定义不准确的问题
  • 缓解措施:先添加基础类型,然后逐步完善,使用 any 作为过渡

完成定义

  • 所有故事完成,验收标准满足
  • 类型检查通过,无 TypeScript 错误
  • 所有测试通过,包括单元测试和集成测试
  • 代码审查通过,符合项目编码标准
  • 文档完整,包含使用示例和 API 文档
  • 包可以被其他 mini-ui-packages 或 mini 项目引用

附件