echarts.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { useEffect, useRef, useState } from 'react';
  2. import * as echarts from 'echarts/core';
  3. import type { ECharts, EChartsOption } from 'echarts';
  4. import {
  5. GridComponent,
  6. LegendComponent,
  7. MarkLineComponent,
  8. TitleComponent,
  9. ToolboxComponent,
  10. TooltipComponent,
  11. } from 'echarts/components';
  12. import { BarChart, LineChart, PieChart } from 'echarts/charts';
  13. import { UniversalTransition } from 'echarts/features';
  14. import { CanvasRenderer } from 'echarts/renderers';
  15. import Style from './index.less';
  16. import classNames from 'classnames';
  17. export interface EchartsProps {
  18. options?: EChartsOption;
  19. className?: string;
  20. }
  21. echarts.use([
  22. TitleComponent,
  23. ToolboxComponent,
  24. TooltipComponent,
  25. GridComponent,
  26. LegendComponent,
  27. LineChart,
  28. CanvasRenderer,
  29. UniversalTransition,
  30. BarChart,
  31. MarkLineComponent,
  32. PieChart,
  33. ]);
  34. const DefaultOptions = {
  35. xAxis: {
  36. type: 'category',
  37. data: [0],
  38. },
  39. yAxis: {
  40. type: 'value',
  41. },
  42. series: [
  43. {
  44. data: [],
  45. type: 'line',
  46. },
  47. ],
  48. };
  49. export { echarts };
  50. export default (props: EchartsProps) => {
  51. const chartsRef = useRef<any>(null);
  52. const chartsDom = useRef<any>(null);
  53. const [loading, setLoading] = useState(false);
  54. const initEcharts = (dom: HTMLDivElement) => {
  55. console.log('------------init');
  56. if (!dom) return;
  57. chartsRef.current = chartsRef.current || echarts.init(dom);
  58. // chartsRef.current.clear()
  59. if (props.options) {
  60. chartsRef.current.setOption(props.options);
  61. } else {
  62. chartsRef.current.setOption(DefaultOptions);
  63. }
  64. };
  65. const updateSize = () => {
  66. if (chartsRef.current) {
  67. // 自适应屏幕变化
  68. (chartsRef.current as ECharts).resize();
  69. }
  70. };
  71. useEffect(() => {
  72. setTimeout(() => (window as Window).addEventListener('resize', updateSize), 100);
  73. return () => {
  74. (window as Window).removeEventListener('resize', updateSize);
  75. if (chartsRef.current) {
  76. // chartsRef.current.clear();
  77. chartsRef.current.dispose();
  78. chartsRef.current = null;
  79. }
  80. };
  81. }, []);
  82. useEffect(() => {
  83. if (chartsRef.current && props.options) {
  84. // chartsRef.current.clear()
  85. chartsRef.current.setOption(props.options);
  86. }
  87. }, [props.options, chartsRef.current]);
  88. useEffect(() => {
  89. // console.log('------------init')
  90. if (loading) {
  91. setTimeout(() => {
  92. initEcharts(chartsDom.current);
  93. }, 300);
  94. }
  95. }, [loading]);
  96. useEffect(() => {
  97. if (chartsDom.current) {
  98. setLoading(true);
  99. }
  100. }, [chartsDom.current]);
  101. return <div className={classNames(Style['content'], props.className)} ref={chartsDom} />;
  102. };