1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
| /*
| * @Company: hugeInfo
| * @Author: AI
| * @Date: 2025-04-17 16:30:00
| * @LastEditTime: 2025-04-23 16:41:01
| * @LastEditors: lwh
| * @Version: 1.0.0
| * @Description: 饼图组件
| */
| import React, { useEffect, useRef } from 'react';
| import * as echarts from 'echarts/core';
| import { PieChart } from 'echarts/charts';
| import { LegendComponent, TooltipComponent } from 'echarts/components';
| import { CanvasRenderer } from 'echarts/renderers';
|
| echarts.use([PieChart, LegendComponent, TooltipComponent, CanvasRenderer]);
|
| /**
| * data: array, // 数据 [{name: '名称', value: 数值, rate: '百分比'}]
| */
| const MyLTopChartPie = (props) => {
| const { data = [], showInside = false, adjustLegend = false } = props;
| const chartRef = useRef(null);
| const chartInstance = useRef(null);
|
| // 饼图颜色
| const colorList = [
| '#3f6fd1', // 市场监管
| '#d23d24', // 教育医疗
| '#c44f92', // 劳动社保
| '#0ab068', // 城市管理
| '#f2923b', // 交通运输
| '#4894c5', // 公共服务
| '#8a5cd8', // 其他
| '#5dc4b7', // 房屋管理
| '#f8cc48', // 土地资源
| '#ac8765' // 备用色
| ];
|
| useEffect(() => {
| if (chartRef.current) {
| if (!chartInstance.current) {
| chartInstance.current = echarts.init(chartRef.current);
| }
| renderChart();
| }
|
| return () => {
| if (chartInstance.current) {
| chartInstance.current.dispose();
| chartInstance.current = null;
| }
| };
| }, [data]);
|
| // 渲染图表
| const renderChart = () => {
| if (!chartInstance.current) return;
|
| const option = {
| tooltip: {
| trigger: 'item',
| formatter: '{a} <br/>{b}: {c} ({d}%)'
| },
| legend: {
| orient: adjustLegend ? 'vertical' : 'horizontal',
| right: adjustLegend ? '0%' : 'center',
| top: adjustLegend ? 'center' : 'bottom',
| itemWidth: 10,
| itemHeight: 10,
| textStyle: {
| color: '#333',
| fontSize: 12,
| },
| formatter: function(name) {
| // 找到对应的数据项
| const item = data.find(item => item.name === name);
| if (!item) return name;
|
| // 如果文本过长,进行截断
| let displayName = name;
| if (name.length > 8) {
| displayName = name.substring(0, 7) + '...';
| }
|
| return `${displayName} (${item.rate}%)`;
| }
| },
| color: [
| '#245DA2','#3491FA','#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de',
| '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'
| ],
| series: [
| {
| name: '纠纷类型',
| type: 'pie',
| radius: '65%',
| center: ['28%', '50%'],
| avoidLabelOverlap: true,
| itemStyle: {
| borderRadius: 4,
| borderColor: '#fff',
| borderWidth: 1
| },
| label: showInside ? {
| show: true,
| position: 'inside',
| formatter: function(params) {
| // 只有占比较大的扇区才显示标签
| if (params.percent > 5) {
| // 名称过长则截断
| let name = params.name;
| if (name.length > 4) {
| name = name.substring(0, 3) + '...';
| }
| return `${name}\n${params.value}`;
| } else {
| return '';
| }
| },
| fontSize: 12,
| color: '#fff'
| } : {
| show: false
| },
| emphasis: {
| label: {
| show: true,
| fontSize: 14,
| fontWeight: 'bold'
| }
| },
| labelLine: {
| show: false
| },
| data: data.map(item => ({
| name: item.name,
| value: item.value
| }))
| }
| ]
| };
|
| chartInstance.current.setOption(option);
| };
|
| return (
| <div ref={chartRef} style={{ width: '100%', height: '100%' }}></div>
| );
| };
|
| export default MyLTopChartPie;
|
|