ColumnChartFCExample.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import React, { useState, useRef, useLayoutEffect } from 'react';
  2. import Taro from '@tarojs/taro';
  3. import { View, Canvas } from '@tarojs/components';
  4. import uChartsClass from '../lib/u-charts-original';
  5. import type { ChartsConfig, TouchEvent } from '../types/u-charts-original';
  6. import type { ExtendedCanvasContext } from '../types';
  7. /**
  8. * ColumnChartFCExample 组件
  9. *
  10. * FC 示例组件(基于 docs/小程序图表库示例/taro-2d柱状图FC使用示例.md)
  11. * 使用原始 u-charts.js + Canvas 2D API
  12. *
  13. * 用于与 BaseChartOriginal2D 进行对比调试
  14. */
  15. interface ColumnChartFCExampleProps {
  16. /** Canvas 元素的 ID,必须唯一 */
  17. canvasId?: string;
  18. /** 图表宽度(像素),默认为屏幕宽度 */
  19. width?: number;
  20. /** 图表高度(像素),默认根据宽高比计算 */
  21. height?: number;
  22. }
  23. function ColumnChartFCComponent(props: ColumnChartFCExampleProps) {
  24. const { canvasId = 'vTsUbNQurVfZNRMaupTQjygMuEHwuTNT', width = 750, height = 500 } = props;
  25. const [cWidth, setCWidth] = useState(750);
  26. const [cHeight, setCHeight] = useState(500);
  27. const [pixelRatio, setPixelRatio] = useState(1);
  28. // 使用 ref 存储图表实例
  29. const uChartsInstanceRef = useRef<Record<string, any>>({});
  30. const drawCharts = (id: string, data: any) => {
  31. const query = Taro.createSelectorQuery();
  32. query.select('#' + id).fields({ node: true, size: true }).exec(res => {
  33. if (res[0]) {
  34. const canvas = res[0].node;
  35. const ctx = canvas.getContext('2d') as ExtendedCanvasContext;
  36. const chart = new uChartsClass({
  37. type: "column",
  38. context: ctx,
  39. width: canvas.width,
  40. height: canvas.height,
  41. categories: data.categories,
  42. series: data.series,
  43. animation: true,
  44. background: "#FFFFFF",
  45. color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
  46. padding: [15, 15, 0, 5],
  47. enableScroll: false,
  48. legend: {},
  49. xAxis: {
  50. disableGrid: true
  51. },
  52. yAxis: {
  53. data: [
  54. {
  55. min: 0
  56. }
  57. ]
  58. },
  59. extra: {
  60. column: {
  61. type: "group",
  62. width: 30,
  63. activeBgColor: "#000000",
  64. activeBgOpacity: 0.08
  65. }
  66. }
  67. } as ChartsConfig);
  68. uChartsInstanceRef.current[id] = chart;
  69. const categories = data.categories;
  70. const series = data.series;
  71. console.log('[ColumnChartFCExample] 图表初始化完成:', id, {
  72. cWidth, cHeight,
  73. canvasWidth: canvas.width,
  74. canvasHeight: canvas.height,
  75. categoriesLength: categories.length,
  76. seriesLength: series.length,
  77. categories,
  78. series,
  79. });
  80. } else {
  81. console.error("[ColumnChartFCExample]: 未获取到 context");
  82. }
  83. });
  84. }
  85. const getServerData = () => {
  86. //模拟从服务器获取数据时的延时
  87. setTimeout(() => {
  88. //模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
  89. let res = {
  90. categories: ["2018", "2019", "2020", "2021", "2022", "2023"],
  91. series: [
  92. {
  93. name: "目标值",
  94. data: [35, 36, 31, 33, 13, 34]
  95. },
  96. {
  97. name: "完成量",
  98. data: [18, 27, 21, 24, 6, 28]
  99. }
  100. ]
  101. };
  102. drawCharts(canvasId, res);
  103. }, 500);
  104. }
  105. const tap = (e: any) => {
  106. uChartsInstanceRef.current[e.currentTarget.id]?.touchLegend(e);
  107. uChartsInstanceRef.current[e.currentTarget.id]?.showToolTip(e);
  108. }
  109. useLayoutEffect(() => {
  110. console.debug('[ColumnChartFCExample] useLayoutEffect')
  111. const sysInfo = Taro.getSystemInfoSync();
  112. const pr = sysInfo.pixelRatio;
  113. //这里的第一个 750 对应 css .charts 的 width
  114. const cw = width / 750 * sysInfo.windowWidth;
  115. //这里的 500 对应 css .charts 的 height
  116. const ch = height / 750 * sysInfo.windowWidth;
  117. setCWidth(cw);
  118. setCHeight(ch);
  119. setPixelRatio(pr);
  120. // 直接在这里获取数据
  121. getServerData();
  122. }, [width, height, canvasId]);
  123. const canvasProps = { style: { width: cWidth, height: cHeight } };
  124. return (
  125. <View>
  126. <Canvas
  127. {...canvasProps}
  128. canvas-id={canvasId}
  129. id={canvasId}
  130. type="2d"
  131. onTouchEnd={tap}
  132. />
  133. </View>
  134. );
  135. }
  136. // 默认导出
  137. export default ColumnChartFCComponent;
  138. // 命名导出,保持向后兼容
  139. export const ColumnChartFCExample = ColumnChartFCComponent;