|
1 | | -import React, { useEffect, useRef, useCallback } from 'react' |
2 | | -import * as echarts from 'echarts' |
3 | | -import { normalizeEChartsOption } from '@utils/echarts/normalizeOption' |
| 1 | +import React, { useMemo, useRef, useCallback } from 'react' |
| 2 | +import EChart from '@stateless/EChart' |
4 | 3 | import PropTypes from 'prop-types' |
| 4 | +import useBigScreenChartsReinit from '@/components/hooks/useBigScreenChartsReinit' |
5 | 5 |
|
6 | 6 | const DonutChart = ({ height = '100%', eOptions }) => { |
7 | | - const chartRef = useRef(null) |
8 | 7 | const chartInstance = useRef(null) |
| 8 | + const chartHandleRef = useRef(null) |
9 | 9 |
|
10 | 10 | const colors = [ |
11 | 11 | ['#2878FF', '#73B9FF'], |
@@ -33,25 +33,11 @@ const DonutChart = ({ height = '100%', eOptions }) => { |
33 | 33 | ['#F8C106', '#FFEAA4'], |
34 | 34 | ] |
35 | 35 |
|
36 | | - // 处理窗口大小变化 |
37 | | - const handleResize = () => { |
38 | | - if (chartInstance.current) { |
39 | | - chartInstance.current.resize() |
40 | | - } |
41 | | - } |
42 | | - |
43 | | - // 初始化图表 |
44 | | - const initChart = () => { |
45 | | - if (!chartRef.current) return |
46 | | - |
47 | | - // 销毁旧实例 |
48 | | - if (chartInstance.current) { |
49 | | - chartInstance.current.dispose() |
50 | | - } |
51 | | - |
52 | | - // 创建新实例 |
53 | | - chartInstance.current = echarts.init(chartRef.current) |
| 36 | + const handleChartInit = useCallback((chart) => { |
| 37 | + chartInstance.current = chart |
| 38 | + }, []) |
54 | 39 |
|
| 40 | + const option = useMemo(() => { |
55 | 41 | const data = eOptions?.data?.map((item, index) => ({ |
56 | 42 | ...item, |
57 | 43 | tooltip: { |
@@ -152,16 +138,20 @@ const DonutChart = ({ height = '100%', eOptions }) => { |
152 | 138 | }, |
153 | 139 | }, |
154 | 140 | labelLayout: (params) => { |
155 | | - const isLeft = params.labelRect.x < chartInstance.current.getWidth() / 2 |
| 141 | + const width = chartInstance.current?.getWidth?.() ?? 0 |
| 142 | + const isLeft = width ? params.labelRect.x < width / 2 : params.labelRect.x < 0 |
156 | 143 | const points = params.labelLinePoints |
| 144 | + if (!points?.[2]) { |
| 145 | + return { hideOverlap: true } |
| 146 | + } |
157 | 147 | points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width |
158 | 148 | return { |
159 | 149 | labelLinePoints: points, |
160 | 150 | hideOverlap: true, |
161 | 151 | } |
162 | 152 | }, |
163 | 153 | animationEasing: 'elasticOut', |
164 | | - animationDelay: () => Math.random() * 200, |
| 154 | + animationDelay: (idx) => idx * 10, |
165 | 155 | } |
166 | 156 |
|
167 | 157 | // 配置项 |
@@ -190,47 +180,14 @@ const DonutChart = ({ height = '100%', eOptions }) => { |
190 | 180 | })) |
191 | 181 | : [optionSerie], |
192 | 182 | } |
| 183 | + return defaultOption |
| 184 | + }, [colors, eOptions]) |
193 | 185 |
|
194 | | - normalizeEChartsOption(defaultOption) |
195 | | - chartInstance.current.setOption(defaultOption) |
196 | | - } |
197 | | - |
198 | | - // 重新初始化图表 |
199 | | - const reinitChart = useCallback(() => { |
200 | | - if (chartInstance.current) { |
201 | | - chartInstance.current.dispose() |
202 | | - } |
203 | | - initChart() |
204 | | - }, [initChart]) |
205 | | - |
206 | | - // 组件挂载和卸载时的处理 |
207 | | - useEffect(() => { |
208 | | - initChart() |
209 | | - window.addEventListener('resize', handleResize) |
210 | | - |
211 | | - // 监听 BigScreen 页面重新初始化事件 |
212 | | - const handleReinit = () => { |
213 | | - reinitChart() |
214 | | - } |
215 | | - window.addEventListener('bigscreen-charts-reinit', handleReinit) |
216 | | - |
217 | | - return () => { |
218 | | - window.removeEventListener('resize', handleResize) |
219 | | - window.removeEventListener('bigscreen-charts-reinit', handleReinit) |
220 | | - if (chartInstance.current) { |
221 | | - chartInstance.current.dispose() |
222 | | - } |
223 | | - } |
224 | | - }, [reinitChart]) |
225 | | - |
226 | | - // 当props变化时重新初始化图表 |
227 | | - useEffect(() => { |
228 | | - if (eOptions) { |
229 | | - initChart() |
230 | | - } |
231 | | - }, [eOptions]) |
| 186 | + useBigScreenChartsReinit(chartHandleRef) |
232 | 187 |
|
233 | | - return <div ref={chartRef} style={{ height, width: '100%' }} /> |
| 188 | + return ( |
| 189 | + <EChart ref={chartHandleRef} option={option} onInit={handleChartInit} notMerge style={{ height, width: '100%' }} /> |
| 190 | + ) |
234 | 191 | } |
235 | 192 |
|
236 | 193 | DonutChart.propTypes = { |
|
0 commit comments