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'; /** * PieChartFCExample 组件 * * FC 示例组件(基于 docs/小程序图表库示例/taro-2d饼状图class使用示例.md) * 使用原始 u-charts.js + Canvas 2D API * * 用于与 BaseChartOriginal2D 进行对比调试 */ interface PieChartFCExampleProps { /** Canvas 元素的 ID,必须唯一 */ canvasId?: string; /** 图表宽度(像素),默认为屏幕宽度 */ width?: number; /** 图表高度(像素),默认根据宽高比计算 */ height?: number; } function PieChartFCComponent(props: PieChartFCExampleProps) { const { canvasId = 'HPTdeOYFgaHlwidEmFOZkYTRwhnebAad', width = 750, height = 500 } = props; const [cWidth, setCWidth] = useState(750); const [cHeight, setCHeight] = useState(500); const [pixelRatio, setPixelRatio] = useState(1); // 使用 ref 存储图表实例 const uChartsInstanceRef = useRef>({}); 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: "pie", context: ctx, width: canvas.width, height: canvas.height, series: data.series, animation: true, background: "#FFFFFF", color: ["#1890FF","#91CB74","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"], padding: [5,5,5,5], enableScroll: false, extra: { pie: { activeOpacity: 0.5, activeRadius: 10, offsetAngle: 0, labelWidth: 15, border: false, borderWidth: 3, borderColor: "#FFFFFF" } } } as ChartsConfig); uChartsInstanceRef.current[id] = chart; const series = data.series; console.log('[PieChartFCExample] 图表初始化完成:', id, { cWidth, cHeight, canvasWidth: canvas.width, canvasHeight: canvas.height, seriesLength: series.length, series, }); } else { console.error("[PieChartFCExample]: 未获取到 context"); } }); } const getServerData = () => { //模拟从服务器获取数据时的延时 setTimeout(() => { //模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接 let res = { series: [ { data: [{"name":"一班","value":50},{"name":"二班","value":30},{"name":"三班","value":20},{"name":"四班","value":18},{"name":"五班","value":8}] } ] }; 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('[PieChartFCExample] 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 ( ); } // 默认导出 export default PieChartFCComponent; // 命名导出,保持向后兼容 export const PieChartFCExample = PieChartFCComponent;