فهرست منبع

♻️ refactor(mini-charts): 统一图表组件架构并删除冗余代码

- 将 BaseChartOriginal2D 重命名为 BaseChart 作为统一基础组件
- 删除旧版组件:BaseChartLegacy、ColumnChartLegacy、CandleChart、RadarChart
- 重构 BarChart、ColumnChart、LineChart、PieChart 组件,使其基于新的 BaseChart
- 简化组件接口,移除冗余配置选项,统一使用 Canvas 2D API
- 更新 yongren-statistics-ui 中的 Statistics.tsx,移除调试代码和旧组件引用
- 添加重构故事文档,详细记录重构策略和验收标准

📝 docs(stories): 添加 mini-charts 组件重构故事文档

- 创建 018.001.refactor-mini-charts-components.story.md 文档
- 详细描述重构背景、目标、策略和验收标准
- 提供技术实现细节和任务分解
- 记录需要删除和保留的文件列表
yourname 2 هفته پیش
والد
کامیت
7190f90f35

+ 256 - 0
docs/stories/018.001.refactor-mini-charts-components.story.md

@@ -0,0 +1,256 @@
+# 故事 018.001 - 规整 mini-charts 组件
+
+## 元数据
+| 字段 | 值 |
+|------|-----|
+| **史诗** | 018 |
+| **故事ID** | 018.001 |
+| **标题** | 规整 mini-charts 组件 |
+| **状态** | In Progress |
+| **优先级** | 高 |
+| **故事点** | 5 |
+| **项目负责人** | James (Claude Code) |
+
+## 故事描述
+规整 `mini-ui-packages/mini-charts/src/components` 中的图表组件,统一使用 `BaseChartOriginal2D` 作为基础组件,删除冗余的旧组件,并在 `yongren-statistics-ui` 中更新使用新组件。
+
+## 背景
+当前 `mini-charts` 包中存在多个版本的图表组件:
+- **BaseChartOriginal2D** - 基于原始 u-charts.js + Canvas 2D API 的最新实现
+- **BaseChart** - 模块化TypeScript版本
+- **BaseChartLegacy** - 旧Canvas API版本
+- **ColumnChartOriginal2D** - 基于 BaseChartOriginal2D 的柱状图(参考实现)
+- **ColumnChart** - 基于 BaseChart 的柱状图
+- **ColumnChartLegacy** - 基于 BaseChartLegacy 的柱状图
+- **ColumnChartFCExample** - 文档示例组件
+- **BarChart、PieChart、LineChart** - 基于 BaseChart 的其他图表
+
+这导致代码冗余、维护困难,需要统一技术栈。
+
+## 目标
+1. 统一所有图表组件使用 `BaseChart` 作为基础(原 BaseChartOriginal2D 重命名)
+2. 删除冗余的旧组件(BaseChart、BaseChartLegacy、ColumnChart、ColumnChartLegacy等)
+3. 更新 `yongren-statistics-ui` 使用新组件
+4. 保持API一致性,方便使用
+
+## 重构策略
+1. **BaseChartOriginal2D → BaseChart**: 删除旧的 BaseChart.tsx 后,将 BaseChartOriginal2D.tsx 重命名为 BaseChart.tsx
+2. **其他组件**: 创建 ColumnChart、BarChart、PieChart、LineChart,基于新的 BaseChart
+3. **保持内部一致性**: 所有组件都使用统一的 BaseChart 作为基础
+
+## 验收标准
+### 功能性验收
+- [ ] BaseChartOriginal2D.tsx 重命名为 BaseChart.tsx(替换旧的 BaseChart.tsx)
+- [ ] 所有图表组件(ColumnChart、BarChart、PieChart、LineChart)使用新的 BaseChart
+- [ ] 删除 BaseChartLegacy.tsx、ColumnChart.tsx、ColumnChartLegacy.tsx
+- [ ] yongren-statistics-ui 的 Statistics.tsx 使用新组件且功能正常
+- [ ] 所有图表渲染正常,无报错
+
+### 技术性验收
+- [ ] 代码符合 Mini UI包开发规范
+- [ ] 组件结构简洁清晰
+- [ ] 组件Props类型定义完整
+- [ ] 所有默认配置保持一致
+
+### 测试验收
+- [ ] yongren-statistics-ui 包的测试通过
+- [ ] 图表能够正常渲染和交互
+- [ ] 无 TypeScript 类型错误
+
+## 技术实现细节
+
+### 重构步骤
+
+#### 步骤1: 删除旧组件,重命名 BaseChartOriginal2D
+1. 删除 `BaseChart.tsx`(旧版本)
+2. 将 `BaseChartOriginal2D.tsx` 重命名为 `BaseChart.tsx`
+3. 更新内部导入引用
+
+#### 步骤2: 创建/更新图表组件
+所有图表组件(ColumnChart、BarChart、PieChart、LineChart)基于新的 BaseChart 创建:
+
+**参考模板**(以 ColumnChart 为例):
+```typescript
+import React from 'react';
+import { BaseChart } from './BaseChart';
+import type { ChartsConfig } from '../lib/u-charts-original';
+
+export interface ColumnChartProps {
+  canvasId: string;
+  width?: number;
+  height?: number;
+  categories: string[];
+  series: ChartsConfig['series'];
+  config?: Partial<ChartsConfig>;
+}
+
+export const ColumnChart: React.FC<ColumnChartProps> = (props) => {
+  const { canvasId, width, height, categories, series, config = {} } = props;
+
+  const mergedConfig: Partial<ChartsConfig> = {
+    animation: true,
+    background: '#FFFFFF',
+    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+    padding: [15, 15, 0, 5],
+    enableScroll: false,
+    legend: {},
+    xAxis: { disableGrid: true, ...config.xAxis },
+    yAxis: { data: [{ min: 0 }], ...config.yAxis },
+    extra: {
+      column: {
+        type: 'group',
+        width: 30,
+        activeBgColor: '#000000',
+        activeBgOpacity: 0.08,
+        ...config.extra?.column,
+      }
+    },
+    ...config,
+  };
+
+  return (
+    <BaseChart
+      canvasId={canvasId}
+      width={width}
+      height={height}
+      type="column"
+      categories={categories}
+      series={series}
+      config={mergedConfig}
+    />
+  );
+};
+```
+
+**组件列表**:
+- **ColumnChart**: 柱状图(type="column")
+- **BarChart**: 横向柱状图(type="bar")
+- **PieChart**: 饼图/环形图(type="pie" 或 "ring")
+- **LineChart**: 折线图(type="line")
+
+### 需要删除的文件
+- `BaseChart.tsx`(旧版本,删除后由 BaseChartOriginal2D 替代)
+- `BaseChartLegacy.tsx`
+- `ColumnChart.tsx`(旧版本)
+- `ColumnChartLegacy.tsx`
+- `CandleChart.tsx`(如果不使用)
+- `RadarChart.tsx`(如果不使用)
+- `BarChart.tsx`(旧版本)
+- `PieChart.tsx`(旧版本)
+- `LineChart.tsx`(旧版本)
+
+**保留文件**(用于调试对比):
+- `ColumnChartFCExample.tsx` - 保留作为文档参考实现
+
+### 更新 Statistics.tsx
+替换导入:
+```typescript
+// 旧导入
+import { ColumnChart } from '@d8d/mini-charts/components/ColumnChart'
+import { BarChart } from '@d8d/mini-charts/components/BarChart'
+import { PieChart } from '@d8d/mini-charts/components/PieChart'
+
+// 新导入 - 直接从组件文件路径导入
+import { ColumnChart } from '@d8d/mini-charts/src/components/ColumnChart'
+import { BarChart } from '@d8d/mini-charts/src/components/BarChart'
+import { PieChart } from '@d8d/mini-charts/src/components/PieChart'
+import { LineChart } from '@d8d/mini-charts/src/components/LineChart'
+```
+
+## 任务分解
+
+### Task 1: 删除旧组件,重命名 BaseChartOriginal2D
+- [ ] 删除旧版 BaseChart.tsx
+- [ ] 将 BaseChartOriginal2D.tsx 重命名为 BaseChart.tsx
+- [ ] 删除 BaseChartLegacy.tsx
+- [ ] 删除旧版 ColumnChart.tsx、BarChart.tsx、PieChart.tsx、LineChart.tsx
+- [ ] 删除 ColumnChartLegacy.tsx
+
+### Task 2: 创建 ColumnChart
+- [ ] 基于新的 BaseChart 创建 ColumnChart.tsx
+- [ ] 使用 type="column"
+- [ ] 合并默认配置
+- [ ] 导出组件
+
+### Task 3: 创建 BarChart
+- [ ] 基于新的 BaseChart 创建 BarChart.tsx
+- [ ] 使用 type="bar"
+- [ ] 合并默认配置
+- [ ] 导出组件
+
+### Task 4: 创建 PieChart
+- [ ] 基于新的 BaseChart 创建 PieChart.tsx
+- [ ] 支持 type="pie" 和 "ring"
+- [ ] 合并默认配置
+- [ ] 导出组件
+
+### Task 5: 创建 LineChart
+- [ ] 基于新的 BaseChart 创建 LineChart.tsx
+- [ ] 使用 type="line"
+- [ ] 合并默认配置
+- [ ] 导出组件
+
+### Task 6: 更新 Statistics.tsx
+- [ ] 更新导入路径(使用 @d8d/mini-charts/src/components/...)
+- [ ] 验证所有图表正常渲染
+- [ ] 移除调试用的条件渲染代码
+
+### Task 7: 测试验证
+- [ ] 构建 mini-charts 包
+- [ ] 构建 yongren-statistics-ui 包
+- [ ] 运行测试确认无错误
+
+## Dev Notes
+
+### 关键点
+1. **类型导入**: 使用 `import type { ChartsConfig } from '../lib/u-charts-original'`
+2. **配置合并**: 使用展开运算符合并用户配置和默认配置
+3. **组件命名**: 使用简洁的名称(ColumnChart、BarChart、PieChart、LineChart),不再使用 Original2D 后缀
+4. **默认配置**: 保持与原 ColumnChartOriginal2D 的默认配置结构一致
+5. **BaseChart**: 原来的 BaseChartOriginal2D 重命名为 BaseChart,作为所有图表的基础组件
+
+### 注意事项
+- 重命名时更新 BaseChart 内部的导出名称
+- 不要修改 `u-charts-original.js`
+- 保持与原组件的API兼容性
+- 组件应该是纯展示组件,不需要内部状态
+- index.ts 保持为空,不导出任何组件
+
+## Agent Model Used
+Claude Sonnet 4.5
+
+## Debug Log References
+无
+
+## Completion Notes
+待完成...
+
+## File List
+### 新建文件
+- `docs/stories/018.001.refactor-mini-charts-components.story.md`
+
+### 修改文件
+- `mini-ui-packages/mini-charts/src/components/BaseChart.tsx`(重命名自 BaseChartOriginal2D.tsx)
+- `mini-ui-packages/mini-charts/src/components/ColumnChart.tsx`(新建,基于 BaseChart)
+- `mini-ui-packages/mini-charts/src/components/BarChart.tsx`(新建,基于 BaseChart)
+- `mini-ui-packages/mini-charts/src/components/PieChart.tsx`(新建,基于 BaseChart)
+- `mini-ui-packages/mini-charts/src/components/LineChart.tsx`(新建,基于 BaseChart)
+- `mini-ui-packages/mini-charts/src/components/index.ts`(保持为空)
+- `mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx`(更新导入路径)
+
+### 删除文件
+- `mini-ui-packages/mini-charts/src/components/BaseChart.tsx`(旧版本,删除前由 BaseChartOriginal2D 替代)
+- `mini-ui-packages/mini-charts/src/components/BaseChartOriginal2D.tsx`(重命名为 BaseChart.tsx 后删除)
+- `mini-ui-packages/mini-charts/src/components/BaseChartLegacy.tsx`
+- `mini-ui-packages/mini-charts/src/components/ColumnChart.tsx`(旧版本)
+- `mini-ui-packages/mini-charts/src/components/ColumnChartOriginal2D.tsx`(保留参考)
+- `mini-ui-packages/mini-charts/src/components/ColumnChartLegacy.tsx`
+- `mini-ui-packages/mini-charts/src/components/BarChart.tsx`(旧版本)
+- `mini-ui-packages/mini-charts/src/components/PieChart.tsx`(旧版本)
+- `mini-ui-packages/mini-charts/src/components/LineChart.tsx`(旧版本)
+- 可能删除 `mini-ui-packages/mini-charts/src/components/CandleChart.tsx`
+- 可能删除 `mini-ui-packages/mini-charts/src/components/RadarChart.tsx`
+
+**保留文件**:
+- `ColumnChartOriginal2D.tsx` - 作为参考实现保留
+- `ColumnChartFCExample.tsx` - 调试用参考实现

+ 54 - 84
mini-ui-packages/mini-charts/src/components/BarChart.tsx

@@ -1,111 +1,81 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
-
-/**
- * 条形图类型(横向柱状图)
- */
-export type BarType = 'group' | 'stack';
+import React from 'react';
+import { BaseChart } from './BaseChart';
+import type { ChartsConfig } from '../lib/u-charts-original';
 
 
 /**
 /**
  * BarChart 组件的 Props 接口
  * BarChart 组件的 Props 接口
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
-export interface BarChartProps extends Omit<BaseChartProps, 'type'> {
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 条形图类型 */
-  barType?: BarType;
-  /** X 轴配置 */
-  xAxis?: XAxisConfig;
-  /** Y 轴配置 */
-  yAxis?: YAxisConfig;
-  /** 图例是否显示 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
+export interface BarChartProps {
+  /** Canvas 元素的 ID,必须唯一 */
+  canvasId: string;
+  /** 图表宽度(像素) */
+  width?: number;
+  /** 图表高度(像素) */
+  height?: number;
+  /** Y 轴分类数据(条形图的分类在Y轴) */
+  categories: string[];
+  /** 系列数据 */
+  series: ChartsConfig['series'];
+  /** 额外的图表配置 */
+  config?: Partial<ChartsConfig>;
 }
 }
 
 
 /**
 /**
  * BarChart 横向柱状图组件
  * BarChart 横向柱状图组件
  *
  *
- * 用于显示分类数据的横向柱状图,支持分组和堆叠模式
- * 与 ColumnChart 的区别在于坐标轴交换,类别在 Y 轴,数值在 X 轴
+ * 使用原始 u-charts.js + Canvas 2D API
+ * 用于显示分类数据的横向柱状图
  */
  */
 export const BarChart: React.FC<BarChartProps> = (props) => {
 export const BarChart: React.FC<BarChartProps> = (props) => {
   const {
   const {
-    dataLabel = true,
-    barType = 'group',
-    xAxis,
-    yAxis,
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    tooltipFormatter,
-    categories = [],
-    series = [],
+    canvasId,
+    width,
+    height,
+    categories,
+    series,
     config = {},
     config = {},
-    ...baseProps
   } = props;
   } = props;
 
 
-  const chartRef = React.useRef<any>(null);
-
   /**
   /**
-   * 默认配置
+   * 合并默认配置
    */
    */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    return {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      xAxis: xAxis ?? { disableGrid: true },
-      yAxis: yAxis ?? {},
-      extra: {
-        bar: {
-          type: barType,
-          width: barType === 'group'
-            ? (baseProps.height ? baseProps.height * 0.45 / (categories.length || 1) : 20)
-            : undefined
-        }
+  const mergedConfig: Partial<ChartsConfig> = {
+    animation: true,
+    background: '#FFFFFF',
+    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+    padding: [15, 15, 0, 5],
+    enableScroll: false,
+    legend: {},
+    xAxis: {
+      disableGrid: true,
+      ...config.xAxis,
+    },
+    yAxis: {
+      data: [{ min: 0 }],
+      ...config.yAxis,
+    },
+    extra: {
+      bar: {
+        type: 'group',
+        width: 30,
+        activeBgColor: '#000000',
+        activeBgOpacity: 0.08,
+        ...config.extra?.bar,
       }
       }
-    };
-  }, [legend, fontSize, background, animation, dataLabel, xAxis, yAxis, barType, categories.length, baseProps.height]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current && tooltipFormatter) {
-      chartRef.current.showToolTip(e, {
-        formatter: tooltipFormatter
-      });
-    } else if (chartRef.current) {
-      chartRef.current.showToolTip(e, {
-        formatter: (item: any, category: string) => {
-          return category + ' ' + item.name + ':' + item.data;
-        }
-      });
-    }
-    baseProps.onTouchStart?.(e);
+    },
+    ...config,
   };
   };
 
 
   return (
   return (
     <BaseChart
     <BaseChart
-      {...baseProps}
+      canvasId={canvasId}
+      width={width}
+      height={height}
+      type="bar"
       categories={categories}
       categories={categories}
       series={series}
       series={series}
-      type="bar"
-      config={{ ...defaultConfig, ...config }}
-      onTouchStart={handleTouchStart}
+      config={mergedConfig}
     />
     />
   );
   );
 };
 };

+ 172 - 93
mini-ui-packages/mini-charts/src/components/BaseChart.tsx

@@ -1,22 +1,21 @@
-import React, { useEffect, useRef, useMemo } from 'react';
+import React, { useState, useRef, useLayoutEffect, useMemo } from 'react';
 import Taro from '@tarojs/taro';
 import Taro from '@tarojs/taro';
 import { Canvas } from '@tarojs/components';
 import { Canvas } from '@tarojs/components';
-import { uCharts } from '../lib/charts/index';
-import type { ChartsConfig, TouchEvent } from '../lib/charts/index';
+import uChartsClass from '../lib/u-charts-original.js';
+import type { ChartsConfig, TouchEvent } from '../lib/u-charts-original';
 import type { ExtendedCanvasContext } from '../types';
 import type { ExtendedCanvasContext } from '../types';
 
 
 /**
 /**
  * BaseChart 组件的 Props 接口
  * BaseChart 组件的 Props 接口
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
 export interface BaseChartProps {
 export interface BaseChartProps {
   /** Canvas 元素的 ID,必须唯一 */
   /** Canvas 元素的 ID,必须唯一 */
   canvasId: string;
   canvasId: string;
-  /** 图表宽度(像素),默认为屏幕宽度 */
+  /** 图表宽度(像素),默认为 750 */
   width?: number;
   width?: number;
-  /** 图表高度(像素),默认根据宽高比计算 */
+  /** 图表高度(像素),默认为 500 */
   height?: number;
   height?: number;
-  /** 设备像素比,默认根据环境自动设置 */
-  pixelRatio?: number;
   /** 图表类型 */
   /** 图表类型 */
   type: ChartsConfig['type'];
   type: ChartsConfig['type'];
   /** X 轴分类数据 */
   /** X 轴分类数据 */
@@ -34,16 +33,16 @@ export interface BaseChartProps {
 }
 }
 
 
 /**
 /**
- * BaseChart 基础图表组件
+ * BaseChartInner 内部组件
  *
  *
- * 封装 Canvas 创建和销毁逻辑,提供响应式尺寸计算和像素比适配
+ * 实际的图表渲染组件,只在数据准备好后才会挂载
+ * 使用空依赖数组确保只初始化一次
  */
  */
-export const BaseChart: React.FC<BaseChartProps> = (props) => {
+const BaseChartInner: React.FC<BaseChartProps> = (props) => {
   const {
   const {
     canvasId,
     canvasId,
-    width,
-    height,
-    pixelRatio,
+    width = 750,
+    height = 500,
     type,
     type,
     categories = [],
     categories = [],
     series = [],
     series = [],
@@ -53,109 +52,138 @@ export const BaseChart: React.FC<BaseChartProps> = (props) => {
     onTouchEnd,
     onTouchEnd,
   } = props;
   } = props;
 
 
-  const chartRef = useRef<uCharts | null>(null);
+  const [cWidth, setCWidth] = useState(750);
+  const [cHeight, setCHeight] = useState(500);
 
 
-  /**
-   * 计算响应式尺寸和像素比
-   */
-  const { cWidth, cHeight, actualPixelRatio } = useMemo(() => {
-    const sysInfo = Taro.getSystemInfoSync();
-    // Canvas 2D 需要使用实际的 pixelRatio 来匹配设备像素
-    // 这样绘制的内容才不会模糊或被放大
-    const pr = pixelRatio ?? sysInfo.pixelRatio;
-    // width 和 height 是逻辑像素(CSS 像素)
-    // Canvas 2D 的实际像素尺寸 = 逻辑像素 * pixelRatio
-    const cw = width ?? pr * sysInfo.windowWidth;
-    const ch = height ?? (500 / 750 * cw);
-    return { cWidth: cw, cHeight: ch, actualPixelRatio: pr };
-  }, [width, height, pixelRatio]);
+  const chartRef = useRef<any>(null);
 
 
   /**
   /**
-   * Canvas props 根据 platform 动态计算
+   * 初始化图表实例
+   * 使用 Canvas 2D API + 原始 u-charts.js
+   * 参考 ColumnChartFCExample 的实现方式
+   *
+   * 注意:使用空依赖数组,只在组件首次挂载时执行一次
+   * 数据变化通过 Wrapper 组件控制重新挂载来实现
    */
    */
-  const canvasProps = useMemo(() => {
-    if (Taro.getEnv() === Taro.ENV_TYPE.ALIPAY) {
-      return {
-        width: String(cWidth),
-        height: String(cHeight),
-        style: { width: '100%', height: '100%' }
-      };
+  useLayoutEffect(() => {
+    console.debug('[BaseChart] useLayoutEffect 开始', { canvasId, width, height });
+
+    // 计算响应式尺寸
+    const sysInfo = Taro.getSystemInfoSync();
+    // 这里的第一个 750 对应 css .charts 的 width
+    const cw = width / 750 * sysInfo.windowWidth;
+    // 这里的 500 对应 css .charts 的 height
+    const ch = height / 750 * sysInfo.windowWidth;
+
+    setCWidth(cw);
+    setCHeight(ch);
+
+    // 确保数据已准备好:categories 和 series 都有数据
+    const isDataReady = categories.length > 0 && series.length > 0;
+
+    if (!isDataReady) {
+      console.log('[BaseChart] 数据未准备好,等待数据...', {
+        canvasId,
+        categoriesLength: categories.length,
+        seriesLength: series.length
+      });
+      return;
     }
     }
-    // Canvas 2D API:
-    // - width/height 属性:实际像素尺寸(逻辑像素 * pixelRatio),需要转为字符串
-    // - style.width/style.height:CSS 显示尺寸(逻辑像素)
-    return {
-      width: String(cWidth * actualPixelRatio),
-      height: String(cHeight * actualPixelRatio),
-      style: { width: `${cWidth}px`, height: `${cHeight}px` }
-    };
-  }, [cWidth, cHeight, actualPixelRatio]);
 
 
-  /**
-   * 初始化图表实例
-   */
-  useEffect(() => {
-    // 使用 setTimeout 确保 Canvas DOM 元素已渲染完成
-    const timer = setTimeout(() => {
-      const rawCtx = Taro.createCanvasContext(canvasId);
-
-      // 检查 canvas 上下文是否有效
-      if (!rawCtx) {
-        console.error('[BaseChart] CanvasContext创建失败!')
-        return
-      }
-
-      // 将 Taro CanvasContext 转换为 uCharts 需要的 CanvasContext
-      // 注意:不能使用展开运算符,因为这会复制方法但丢失 this 指向
-      const ctx = rawCtx as ExtendedCanvasContext;
-
-      // Canvas 2D: 传入 uCharts 的 width/height 需要乘以 pixelRatio
-      // 因为原始 u-charts.js 的绘制坐标基于这些值计算
-      const chartConfig: ChartsConfig = {
-        type,
-        context: ctx,
-        categories,
-        series,
-        width: cWidth * actualPixelRatio,
-        height: cHeight * actualPixelRatio,
-        pixelRatio: actualPixelRatio,
-        ...config,
-      };
-
-      chartRef.current = new uCharts(chartConfig);
-    }, 0)
-
-    return () => {
-      // 清理定时器和图表实例
-      clearTimeout(timer)
-      chartRef.current = null;
-    };
-  }, [canvasId, type, categories, series, cWidth, cHeight, actualPixelRatio, config]);
+    // 延迟初始化图表,等待 Canvas 尺寸渲染完成(参考 FC 示例)
+    setTimeout(() => {
+      // 使用 Canvas 2D API 的方式获取 context
+      const query = Taro.createSelectorQuery();
+      query.select('#' + canvasId).fields({ node: true, size: true }).exec((res) => {
+        if (res[0]) {
+          const canvas = res[0].node;
+          const ctx = canvas.getContext('2d');
+
+          console.debug('[BaseChartOriginal2D] canvas.width', canvas.width);
+          console.debug('[BaseChartOriginal2D] canvas.height', canvas.height);
+
+          // 将 Taro CanvasContext 转换为 uCharts 需要的 CanvasContext
+          const extendedCtx = ctx as ExtendedCanvasContext;
+
+          // Canvas 2D: 使用 canvas 的实际 width/height
+          const chartConfig: ChartsConfig = {
+            type,
+            context: extendedCtx,
+            categories,
+            series,
+            width: canvas.width,
+            height: canvas.height,
+            animation: true,
+            background: '#FFFFFF',
+            color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+            padding: [15, 15, 0, 5],
+            enableScroll: false,
+            legend: {},
+            xAxis: {
+              disableGrid: true
+            },
+            yAxis: {
+              data: [{ min: 0 }]
+            },
+            extra: {
+              column: {
+                type: 'group',
+                width: 30,
+                activeBgColor: '#000000',
+                activeBgOpacity: 0.08
+              }
+            },
+            ...config,
+          };
+
+          chartRef.current = new uChartsClass(chartConfig);
+          console.log('[BaseChart] 图表初始化完成:', canvasId, {
+            cWidth, cHeight,
+            canvasWidth: canvas.width,
+            canvasHeight: canvas.height,
+            categoriesLength: categories.length,
+            seriesLength: series.length,
+            categories,
+            series,
+          });
+        } else {
+          console.error('[BaseChart] 未获取到 canvas node:', canvasId);
+        }
+      });
+    }, 500); // 延迟 500ms,等待 Canvas 尺寸渲染完成
+  }, []); // 空依赖数组:只在首次挂载时执行一次
 
 
   /**
   /**
-   * 触摸开始事件处理
+   * 触摸事件处理
    */
    */
   const handleTouchStart = (e: any) => {
   const handleTouchStart = (e: any) => {
+    if (chartRef.current) {
+      chartRef.current.touchLegend(e);
+      chartRef.current.showToolTip(e);
+    }
     onTouchStart?.(e as TouchEvent);
     onTouchStart?.(e as TouchEvent);
   };
   };
 
 
-  /**
-   * 触摸移动事件处理
-   */
   const handleTouchMove = (e: any) => {
   const handleTouchMove = (e: any) => {
+    if (chartRef.current) {
+      chartRef.current.scroll(e);
+    }
     onTouchMove?.(e as TouchEvent);
     onTouchMove?.(e as TouchEvent);
   };
   };
 
 
-  /**
-   * 触摸结束事件处理
-   */
   const handleTouchEnd = (e: any) => {
   const handleTouchEnd = (e: any) => {
+    if (chartRef.current) {
+      chartRef.current.touchLegend(e);
+      chartRef.current.showToolTip(e);
+    }
     onTouchEnd?.(e as TouchEvent);
     onTouchEnd?.(e as TouchEvent);
   };
   };
 
 
+  const canvasProps = { style: { width: cWidth, height: cHeight } };
+
   return (
   return (
     <Canvas
     <Canvas
-      canvasId={canvasId}
+      canvas-id={canvasId}
       id={canvasId}
       id={canvasId}
       {...canvasProps}
       {...canvasProps}
       onTouchStart={handleTouchStart}
       onTouchStart={handleTouchStart}
@@ -166,4 +194,55 @@ export const BaseChart: React.FC<BaseChartProps> = (props) => {
   );
   );
 };
 };
 
 
+/**
+ * BaseChart 组件
+ *
+ * 外层 Wrapper 组件,负责:
+ * - 检查数据是否准备好
+ * - 缓存 config 引用
+ * - 只有数据准备好后才挂载 Inner 组件
+ *
+ * 使用原始 u-charts.js + Canvas 2D API
+ * 参考 docs/小程序图表库示例/taro-2d柱状图使用示例.md
+ */
+export const BaseChart: React.FC<BaseChartProps> = (props) => {
+  const {
+    canvasId,
+    width,
+    height,
+    type,
+    categories = [],
+    series = [],
+    config = {},
+    onTouchStart,
+    onTouchMove,
+    onTouchEnd,
+  } = props;
+
+  // 缓存配置,避免每次渲染创建新对象
+  const stableConfig = useMemo(() => config, [JSON.stringify(config)]);
+
+  // 只有数据准备好才渲染 Inner 组件
+  const isReady = categories.length > 0 && series.length > 0;
+
+  if (!isReady) {
+    return null;
+  }
+
+  return (
+    <BaseChartInner
+      canvasId={canvasId}
+      width={width}
+      height={height}
+      type={type}
+      categories={categories}
+      series={series}
+      config={stableConfig}
+      onTouchStart={onTouchStart}
+      onTouchMove={onTouchMove}
+      onTouchEnd={onTouchEnd}
+    />
+  );
+};
+
 export default BaseChart;
 export default BaseChart;

+ 0 - 167
mini-ui-packages/mini-charts/src/components/BaseChartLegacy.tsx

@@ -1,167 +0,0 @@
-import React, { useEffect, useRef, useMemo } from 'react';
-import Taro from '@tarojs/taro';
-import { Canvas } from '@tarojs/components';
-// 导入原始的 u-charts.js
-// @ts-ignore
-import uCharts from '../lib/u-charts-original.js';
-import type { ChartsConfig, TouchEvent } from '../lib/charts/index';
-import type { ExtendedCanvasContext } from '../types';
-
-/**
- * BaseChartLegacy 组件的 Props 接口
- * 用于测试原始 u-charts.js (旧版 Canvas API)
- */
-export interface BaseChartLegacyProps {
-  /** Canvas 元素的 ID,必须唯一 */
-  canvasId: string;
-  /** 图表宽度(像素),默认为屏幕宽度 */
-  width?: number;
-  /** 图表高度(像素),默认根据宽高比计算 */
-  height?: number;
-  /** 设备像素比,默认根据环境自动设置 */
-  pixelRatio?: number;
-  /** 图表类型 */
-  type: ChartsConfig['type'];
-  /** X 轴分类数据 */
-  categories?: string[];
-  /** 系列数据 */
-  series?: ChartsConfig['series'];
-  /** 额外的图表配置 */
-  config?: Partial<ChartsConfig>;
-  /** 触摸开始事件 */
-  onTouchStart?: (e: TouchEvent) => void;
-  /** 触摸移动事件 */
-  onTouchMove?: (e: TouchEvent) => void;
-  /** 触摸结束事件 */
-  onTouchEnd?: (e: TouchEvent) => void;
-}
-
-/**
- * BaseChartLegacy 基础图表组件(测试版)
- *
- * 使用原始 u-charts.js 和旧版 Canvas API 进行测试
- * Canvas ID 需要加上 "-legacy" 后缀以避免与 Canvas 2D 冲突
- */
-export const BaseChartLegacy: React.FC<BaseChartLegacyProps> = (props) => {
-  const {
-    canvasId,
-    width,
-    height,
-    pixelRatio,
-    type,
-    categories = [],
-    series = [],
-    config = {},
-    onTouchStart,
-    onTouchMove,
-    onTouchEnd,
-  } = props;
-
-  const chartRef = useRef<any>(null);
-
-  /**
-   * 计算响应式尺寸和像素比
-   */
-  const { cWidth, cHeight, actualPixelRatio } = useMemo(() => {
-    const sysInfo = Taro.getSystemInfoSync();
-    // 旧版 Canvas API:width 和 height 都是逻辑像素
-    const pr = pixelRatio ?? sysInfo.pixelRatio;
-    const cw = width ?? sysInfo.windowWidth;
-    const ch = height ?? (500 / 750 * cw);
-    return { cWidth: cw, cHeight: ch, actualPixelRatio: pr };
-  }, [width, height, pixelRatio]);
-
-  /**
-   * Canvas props (旧版 Canvas API)
-   * 旧版 API 的 canvasId 不需要 type="2d"
-   */
-  const canvasProps = useMemo(() => ({
-    canvasId: canvasId + '-legacy',
-    id: canvasId + '-legacy',
-    style: { width: `${cWidth}px`, height: `${cHeight}px` }
-  }), [canvasId, cWidth, cHeight]);
-
-  /**
-   * 初始化图表实例
-   */
-  useEffect(() => {
-    const timer = setTimeout(() => {
-      // 使用旧版 Canvas API 创建上下文
-      const rawCtx = Taro.createCanvasContext(canvasId + '-legacy');
-
-      if (!rawCtx) {
-        console.error('[BaseChartLegacy] CanvasContext创建失败!')
-        return
-      }
-
-      // 旧版 Canvas API:直接使用 rawCtx
-      const ctx = rawCtx as any;
-
-      const chartConfig: ChartsConfig = {
-        type,
-        context: ctx,
-        categories,
-        series,
-        width: cWidth,
-        height: cHeight,
-        pixelRatio: actualPixelRatio,
-        ...config,
-      };
-
-      // @ts-ignore - 使用原始 u-charts 构造函数
-      chartRef.current = new uCharts(chartConfig);
-
-      console.log('[BaseChartLegacy] 图表初始化成功', {
-        canvasId: canvasId + '-legacy',
-        width: cWidth,
-        height: cHeight,
-        pixelRatio: actualPixelRatio,
-        type
-      });
-    }, 100)
-
-    return () => {
-      clearTimeout(timer)
-      chartRef.current = null;
-    };
-  }, [canvasId, type, categories, series, cWidth, cHeight, actualPixelRatio, config]);
-
-  /**
-   * 触摸事件处理
-   */
-  const handleTouchStart = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.touchLegend(e);
-      chartRef.current.touchToolTip(e);
-      chartRef.current.showToolTip(e);
-    }
-    onTouchStart?.(e as TouchEvent);
-  };
-
-  const handleTouchMove = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.touchToolTip(e);
-      chartRef.current.showToolTip(e);
-    }
-    onTouchMove?.(e as TouchEvent);
-  };
-
-  const handleTouchEnd = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.touchToolTip(e);
-      chartRef.current.showToolTip(e);
-    }
-    onTouchEnd?.(e as TouchEvent);
-  };
-
-  return (
-    <Canvas
-      {...canvasProps}
-      onTouchStart={handleTouchStart}
-      onTouchMove={handleTouchMove}
-      onTouchEnd={handleTouchEnd}
-    />
-  );
-};
-
-export default BaseChartLegacy;

+ 0 - 248
mini-ui-packages/mini-charts/src/components/BaseChartOriginal2D.tsx

@@ -1,248 +0,0 @@
-import React, { useState, useRef, useLayoutEffect, useMemo } from 'react';
-import Taro from '@tarojs/taro';
-import { Canvas } from '@tarojs/components';
-import uChartsClass from '../lib/u-charts-original.js';
-import type { ChartsConfig, TouchEvent } from '../lib/u-charts-original';
-import type { ExtendedCanvasContext } from '../types';
-
-/**
- * BaseChartOriginal2D 组件的 Props 接口
- * 使用原始 u-charts.js + Canvas 2D API
- */
-export interface BaseChartOriginal2DProps {
-  /** Canvas 元素的 ID,必须唯一 */
-  canvasId: string;
-  /** 图表宽度(像素),默认为 750 */
-  width?: number;
-  /** 图表高度(像素),默认为 500 */
-  height?: number;
-  /** 图表类型 */
-  type: ChartsConfig['type'];
-  /** X 轴分类数据 */
-  categories?: string[];
-  /** 系列数据 */
-  series?: ChartsConfig['series'];
-  /** 额外的图表配置 */
-  config?: Partial<ChartsConfig>;
-  /** 触摸开始事件 */
-  onTouchStart?: (e: TouchEvent) => void;
-  /** 触摸移动事件 */
-  onTouchMove?: (e: TouchEvent) => void;
-  /** 触摸结束事件 */
-  onTouchEnd?: (e: TouchEvent) => void;
-}
-
-/**
- * BaseChartOriginal2DInner 内部组件
- *
- * 实际的图表渲染组件,只在数据准备好后才会挂载
- * 使用空依赖数组确保只初始化一次
- */
-const BaseChartOriginal2DInner: React.FC<BaseChartOriginal2DProps> = (props) => {
-  const {
-    canvasId,
-    width = 750,
-    height = 500,
-    type,
-    categories = [],
-    series = [],
-    config = {},
-    onTouchStart,
-    onTouchMove,
-    onTouchEnd,
-  } = props;
-
-  const [cWidth, setCWidth] = useState(750);
-  const [cHeight, setCHeight] = useState(500);
-
-  const chartRef = useRef<any>(null);
-
-  /**
-   * 初始化图表实例
-   * 使用 Canvas 2D API + 原始 u-charts.js
-   * 参考 ColumnChartFCExample 的实现方式
-   *
-   * 注意:使用空依赖数组,只在组件首次挂载时执行一次
-   * 数据变化通过 Wrapper 组件控制重新挂载来实现
-   */
-  useLayoutEffect(() => {
-    console.debug('[BaseChartOriginal2D] useLayoutEffect 开始', { canvasId, width, height });
-
-    // 计算响应式尺寸
-    const sysInfo = Taro.getSystemInfoSync();
-    // 这里的第一个 750 对应 css .charts 的 width
-    const cw = width / 750 * sysInfo.windowWidth;
-    // 这里的 500 对应 css .charts 的 height
-    const ch = height / 750 * sysInfo.windowWidth;
-
-    setCWidth(cw);
-    setCHeight(ch);
-
-    // 确保数据已准备好:categories 和 series 都有数据
-    const isDataReady = categories.length > 0 && series.length > 0;
-
-    if (!isDataReady) {
-      console.log('[BaseChartOriginal2D] 数据未准备好,等待数据...', {
-        canvasId,
-        categoriesLength: categories.length,
-        seriesLength: series.length
-      });
-      return;
-    }
-
-    // 延迟初始化图表,等待 Canvas 尺寸渲染完成(参考 FC 示例)
-    setTimeout(() => {
-      // 使用 Canvas 2D API 的方式获取 context
-      const query = Taro.createSelectorQuery();
-      query.select('#' + canvasId).fields({ node: true, size: true }).exec((res) => {
-        if (res[0]) {
-          const canvas = res[0].node;
-          const ctx = canvas.getContext('2d');
-
-          console.debug('[BaseChartOriginal2D] canvas.width', canvas.width);
-          console.debug('[BaseChartOriginal2D] canvas.height', canvas.height);
-
-          // 将 Taro CanvasContext 转换为 uCharts 需要的 CanvasContext
-          const extendedCtx = ctx as ExtendedCanvasContext;
-
-          // Canvas 2D: 使用 canvas 的实际 width/height
-          const chartConfig: ChartsConfig = {
-            type,
-            context: extendedCtx,
-            categories,
-            series,
-            width: canvas.width,
-            height: canvas.height,
-            animation: true,
-            background: '#FFFFFF',
-            color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
-            padding: [15, 15, 0, 5],
-            enableScroll: false,
-            legend: {},
-            xAxis: {
-              disableGrid: true
-            },
-            yAxis: {
-              data: [{ min: 0 }]
-            },
-            extra: {
-              column: {
-                type: 'group',
-                width: 30,
-                activeBgColor: '#000000',
-                activeBgOpacity: 0.08
-              }
-            },
-            ...config,
-          };
-
-          chartRef.current = new uChartsClass(chartConfig);
-          console.log('[BaseChartOriginal2D] 图表初始化完成:', canvasId, {
-            cWidth, cHeight,
-            canvasWidth: canvas.width,
-            canvasHeight: canvas.height,
-            categoriesLength: categories.length,
-            seriesLength: series.length,
-            categories,
-            series,
-          });
-        } else {
-          console.error('[BaseChartOriginal2D] 未获取到 canvas node:', canvasId);
-        }
-      });
-    }, 500); // 延迟 500ms,等待 Canvas 尺寸渲染完成
-  }, []); // 空依赖数组:只在首次挂载时执行一次
-
-  /**
-   * 触摸事件处理
-   */
-  const handleTouchStart = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.touchLegend(e);
-      chartRef.current.showToolTip(e);
-    }
-    onTouchStart?.(e as TouchEvent);
-  };
-
-  const handleTouchMove = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.scroll(e);
-    }
-    onTouchMove?.(e as TouchEvent);
-  };
-
-  const handleTouchEnd = (e: any) => {
-    if (chartRef.current) {
-      chartRef.current.touchLegend(e);
-      chartRef.current.showToolTip(e);
-    }
-    onTouchEnd?.(e as TouchEvent);
-  };
-
-  const canvasProps = { style: { width: cWidth, height: cHeight } };
-
-  return (
-    <Canvas
-      canvas-id={canvasId}
-      id={canvasId}
-      {...canvasProps}
-      onTouchStart={handleTouchStart}
-      onTouchMove={handleTouchMove}
-      onTouchEnd={handleTouchEnd}
-      type="2d"
-    />
-  );
-};
-
-/**
- * BaseChartOriginal2D 组件
- *
- * 外层 Wrapper 组件,负责:
- * - 检查数据是否准备好
- * - 缓存 config 引用
- * - 只有数据准备好后才挂载 Inner 组件
- *
- * 使用原始 u-charts.js + Canvas 2D API
- * 参考 docs/小程序图表库示例/taro-2d柱状图使用示例.md
- */
-export const BaseChartOriginal2D: React.FC<BaseChartOriginal2DProps> = (props) => {
-  const {
-    canvasId,
-    width,
-    height,
-    type,
-    categories = [],
-    series = [],
-    config = {},
-    onTouchStart,
-    onTouchMove,
-    onTouchEnd,
-  } = props;
-
-  // 缓存配置,避免每次渲染创建新对象
-  const stableConfig = useMemo(() => config, [JSON.stringify(config)]);
-
-  // 只有数据准备好才渲染 Inner 组件
-  const isReady = categories.length > 0 && series.length > 0;
-
-  if (!isReady) {
-    return null;
-  }
-
-  return (
-    <BaseChartOriginal2DInner
-      canvasId={canvasId}
-      width={width}
-      height={height}
-      type={type}
-      categories={categories}
-      series={series}
-      config={stableConfig}
-      onTouchStart={onTouchStart}
-      onTouchMove={onTouchMove}
-      onTouchEnd={onTouchEnd}
-    />
-  );
-};
-
-export default BaseChartOriginal2D;

+ 0 - 155
mini-ui-packages/mini-charts/src/components/CandleChart.tsx

@@ -1,155 +0,0 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, ChartsConfig, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
-
-/**
- * K线图组件的 Props 接口
- */
-export interface CandleChartProps extends Omit<BaseChartProps, 'type'> {
-  /** 是否显示移动平均线 */
-  ma?: boolean;
-  /** MA5 移动平均线颜色 */
-  ma5Color?: string;
-  /** MA10 移动平均线颜色 */
-  ma10Color?: string;
-  /** MA30 移动平均线颜色 */
-  ma30Color?: string;
-  /** 是否启用滚动 */
-  enableScroll?: boolean;
-  /** X 轴配置 */
-  xAxis?: XAxisConfig;
-  /** Y 轴配置 */
-  yAxis?: YAxisConfig;
-  /** 图例是否显示 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** 额外K线图配置 */
-  extra?: ChartsConfig['extra'];
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
-}
-
-/**
- * CandleChart K线图组件
- *
- * 用于显示股票/加密货币等金融数据的K线图,支持移动平均线
- */
-export const CandleChart: React.FC<CandleChartProps> = (props) => {
-  const {
-    ma = true,
-    ma5Color = '#fe6500',
-    ma10Color = '#52a9ff',
-    ma30Color = '#4adef7',
-    enableScroll = true,
-    xAxis,
-    yAxis,
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    extra = {},
-    tooltipFormatter,
-    categories = [],
-    series = [],
-    config = {},
-    ...baseProps
-  } = props;
-
-  const chartRef = React.useRef<any>(null);
-
-  /**
-   * 默认配置
-   */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    return {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      xAxis: xAxis ?? { disableGrid: true },
-      yAxis: yAxis ?? { gridType: 'dash', dashLength: 2 },
-      extra: {
-        candle: {
-          color: {
-            upLine: '#f54954',
-            upFill: '#f54954',
-            downLine: '#18b878',
-            downFill: '#18b878'
-          },
-          ma: ma
-            ? [
-              { day: 5, color: ma5Color, name: 'MA5' },
-              { day: 10, color: ma10Color, name: 'MA10' },
-              { day: 30, color: ma30Color, name: 'MA30' }
-            ]
-            : false,
-          bar: true,
-          animation: animation
-        },
-        ...extra
-      }
-    };
-  }, [legend, fontSize, background, animation, xAxis, yAxis, ma, ma5Color, ma10Color, ma30Color, extra]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current) {
-      chartRef.current.scrollStart(e);
-      if (tooltipFormatter) {
-        chartRef.current.showToolTip(e, {
-          formatter: tooltipFormatter
-        });
-      } else {
-        chartRef.current.showToolTip(e, {
-          formatter: (item: any, category: string) => {
-            return category + ' ' + item.name + ':' + item.data;
-          }
-        });
-      }
-    }
-    baseProps.onTouchStart?.(e);
-  };
-
-  /**
-   * 滚动事件处理
-   */
-  const handleTouchMove = (e: TouchEvent) => {
-    if (chartRef.current && enableScroll) {
-      chartRef.current.scroll(e);
-    }
-    baseProps.onTouchMove?.(e);
-  };
-
-  /**
-   * 滚动结束事件处理
-   */
-  const handleTouchEnd = (e: TouchEvent) => {
-    if (chartRef.current && enableScroll) {
-      chartRef.current.scrollEnd(e);
-    }
-    baseProps.onTouchEnd?.(e);
-  };
-
-  return (
-    <BaseChart
-      {...baseProps}
-      categories={categories}
-      series={series}
-      type="candle"
-      config={{ ...defaultConfig, ...config }}
-      onTouchStart={handleTouchStart}
-      onTouchMove={handleTouchMove}
-      onTouchEnd={handleTouchEnd}
-    />
-  );
-};
-
-export default CandleChart;

+ 54 - 87
mini-ui-packages/mini-charts/src/components/ColumnChart.tsx

@@ -1,113 +1,80 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
+import React from 'react';
+import { BaseChart } from './BaseChart';
+import type { ChartsConfig } from '../lib/u-charts-original';
 
 
 /**
 /**
- * 柱状图类型
+ * ColumnChart 组件的 Props 接口
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
-export type ColumnType = 'group' | 'stack';
-
-/**
- * 柱状图组件的 Props 接口
- */
-export interface ColumnChartProps extends Omit<BaseChartProps, 'type'> {
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 柱状图类型 */
-  columnType?: ColumnType;
-  /** X 轴配置 */
-  xAxis?: XAxisConfig;
-  /** Y 轴配置 */
-  yAxis?: YAxisConfig;
-  /** 图例是否显示 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
+export interface ColumnChartProps {
+  /** Canvas 元素的 ID,必须唯一 */
+  canvasId: string;
+  /** 图表宽度(像素) */
+  width?: number;
+  /** 图表高度(像素) */
+  height?: number;
+  /** X 轴分类数据 */
+  categories: string[];
+  /** 系列数据 */
+  series: ChartsConfig['series'];
+  /** 额外的图表配置 */
+  config?: Partial<ChartsConfig>;
 }
 }
 
 
 /**
 /**
  * ColumnChart 柱状图组件
  * ColumnChart 柱状图组件
  *
  *
- * 用于显示分类数据的柱状图,支持分组和堆叠模式
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
 export const ColumnChart: React.FC<ColumnChartProps> = (props) => {
 export const ColumnChart: React.FC<ColumnChartProps> = (props) => {
   const {
   const {
-    dataLabel = true,
-    columnType = 'group',
-    xAxis,
-    yAxis,
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    tooltipFormatter,
-    categories = [],
-    series = [],
+    canvasId,
+    width,
+    height,
+    categories,
+    series,
     config = {},
     config = {},
-    ...baseProps
   } = props;
   } = props;
 
 
-  const chartRef = React.useRef<any>(null);
-
   /**
   /**
-   * 默认配置
+   * 合并默认配置
    */
    */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    const result = {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      xAxis: xAxis ?? { disableGrid: true },
-      yAxis: yAxis ?? {},
-      extra: {
-        column: {
-          type: columnType,
-          width: columnType === 'group'
-            ? (baseProps.width ? baseProps.width * 0.45 / (categories.length || 1) : 20)
-            : undefined
-        }
+  const mergedConfig: Partial<ChartsConfig> = {
+    animation: true,
+    background: '#FFFFFF',
+    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+    padding: [15, 15, 0, 5],
+    enableScroll: false,
+    legend: {},
+    xAxis: {
+      disableGrid: true,
+      ...config.xAxis,
+    },
+    yAxis: {
+      data: [{ min: 0 }],
+      ...config.yAxis,
+    },
+    extra: {
+      column: {
+        type: 'group',
+        width: 30,
+        activeBgColor: '#000000',
+        activeBgOpacity: 0.08,
+        ...config.extra?.column,
       }
       }
-    };
-    return result
-  }, [legend, fontSize, background, animation, dataLabel, xAxis, yAxis, columnType, categories.length, baseProps.width]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current && tooltipFormatter) {
-      chartRef.current.showToolTip(e, {
-        formatter: tooltipFormatter
-      });
-    } else if (chartRef.current) {
-      chartRef.current.showToolTip(e, {
-        formatter: (item: any, category: string) => {
-          return category + ' ' + item.name + ':' + item.data;
-        }
-      });
-    }
-    baseProps.onTouchStart?.(e);
+    },
+    ...config,
   };
   };
 
 
-  const finalConfig = { ...defaultConfig, ...config }
-
   return (
   return (
     <BaseChart
     <BaseChart
-      {...baseProps}
+      canvasId={canvasId}
+      width={width}
+      height={height}
+      type="column"
       categories={categories}
       categories={categories}
       series={series}
       series={series}
-      type="column"
-      config={finalConfig}
-      onTouchStart={handleTouchStart}
+      config={mergedConfig}
     />
     />
   );
   );
 };
 };

+ 0 - 115
mini-ui-packages/mini-charts/src/components/ColumnChartLegacy.tsx

@@ -1,115 +0,0 @@
-import React, { useMemo } from 'react';
-import { BaseChartLegacy, BaseChartLegacyProps } from './BaseChartLegacy';
-import type { TouchEvent, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
-
-/**
- * 柱状图类型
- */
-export type ColumnType = 'group' | 'stack';
-
-/**
- * 柱状图组件的 Props 接口(测试版)
- */
-export interface ColumnChartLegacyProps extends Omit<BaseChartLegacyProps, 'type'> {
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 柱状图类型 */
-  columnType?: ColumnType;
-  /** X 轴配置 */
-  xAxis?: XAxisConfig;
-  /** Y 轴配置 */
-  yAxis?: YAxisConfig;
-  /** 图例是否显示 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
-}
-
-/**
- * ColumnChartLegacy 柱状图组件(测试版)
- *
- * 使用原始 u-charts.js 和旧版 Canvas API 进行测试
- */
-export const ColumnChartLegacy: React.FC<ColumnChartLegacyProps> = (props) => {
-  const {
-    dataLabel = true,
-    columnType = 'group',
-    xAxis,
-    yAxis,
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    tooltipFormatter,
-    categories = [],
-    series = [],
-    config = {},
-    ...baseProps
-  } = props;
-
-  const chartRef = React.useRef<any>(null);
-
-  /**
-   * 默认配置
-   */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    const result = {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      xAxis: xAxis ?? { disableGrid: true },
-      yAxis: yAxis ?? {},
-      extra: {
-        column: {
-          type: columnType,
-          width: columnType === 'group'
-            ? (baseProps.width ? baseProps.width * 0.45 / (categories.length || 1) : 20)
-            : undefined
-        }
-      }
-    };
-    return result
-  }, [legend, fontSize, background, animation, dataLabel, xAxis, yAxis, columnType, categories.length, baseProps.width]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current && tooltipFormatter) {
-      chartRef.current.showToolTip(e, {
-        formatter: tooltipFormatter
-      });
-    } else if (chartRef.current) {
-      chartRef.current.showToolTip(e, {
-        formatter: (item: any, category: string) => {
-          return category + ' ' + item.name + ':' + item.data;
-        }
-      });
-    }
-    baseProps.onTouchStart?.(e);
-  };
-
-  const finalConfig = { ...defaultConfig, ...config }
-
-  return (
-    <BaseChartLegacy
-      {...baseProps}
-      categories={categories}
-      series={series}
-      type="column"
-      config={finalConfig}
-      onTouchStart={handleTouchStart}
-    />
-  );
-};
-
-export default ColumnChartLegacy;

+ 0 - 86
mini-ui-packages/mini-charts/src/components/ColumnChartOriginal2D.tsx

@@ -1,86 +0,0 @@
-import React from 'react';
-import { BaseChartOriginal2D } from './BaseChartOriginal2D';
-import type { ChartsConfig } from '../lib/u-charts-original';
-
-/**
- * ColumnChartOriginal2D 组件的 Props 接口
- * 使用原始 u-charts.js + Canvas 2D API
- */
-export interface ColumnChartOriginal2DProps {
-  /** Canvas 元素的 ID,必须唯一 */
-  canvasId: string;
-  /** 图表宽度(像素) */
-  width?: number;
-  /** 图表高度(像素) */
-  height?: number;
-  /** X 轴分类数据 */
-  categories: string[];
-  /** 系列数据 */
-  series: ChartsConfig['series'];
-  /** 额外的图表配置 */
-  config?: Partial<ChartsConfig>;
-  /** Tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
-}
-
-/**
- * ColumnChartOriginal2D 柱状图组件
- *
- * 使用原始 u-charts.js + Canvas 2D API
- * 用于测试对比 Legacy 版本和当前模块化版本
- */
-export const ColumnChartOriginal2D: React.FC<ColumnChartOriginal2DProps> = (props) => {
-  const {
-    canvasId,
-    width,
-    height,
-    categories,
-    series,
-    config = {},
-    tooltipFormatter,
-  } = props;
-
-  /**
-   * 合并默认配置
-   */
-  const mergedConfig: Partial<ChartsConfig> = {
-    animation: true,
-    background: '#FFFFFF',
-    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
-    padding: [15, 15, 0, 5],
-    enableScroll: false,
-    legend: {},
-    xAxis: {
-      disableGrid: true,
-      ...config.xAxis,
-    },
-    yAxis: {
-      data: [{ min: 0 }],
-      ...config.yAxis,
-    },
-    extra: {
-      column: {
-        type: 'group',
-        width: 30,
-        activeBgColor: '#000000',
-        activeBgOpacity: 0.08,
-        ...config.extra?.column,
-      }
-    },
-    ...config,
-  };
-
-  return (
-    <BaseChartOriginal2D
-      canvasId={canvasId}
-      width={width}
-      height={height}
-      type="column"
-      categories={categories}
-      series={series}
-      config={mergedConfig}
-    />
-  );
-};
-
-export default ColumnChartOriginal2D;

+ 56 - 116
mini-ui-packages/mini-charts/src/components/LineChart.tsx

@@ -1,6 +1,6 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, ChartsConfig, LegendConfig, XAxisConfig, YAxisConfig } from '../lib/charts/index';
+import React from 'react';
+import { BaseChart } from './BaseChart';
+import type { ChartsConfig } from '../lib/u-charts-original';
 
 
 /**
 /**
  * 数据点形状
  * 数据点形状
@@ -8,139 +8,79 @@ import type { TouchEvent, ChartsConfig, LegendConfig, XAxisConfig, YAxisConfig }
 export type DataPointShape = 'circle' | 'rect' | 'triangle' | 'diamond';
 export type DataPointShape = 'circle' | 'rect' | 'triangle' | 'diamond';
 
 
 /**
 /**
- * 折线图组件的 Props 接口
+ * LineChart 组件的 Props 接口
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
-export interface LineChartProps extends Omit<BaseChartProps, 'type'> {
-  /** 是否显示数据点 */
-  dataPointShape?: DataPointShape | boolean;
-  /** 数据点大小 */
-  dataPointRadius?: number;
-  /** 是否启用滚动 */
-  enableScroll?: boolean;
-  /** X 轴配置 */
-  xAxis?: XAxisConfig;
-  /** Y 轴配置 */
-  yAxis?: YAxisConfig;
-  /** 图例是否显示 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 额外折线图配置 */
-  extra?: ChartsConfig['extra'];
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
+export interface LineChartProps {
+  /** Canvas 元素的 ID,必须唯一 */
+  canvasId: string;
+  /** 图表宽度(像素) */
+  width?: number;
+  /** 图表高度(像素) */
+  height?: number;
+  /** X 轴分类数据 */
+  categories: string[];
+  /** 系列数据 */
+  series: ChartsConfig['series'];
+  /** 额外的图表配置 */
+  config?: Partial<ChartsConfig>;
 }
 }
 
 
 /**
 /**
  * LineChart 折线图组件
  * LineChart 折线图组件
  *
  *
- * 用于显示趋势数据的折线图,支持数据点形状、滚动和缩放
+ * 使用原始 u-charts.js + Canvas 2D API
+ * 用于显示趋势数据的折线图
  */
  */
 export const LineChart: React.FC<LineChartProps> = (props) => {
 export const LineChart: React.FC<LineChartProps> = (props) => {
   const {
   const {
-    dataPointShape = true,
-    dataPointRadius = 4,
-    enableScroll = false,
-    xAxis,
-    yAxis,
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    dataLabel = false,
-    extra = {},
-    tooltipFormatter,
-    categories = [],
-    series = [],
+    canvasId,
+    width,
+    height,
+    categories,
+    series,
     config = {},
     config = {},
-    ...baseProps
   } = props;
   } = props;
 
 
-  const chartRef = React.useRef<any>(null);
-
-  /**
-   * 默认配置
-   */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    return {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      dataPointShape: typeof dataPointShape === 'boolean' ? (dataPointShape ? 'circle' : false) : dataPointShape,
-      dataPointRadius,
-      enableScroll,
-      xAxis: xAxis ?? { disableGrid: false },
-      yAxis: yAxis ?? {},
-      extra: {
-        line: {
-          type: 'curve',
-          width: 2
-        },
-        ...extra
-      }
-    };
-  }, [legend, fontSize, background, animation, dataLabel, dataPointShape, dataPointRadius, enableScroll, xAxis, yAxis, extra]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current) {
-      chartRef.current.scrollStart(e);
-      if (tooltipFormatter) {
-        chartRef.current.showToolTip(e, {
-          formatter: tooltipFormatter
-        });
-      } else {
-        chartRef.current.showToolTip(e, {
-          formatter: (item: any, category: string) => {
-            return category + ' ' + item.name + ':' + item.data;
-          }
-        });
-      }
-    }
-    baseProps.onTouchStart?.(e);
-  };
-
   /**
   /**
-   * 滚动事件处理
+   * 合并默认配置
    */
    */
-  const handleTouchMove = (e: TouchEvent) => {
-    if (chartRef.current && enableScroll) {
-      chartRef.current.scroll(e);
-    }
-    baseProps.onTouchMove?.(e);
-  };
-
-  /**
-   * 滚动结束事件处理
-   */
-  const handleTouchEnd = (e: TouchEvent) => {
-    if (chartRef.current && enableScroll) {
-      chartRef.current.scrollEnd(e);
-    }
-    baseProps.onTouchEnd?.(e);
+  const mergedConfig: Partial<ChartsConfig> = {
+    animation: true,
+    background: '#FFFFFF',
+    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+    padding: [15, 15, 0, 5],
+    enableScroll: false,
+    legend: {},
+    xAxis: {
+      disableGrid: false,
+      ...config.xAxis,
+    },
+    yAxis: {
+      data: [{ min: 0 }],
+      ...config.yAxis,
+    },
+    extra: {
+      line: {
+        type: 'curve',
+        width: 2,
+        activeType: 'hollow',
+        ...config.extra?.line,
+      },
+      ...config.extra,
+    },
+    ...config,
   };
   };
 
 
   return (
   return (
     <BaseChart
     <BaseChart
-      {...baseProps}
+      canvasId={canvasId}
+      width={width}
+      height={height}
+      type="line"
       categories={categories}
       categories={categories}
       series={series}
       series={series}
-      type="line"
-      config={{ ...defaultConfig, ...config }}
-      onTouchStart={handleTouchStart}
-      onTouchMove={handleTouchMove}
-      onTouchEnd={handleTouchEnd}
+      config={mergedConfig}
     />
     />
   );
   );
 };
 };

+ 47 - 78
mini-ui-packages/mini-charts/src/components/PieChart.tsx

@@ -1,6 +1,6 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, ChartsConfig, LegendConfig } from '../lib/charts/index';
+import React from 'react';
+import { BaseChart } from './BaseChart';
+import type { ChartsConfig } from '../lib/u-charts-original';
 
 
 /**
 /**
  * 饼图类型
  * 饼图类型
@@ -8,104 +8,73 @@ import type { TouchEvent, ChartsConfig, LegendConfig } from '../lib/charts/index
 export type PieChartType = 'pie' | 'ring';
 export type PieChartType = 'pie' | 'ring';
 
 
 /**
 /**
- * 饼图组件的 Props 接口
+ * PieChart 组件的 Props 接口
+ * 使用原始 u-charts.js + Canvas 2D API
  */
  */
-export interface PieChartProps extends Omit<BaseChartProps, 'type' | 'categories'> {
+export interface PieChartProps {
+  /** Canvas 元素的 ID,必须唯一 */
+  canvasId: string;
+  /** 图表宽度(像素) */
+  width?: number;
+  /** 图表高度(像素) */
+  height?: number;
   /** 饼图类型 */
   /** 饼图类型 */
   pieType?: PieChartType;
   pieType?: PieChartType;
-  /** 是否显示图例 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 环形图内径比例 (0-1) */
-  ringWidth?: number;
-  /** 额外饼图配置 */
-  extra?: ChartsConfig['extra'];
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any) => string;
+  /** 系列数据 */
+  series: ChartsConfig['series'];
+  /** 额外的图表配置 */
+  config?: Partial<ChartsConfig>;
 }
 }
 
 
 /**
 /**
  * PieChart 饼图组件
  * PieChart 饼图组件
  *
  *
+ * 使用原始 u-charts.js + Canvas 2D API
  * 用于显示占比数据的饼图,支持普通饼图和环形图
  * 用于显示占比数据的饼图,支持普通饼图和环形图
  */
  */
 export const PieChart: React.FC<PieChartProps> = (props) => {
 export const PieChart: React.FC<PieChartProps> = (props) => {
   const {
   const {
+    canvasId,
+    width,
+    height,
     pieType = 'pie',
     pieType = 'pie',
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    dataLabel = true,
-    ringWidth = 0.6,
-    extra = {},
-    tooltipFormatter,
-    series = [],
+    series,
     config = {},
     config = {},
-    ...baseProps
   } = props;
   } = props;
 
 
-  const chartRef = React.useRef<any>(null);
-
-  /**
-   * 默认配置
-   */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    return {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      extra: {
-        pie: {
-          activeOpacity: 0.5,
-          activeRadius: 10,
-          offsetAngle: 0,
-          ringWidth: pieType === 'ring' ? ringWidth : 0,
-          labelWidth: 15,
-          ringWidthRatio: pieType === 'ring' ? ringWidth : 0
-        },
-        ...extra
-      }
-    };
-  }, [legend, fontSize, background, animation, dataLabel, pieType, ringWidth, extra]);
-
   /**
   /**
-   * tooltip 事件处理
+   * 合并默认配置
    */
    */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current) {
-      if (tooltipFormatter) {
-        chartRef.current.showToolTip(e, {
-          formatter: tooltipFormatter
-        });
-      } else {
-        chartRef.current.showToolTip(e, {
-          formatter: (item: any) => {
-            return item.name + ':' + item.data;
-          }
-        });
-      }
-    }
-    baseProps.onTouchStart?.(e);
+  const mergedConfig: Partial<ChartsConfig> = {
+    animation: true,
+    background: '#FFFFFF',
+    color: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ef4444'],
+    padding: [15, 15, 0, 5],
+    enableScroll: false,
+    legend: {},
+    extra: {
+      pie: {
+        activeOpacity: 0.5,
+        activeRadius: 10,
+        offsetAngle: 0,
+        ringWidth: pieType === 'ring' ? 0.6 : 0,
+        labelWidth: 15,
+        ringWidthRatio: pieType === 'ring' ? 0.6 : 0,
+        ...config.extra?.pie,
+      },
+      ...config.extra,
+    },
+    ...config,
   };
   };
 
 
   return (
   return (
     <BaseChart
     <BaseChart
-      {...baseProps}
-      series={series}
+      canvasId={canvasId}
+      width={width}
+      height={height}
       type={pieType}
       type={pieType}
-      config={{ ...defaultConfig, ...config }}
-      onTouchStart={handleTouchStart}
+      series={series}
+      config={mergedConfig}
     />
     />
   );
   );
 };
 };

+ 0 - 108
mini-ui-packages/mini-charts/src/components/RadarChart.tsx

@@ -1,108 +0,0 @@
-import React, { useMemo } from 'react';
-import { BaseChart, BaseChartProps } from './BaseChart';
-import type { TouchEvent, ChartsConfig, LegendConfig } from '../lib/charts/index';
-
-/**
- * 雷达图组件的 Props 接口
- */
-export interface RadarChartProps extends Omit<BaseChartProps, 'type'> {
-  /** 是否显示图例 */
-  legend?: boolean;
-  /** 字体大小 */
-  fontSize?: number;
-  /** 背景颜色 */
-  background?: string;
-  /** 是否开启动画 */
-  animation?: boolean;
-  /** 是否显示数据标签 */
-  dataLabel?: boolean;
-  /** 雷达图轴线颜色 */
-  axisColor?: string;
-  /** 雷达图区域透明度 */
-  areaOpacity?: number;
-  /** 额外雷达图配置 */
-  extra?: ChartsConfig['extra'];
-  /** tooltip 格式化函数 */
-  tooltipFormatter?: (item: any, category: string) => string;
-}
-
-/**
- * RadarChart 雷达图组件
- *
- * 用于显示多维数据对比的雷达图
- */
-export const RadarChart: React.FC<RadarChartProps> = (props) => {
-  const {
-    legend = true,
-    fontSize = 11,
-    background = '#FFFFFF',
-    animation = true,
-    dataLabel = false,
-    axisColor = '#cccccc',
-    areaOpacity = 0.5,
-    extra = {},
-    tooltipFormatter,
-    categories = [],
-    series = [],
-    config = {},
-    ...baseProps
-  } = props;
-
-  const chartRef = React.useRef<any>(null);
-
-  /**
-   * 默认配置
-   */
-  const defaultConfig = useMemo(() => {
-    const legendConfig: LegendConfig = legend ? { show: true } : { show: false };
-    return {
-      legend: legendConfig,
-      fontSize,
-      background,
-      animation,
-      dataLabel,
-      extra: {
-        radar: {
-          gridColor: axisColor,
-          axisColor,
-          opacity: areaOpacity,
-          max: 100
-        },
-        ...extra
-      }
-    };
-  }, [legend, fontSize, background, animation, dataLabel, axisColor, areaOpacity, extra]);
-
-  /**
-   * tooltip 事件处理
-   */
-  const handleTouchStart = (e: TouchEvent) => {
-    if (chartRef.current) {
-      if (tooltipFormatter) {
-        chartRef.current.showToolTip(e, {
-          formatter: tooltipFormatter
-        });
-      } else {
-        chartRef.current.showToolTip(e, {
-          formatter: (item: any, category: string) => {
-            return category + ' ' + item.name + ':' + item.data;
-          }
-        });
-      }
-    }
-    baseProps.onTouchStart?.(e);
-  };
-
-  return (
-    <BaseChart
-      {...baseProps}
-      categories={categories}
-      series={series}
-      type="radar"
-      config={{ ...defaultConfig, ...config }}
-      onTouchStart={handleTouchStart}
-    />
-  );
-};
-
-export default RadarChart;

+ 8 - 97
mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx

@@ -4,11 +4,8 @@ import { useQuery } from '@tanstack/react-query'
 import { YongrenTabBarLayout } from '@d8d/yongren-shared-ui/components/YongrenTabBarLayout'
 import { YongrenTabBarLayout } from '@d8d/yongren-shared-ui/components/YongrenTabBarLayout'
 import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
 import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
 import { ColumnChart } from '@d8d/mini-charts/components/ColumnChart'
 import { ColumnChart } from '@d8d/mini-charts/components/ColumnChart'
-import { ColumnChartOriginal2D } from '@d8d/mini-charts/components/ColumnChartOriginal2D'
-import { ColumnChartLegacy } from '@d8d/mini-charts/components/ColumnChartLegacy'
-import { ColumnChartFCExample } from '@d8d/mini-charts/components/ColumnChartFCExample'
-import { PieChart } from '@d8d/mini-charts/components/PieChart'
 import { BarChart } from '@d8d/mini-charts/components/BarChart'
 import { BarChart } from '@d8d/mini-charts/components/BarChart'
+import { PieChart } from '@d8d/mini-charts/components/PieChart'
 import { enterpriseStatisticsClient } from '../../api/enterpriseStatisticsClient'
 import { enterpriseStatisticsClient } from '../../api/enterpriseStatisticsClient'
 import type {
 import type {
   DisabilityTypeDistributionResponse,
   DisabilityTypeDistributionResponse,
@@ -253,48 +250,9 @@ const Statistics: React.FC<StatisticsProps> = () => {
           </View>
           </View>
         </View>
         </View>
 
 
-        {/* 残疾类型分布 - 当前版本(Canvas 2D + 模块化TS) */}
-        {false && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700">残疾类型分布 (Canvas 2D + 模块化TS)</Text>
-          {isLoadingDisability ? (
-            <Text className="text-gray-500 text-center py-4">加载中...</Text>
-          ) : (
-            (() => {
-              const stats = getStats(disabilityData)
-              if (stats.length > 0) {
-                const chartData = convertToColumnData(stats)
-                return (
-                  <View className="mt-3">
-                    <ColumnChart
-                      canvasId="disability-type-chart"
-                      width={650}
-                      height={200}
-                      categories={chartData.categories}
-                      series={chartData.series}
-                      config={{
-                        color: ['#3b82f6'],
-                        fontSize: 10,
-                        dataLabel: true,
-                        xAxis: { disableGrid: true },
-                        yAxis: {}
-                      }}
-                      tooltipFormatter={(item: any, category: string) => {
-                        const statItem = stats.find(s => s.key === category)
-                        return `${category} ${item.data}人 (${statItem?.percentage || 0}%)`
-                      }}
-                    />
-                  </View>
-                )
-              } else {
-                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
-              }
-            })()
-          )}
-        </View>)}
-
-        {/* 残疾类型分布 - Original2D版本(Canvas 2D + 原始JS) */}
-        {true && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700">残疾类型分布 (Canvas 2D + 原始JS)</Text>
+        {/* 残疾类型分布 */}
+        <View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
+          <Text className="font-semibold text-gray-700">残疾类型分布</Text>
           {isLoadingDisability ? (
           {isLoadingDisability ? (
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
             <Text className="text-gray-500 text-center py-4">加载中...</Text>
           ) : (() => {
           ) : (() => {
@@ -303,8 +261,8 @@ const Statistics: React.FC<StatisticsProps> = () => {
               const chartData = convertToColumnData(stats)
               const chartData = convertToColumnData(stats)
               return (
               return (
                 <View className="mt-3">
                 <View className="mt-3">
-                  <ColumnChartOriginal2D
-                    canvasId="disability-type-chart-orig2d"
+                  <ColumnChart
+                    canvasId="disability-type-chart"
                     width={650}
                     width={650}
                     height={300}
                     height={300}
                     categories={chartData.categories}
                     categories={chartData.categories}
@@ -317,42 +275,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
               return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
               return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
             }
             }
           })()}
           })()}
-        </View>)}
-
-        {/* 残疾类型分布 - Legacy版本(旧Canvas API + 原始JS) */}
-        {false && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700">残疾类型分布 (旧Canvas API + 原始JS)</Text>
-          {isLoadingDisability ? (
-            <Text className="text-gray-500 text-center py-4">加载中...</Text>
-          ) : (
-            (() => {
-              const stats = getStats(disabilityData)
-              if (stats.length > 0) {
-                const chartData = convertToColumnData(stats)
-                return (
-                  <View className="mt-3">
-                    <ColumnChartLegacy
-                      canvasId="disability-type-chart-legacy"
-                      width={650}
-                      height={200}
-                      categories={chartData.categories}
-                      series={chartData.series}
-                      config={{
-                        color: ['#3b82f6'],
-                        fontSize: 10,
-                        dataLabel: true,
-                        xAxis: { disableGrid: true },
-                        yAxis: {}
-                      }}
-                    />
-                  </View>
-                )
-              } else {
-                return <Text className="text-gray-500 text-center py-4 mt-3">暂无数据</Text>
-              }
-            })()
-          )}
-        </View>)}
+        </View>
 
 
         {/* 性别分布 */}
         {/* 性别分布 */}
         {false && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
         {false && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
@@ -363,7 +286,7 @@ const Statistics: React.FC<StatisticsProps> = () => {
               const genderStats = getStats(genderData)
               const genderStats = getStats(genderData)
               return genderStats.length > 0 ? (
               return genderStats.length > 0 ? (
                 <View className="mt-3">
                 <View className="mt-3">
-                  <ColumnChartLegacy
+                  <ColumnChart
                     canvasId="gender-chart"
                     canvasId="gender-chart"
                     width={650}
                     width={650}
                     height={200}
                     height={200}
@@ -533,18 +456,6 @@ const Statistics: React.FC<StatisticsProps> = () => {
             })()}
             })()}
         </View>}
         </View>}
 
 
-        {/* ==================== FC 示例组件(对比调试用) ==================== */}
-        {/* FC 示例 - 基于文档的原始实现 */}
-        {true && (<View className="card bg-white p-4 mb-4 rounded-lg shadow-sm flex flex-col">
-          <Text className="font-semibold text-gray-700">FC 示例(文档原始实现 - 对比调试)</Text>
-          <View className="mt-3">
-            <ColumnChartFCExample
-              canvasId="fc-example-chart"
-              width={650}
-              height={300}
-            />
-          </View>
-        </View>)}
       </ScrollView>
       </ScrollView>
     </YongrenTabBarLayout>
     </YongrenTabBarLayout>
   )
   )