/** @format */ import React, { useRef, useLayoutEffect, useEffect, useState } from 'react'; import echarts from 'echarts/lib/echarts'; 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 _ from 'lodash'; import { globalTheme, ThemeData } from '../../../utils/theme'; interface RingChartProps { sum?: number; size?: Record; theme?: ThemeData; [key: string]: any; } const RingChart = (props: RingChartProps) => { const { sum = 0, size = { height: 90, width: 90 }, option = {}, data = { value: 335, name: '直接访问' }, theme, backgroundColor, } = props; const colorList = theme ? theme : globalTheme; const wrapperRef = useRef(null); const [echartsInc, setEchartsInc] = useState | null>( null, ); const placeHolderStyle = { normal: { color: 'rgba(0,0,0,0)', label: { show: false }, labelLine: { show: false }, }, emphasis: { color: 'rgba(0,0,0,0)', }, }; let hasPlaceData = data.value < sum ? { value: sum - data.value, name: 'invisible', itemStyle: placeHolderStyle, } : {}; let ringData = [hasPlaceData, data]; const optionBase = { color: [...colorList.colorList], // backgroundColor: '#000', tooltip: { show: true, trigger: 'axis', triggerOn: 'mousemove', hideDelay: 100, textStyle: { fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: colorList.textColor, }, }, legend: { show: false, padding: 40, itemGap: 40, bottom: 0, orient: 'vertical', itemHeight: 7, itemWidth: 8, left: '56%', top: 'middle', icon: 'rect', valueType: 'count', textStyle: { color: '#999', fontSize: 14, verticalAlign: 'top', rich: { a: { padding: [10, 10, 4, 0], }, b: { fontSize: 18, fontFamily: 'DINAlternate-Bold', }, }, }, formatter: (name: string) => { let str: any[] = []; let total = 0; ringData.forEach((item: { value: number }) => { total += item.value; }); ringData.forEach((item: { name: string; value: number }) => { if (item.name === name) { str = [ `{a|${name}}`, optionBase.legend.valueType === 'percent' ? `{b|${Math.round((item.value / total) * 100)}%}` : `\n{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', clockWise: false, radius: ['85%', '88%'], center: ['50%', '50%'], hoverAnimation: false, avoidLabelOverlap: false, label: { show: false, }, itemStyle: { normal: { color: '#666', }, }, data: [ { value: 100, name: '', }, ], }, { name: '访问来源', type: 'pie', radius: ['65%', '75%'], center: ['50%', '50%'], hoverAnimation: false, avoidLabelOverlap: false, label: { show: true, position: 'center', rich: { a: { color: colorList.textColor, fontSize: 18, fontFamily: 'DINAlternate-Bold', lineHeight: 22, fontWeight: 500, }, }, formatter: [`{a|${`${data.value}`}}`].join('\n'), fontFamily: 'Microsoft Yahei', fontWeight: 'normal', fontSize: 14, color: '#999', }, itemStyle: { normal: { color: new echarts.graphic.LinearGradient( 0, 0, 0, 1, [ { // 0% 处的颜色 offset: 0, color: backgroundColor ? backgroundColor : '#000', }, { // 100% 处的颜色 offset: 1, color: colorList.primaryColor, }, ], false, ), }, }, data: ringData, }, ], 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]); useEffect(() => { if (!echartsInc) { return; } echartsInc.resize(); }, [size]); return
; }; RingChart.updatecolorbytheme = () => {}; export default RingChart;