/** @format */ import 'echarts/lib/chart/pie'; import 'zrender/lib/svg/svg'; import 'echarts/lib/component/tooltip'; import 'echarts/lib/component/title'; import 'echarts/lib/component/legend'; import 'echarts/lib/component/grid'; import echarts from 'echarts/lib/echarts'; import _ from 'lodash'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; interface RingChartProps { size?: Record; [key: string]: any; } const RingChart = (props: RingChartProps) => { const { size = { height: 300 }, option = {}, data: receivedData } = props; const wrapperRef = useRef(null); const [echartsInc, setEchartsInc] = useState | null>( null, ); const [data, setData] = useState[]>([]); useEffect(() => { if (Array.isArray(receivedData)) { setData(receivedData.map(item => ({ name: item.x, value: item.y }))); } else { setData([]); } }, [receivedData]); const optionBase = { color: ['#0a73ff', '#945718', '#79daff'], tooltip: { show: true, trigger: 'axis', triggerOn: 'mousemove', hideDelay: 100, textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: '#fff', }, }, legend: { show: true, padding: 2, itemGap: 10, bottom: 0, orient: 'vertical', itemHeight: 7, itemWidth: 8, left: '66%', top: 'middle', icon: 'circle', valueType: 'count', textStyle: { color: '#999', fontSize: 14, rich: { a: { padding: [4, 10, 4, 0], }, b: { fontSize: 20, fontFamily: 'DINAlternate-Bold', }, }, }, formatter: (name: string) => { let str: any[] = []; let total = 0; data.forEach(item => { total += item.value; }); data.forEach(item => { if (item.name === name) { str = [ `{a|${name}}`, optionBase.legend.valueType === 'percent' ? `{b|${Math.round((item.value / total) * 100)}%}` : `{b|${item.value}}`, ]; } }); return str.join(optionBase.legend.orient === 'horizontal' ? '\n' : ''); }, }, grid: { left: 30, right: 40, bottom: 30, top: 30, containLabel: true, }, radiusAxis: { axisLine: { show: true, }, }, series: [ { name: '访问来源', type: 'pie', radius: ['60%', '70%'], center: ['30%', '50%'], hoverAnimation: false, avoidLabelOverlap: false, label: { show: true, position: 'center', rich: { a: { color: '#fff', fontSize: 24, fontFamily: 'DINAlternate-Bold', lineHeight: 28, }, b: { fontSize: 14, color: '#fff', padding: [3, 0, 0, 0], }, }, formatter: ['{b|完成率}', `{a|${`${30}%`}}`].join('\n'), fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: '#999', }, data, }, ], animation: true, animationEasing: 'cubicOut', animationEasingUpdate: 'cubicOut', animationDuration: 500, animationDurationUpdate: 300, }; useLayoutEffect(() => { if (wrapperRef && wrapperRef.current) { const myChart = echarts.init(wrapperRef.current, null, { devicePixelRatio: 2, }); setEchartsInc(myChart); const latestOption = _.mergeWith({}, optionBase, option); myChart.setOption(latestOption); } }, []); useEffect(() => { if (!echartsInc) { return; } const latestOption = _.mergeWith(optionBase, option); echartsInc.setOption(latestOption, { notMerge: true }); }, [option, data]); useEffect(() => { if (!echartsInc) { return; } echartsInc.resize(); }, [size]); return
; }; export default RingChart;