VisitStatsChart.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <div ref="chartRef" style="width: 100%; height: 350px;"></div>
  3. </template>
  4. <script setup lang="ts">
  5. import { ref, onMounted, watch } from 'vue';
  6. import * as echarts from 'echarts';
  7. const props = defineProps({
  8. data: {
  9. type: Array as any,
  10. default: () => []
  11. }
  12. });
  13. const chartRef = ref<HTMLElement | null>(null);
  14. let chart: echarts.ECharts | null = null;
  15. const initChart = () => {
  16. if (!chartRef.value || props.data.length === 0) return;
  17. if (!chart) {
  18. chart = echarts.init(chartRef.value);
  19. }
  20. const colors = ['#3AA1FF', '#4ECB73', '#FFBB96'];
  21. const chartData = props.data.map((item: any, index: number) => ({
  22. name: item.label,
  23. value: parseFloat(item.value),
  24. itemStyle: {
  25. color: colors[index % colors.length]
  26. }
  27. }));
  28. const option = {
  29. tooltip: {
  30. trigger: 'item',
  31. formatter: '{b}: {c}'
  32. },
  33. legend: {
  34. orient: 'vertical',
  35. right: '5%',
  36. top: 'center',
  37. itemWidth: 12,
  38. itemHeight: 12,
  39. itemGap: 25,
  40. formatter: (name: string) => {
  41. const item = props.data.find((i: any) => i.label === name);
  42. return `{name|${name}: }{value|${item ? item.value : ''}}`;
  43. },
  44. textStyle: {
  45. rich: {
  46. name: {
  47. color: '#666',
  48. fontSize: 12
  49. },
  50. value: {
  51. color: '#333',
  52. fontSize: 13,
  53. fontWeight: 'bold'
  54. }
  55. }
  56. }
  57. },
  58. series: [
  59. {
  60. name: '访销统计',
  61. type: 'pie',
  62. radius: ['60%', '80%'],
  63. center: ['35%', '50%'],
  64. avoidLabelOverlap: false,
  65. label: {
  66. show: false,
  67. position: 'center'
  68. },
  69. emphasis: {
  70. label: {
  71. show: false
  72. }
  73. },
  74. labelLine: {
  75. show: false
  76. },
  77. data: chartData
  78. },
  79. // 装饰性的背景圆环
  80. {
  81. type: 'pie',
  82. radius: ['55%', '85%'],
  83. center: ['35%', '50%'],
  84. silent: true,
  85. itemStyle: {
  86. color: '#f8f9fb'
  87. },
  88. z: -1,
  89. label: { show: false },
  90. data: [{ value: 1 }]
  91. }
  92. ]
  93. };
  94. chart.setOption(option);
  95. };
  96. onMounted(() => {
  97. initChart();
  98. window.addEventListener('resize', () => chart?.resize());
  99. });
  100. watch(() => props.data, () => {
  101. initChart();
  102. }, { deep: true });
  103. </script>