Przeglądaj źródła

✨ feat(charts): 新增基于文档的FC示例组件

- 新增 `ColumnChartFCExample` 组件,作为基于文档示例的原始实现
- 在 `package.json` 中为新增组件添加导出路径映射
- 在 `Statistics` 页面添加新组件的示例区块,用于对比调试
- 新增文档文件 `docs/小程序图表库示例/taro-2d柱状图FC使用示例.md`,包含原始示例代码
yourname 2 tygodni temu
rodzic
commit
f164cec4e2

+ 136 - 0
docs/小程序图表库示例/taro-2d柱状图FC使用示例.md

@@ -0,0 +1,136 @@
+```tsx
+//index.js
+import React, { useState, useRef, useLayoutEffect } from 'react';
+import Taro, { useReady } from '@tarojs/taro';
+import { View, Canvas } from '@tarojs/components';
+import uCharts from '../lib/u-charts-original';
+// import './index.scss';
+
+interface ColumnChartProps {
+  // 可以添加 props 定义
+}
+
+function ColumnChartComponent(_props: ColumnChartProps) {
+  const [cWidth, setCWidth] = useState(750);
+  const [cHeight, setCHeight] = useState(500);
+  const [pixelRatio, setPixelRatio] = useState(1);
+
+  // 使用 ref 存储图表实例
+  const uChartsInstanceRef = useRef<Record<string, any>>({});
+
+  const drawCharts = (id: string, data: any) => {
+    const query = Taro.createSelectorQuery();
+    query.select('#' + id).fields({ node: true, size: true }).exec(res => {
+      if (res[0]) {
+        const canvas = res[0].node;
+        const ctx = canvas.getContext('2d');
+        const chart = new uCharts({
+          type: "column",
+          context: ctx,
+          width: canvas.width,
+          height: canvas.height,
+          categories: data.categories,
+          series: data.series,
+          // pixelRatio: pixelRatio,
+          animation: true,
+          background: "#FFFFFF",
+          color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
+          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
+            }
+          }
+        });
+        uChartsInstanceRef.current[id] = chart;
+      } else {
+        console.error("[uCharts]: 未获取到 context");
+      }
+    });
+  }
+
+  const getServerData = () => {
+    //模拟从服务器获取数据时的延时
+    setTimeout(() => {
+      //模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+      let res = {
+        categories: ["2018", "2019", "2020", "2021", "2022", "2023"],
+        series: [
+          {
+            name: "目标值",
+            data: [35, 36, 31, 33, 13, 34]
+          },
+          {
+            name: "完成量",
+            data: [18, 27, 21, 24, 6, 28]
+          }
+        ]
+      };
+      drawCharts('vTsUbNQurVfZNRMaupTQjygMuEHwuTNT', res);
+    }, 500);
+  }
+
+  const tap = (e: any) => {
+    uChartsInstanceRef.current[e.target.id]?.touchLegend(e);
+    uChartsInstanceRef.current[e.target.id]?.showToolTip(e);
+  }
+
+  useLayoutEffect(() => {
+    console.debug('useReady')
+    const sysInfo = Taro.getSystemInfoSync();
+    // console.debug('sysInfo', sysInfo)
+    const pr = sysInfo.pixelRatio;
+    //这里的第一个 750 对应 css .charts 的 width
+    const cw = 750 / 750 * sysInfo.windowWidth;
+    //这里的 500 对应 css .charts 的 height
+    const ch = 500 / 750 * sysInfo.windowWidth;
+    setCWidth(cw);
+    setCHeight(ch);
+    setPixelRatio(pr);
+
+    // 直接在这里获取数据
+    getServerData();
+  });
+
+  const canvasProps = { style: { width: cWidth, height: cHeight } };
+  return (
+    <View>
+      <Canvas
+        {...canvasProps}
+        canvas-id="vTsUbNQurVfZNRMaupTQjygMuEHwuTNT"
+        id="vTsUbNQurVfZNRMaupTQjygMuEHwuTNT"
+        type="2d"
+        // className="charts"
+        onTouchEnd={tap}
+      />
+    </View>
+  );
+}
+
+// 默认导出
+export default ColumnChartComponent;
+
+// 命名导出,保持向后兼容
+export const ColumnChartOriginal2D = ColumnChartComponent;
+
+// /*index.scss*/
+// .charts{
+//   width: 750rpx;
+//   height: 500rpx;
+// }
+```

+ 5 - 0
mini-ui-packages/mini-charts/package.json

@@ -65,6 +65,11 @@
       "types": "./dist/src/components/ColumnChartOriginal2D.d.ts",
       "import": "./dist/src/components/ColumnChartOriginal2D.js",
       "require": "./dist/src/components/ColumnChartOriginal2D.js"
+    },
+    "./components/ColumnChartFCExample": {
+      "types": "./dist/src/components/ColumnChartFCExample.d.ts",
+      "import": "./dist/src/components/ColumnChartFCExample.js",
+      "require": "./dist/src/components/ColumnChartFCExample.js"
     }
   },
   "scripts": {

+ 141 - 0
mini-ui-packages/mini-charts/src/components/ColumnChartFCExample.tsx

@@ -0,0 +1,141 @@
+import React, { useState, useRef, useLayoutEffect } from 'react';
+import Taro from '@tarojs/taro';
+import { View, 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';
+
+/**
+ * ColumnChartFCExample 组件
+ *
+ * FC 示例组件(基于 docs/小程序图表库示例/taro-2d柱状图FC使用示例.md)
+ * 使用原始 u-charts.js + Canvas 2D API
+ *
+ * 用于与 BaseChartOriginal2D 进行对比调试
+ */
+interface ColumnChartFCExampleProps {
+  /** Canvas 元素的 ID,必须唯一 */
+  canvasId?: string;
+  /** 图表宽度(像素),默认为屏幕宽度 */
+  width?: number;
+  /** 图表高度(像素),默认根据宽高比计算 */
+  height?: number;
+}
+
+function ColumnChartFCComponent(props: ColumnChartFCExampleProps) {
+  const { canvasId = 'vTsUbNQurVfZNRMaupTQjygMuEHwuTNT', width = 750, height = 500 } = props;
+
+  const [cWidth, setCWidth] = useState(750);
+  const [cHeight, setCHeight] = useState(500);
+  const [pixelRatio, setPixelRatio] = useState(1);
+
+  // 使用 ref 存储图表实例
+  const uChartsInstanceRef = useRef<Record<string, any>>({});
+
+  const drawCharts = (id: string, data: any) => {
+    const query = Taro.createSelectorQuery();
+    query.select('#' + id).fields({ node: true, size: true }).exec(res => {
+      if (res[0]) {
+        const canvas = res[0].node;
+        const ctx = canvas.getContext('2d') as ExtendedCanvasContext;
+        const chart = new uChartsClass({
+          type: "column",
+          context: ctx,
+          width: canvas.width,
+          height: canvas.height,
+          categories: data.categories,
+          series: data.series,
+          animation: true,
+          background: "#FFFFFF",
+          color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
+          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
+            }
+          }
+        } as ChartsConfig);
+        uChartsInstanceRef.current[id] = chart;
+        console.log('[ColumnChartFCExample] 图表初始化完成:', id);
+      } else {
+        console.error("[ColumnChartFCExample]: 未获取到 context");
+      }
+    });
+  }
+
+  const getServerData = () => {
+    //模拟从服务器获取数据时的延时
+    setTimeout(() => {
+      //模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+      let res = {
+        categories: ["2018", "2019", "2020", "2021", "2022", "2023"],
+        series: [
+          {
+            name: "目标值",
+            data: [35, 36, 31, 33, 13, 34]
+          },
+          {
+            name: "完成量",
+            data: [18, 27, 21, 24, 6, 28]
+          }
+        ]
+      };
+      drawCharts(canvasId, res);
+    }, 500);
+  }
+
+  const tap = (e: any) => {
+    uChartsInstanceRef.current[e.currentTarget.id]?.touchLegend(e);
+    uChartsInstanceRef.current[e.currentTarget.id]?.showToolTip(e);
+  }
+
+  useLayoutEffect(() => {
+    console.debug('[ColumnChartFCExample] useLayoutEffect')
+    const sysInfo = Taro.getSystemInfoSync();
+    const pr = sysInfo.pixelRatio;
+    //这里的第一个 750 对应 css .charts 的 width
+    const cw = width / 750 * sysInfo.windowWidth;
+    //这里的 500 对应 css .charts 的 height
+    const ch = height / 750 * sysInfo.windowWidth;
+    setCWidth(cw);
+    setCHeight(ch);
+    setPixelRatio(pr);
+
+    // 直接在这里获取数据
+    getServerData();
+  }, [width, height, canvasId]);
+
+  const canvasProps = { style: { width: cWidth, height: cHeight } };
+  return (
+    <View>
+      <Canvas
+        {...canvasProps}
+        canvas-id={canvasId}
+        id={canvasId}
+        type="2d"
+        onTouchEnd={tap}
+      />
+    </View>
+  );
+}
+
+// 默认导出
+export default ColumnChartFCComponent;
+
+// 命名导出,保持向后兼容
+export const ColumnChartFCExample = ColumnChartFCComponent;

+ 14 - 0
mini-ui-packages/yongren-statistics-ui/src/pages/Statistics/Statistics.tsx

@@ -6,6 +6,7 @@ import { Navbar } from '@d8d/mini-shared-ui-components/components/navbar'
 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 { enterpriseStatisticsClient } from '../../api/enterpriseStatisticsClient'
@@ -539,6 +540,19 @@ const Statistics: React.FC<StatisticsProps> = () => {
               }
             })()}
         </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>
     </YongrenTabBarLayout>
   )