|
@@ -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;
|