ItemDistribution.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <div class="item-distribution">
  3. <div class="chart-container" ref="itemChart"></div>
  4. <div class="legend-grid">
  5. <div v-for="(item, index) in chartsData.items" :key="index" class="legend-item">
  6. <div class="legend-dot" :style="{ backgroundColor: item.color }"></div>
  7. <div class="legend-text">{{ item.name }}: {{ item.value }}</div>
  8. </div>
  9. </div>
  10. </div>
  11. </template>
  12. <script>
  13. import * as echarts from 'echarts'
  14. export default {
  15. name: 'ItemDistribution',
  16. props: {
  17. chartsData: {
  18. type: Object,
  19. default: () => ({
  20. items: [
  21. ]
  22. })
  23. }
  24. },
  25. data() {
  26. return {
  27. chart: null
  28. }
  29. },
  30. mounted() {
  31. this.$nextTick(() => {
  32. this.initChart()
  33. })
  34. },
  35. watch: {
  36. chartsData: {
  37. deep: true,
  38. handler() {
  39. this.$nextTick(() => {
  40. if (this.chart) this.chart.dispose()
  41. this.initChart()
  42. })
  43. }
  44. }
  45. },
  46. methods: {
  47. initChart() {
  48. if (!this.$refs.itemChart) return
  49. this.chart = echarts.init(this.$refs.itemChart)
  50. const option = {
  51. responsive: true,
  52. maintainAspectRatio: false,
  53. series: [{
  54. type: 'pie',
  55. radius: ['50%', '70%'],
  56. data: this.chartsData.items.map(item => ({
  57. name: item.name,
  58. value: item.value,
  59. color: item.color
  60. })),
  61. itemStyle: {
  62. color: function(params) {
  63. return params.data.color || params.color
  64. }
  65. },
  66. label: {
  67. show: true,
  68. color: 'rgba(255, 255, 255, 0.7)',
  69. fontSize: 10,
  70. formatter: '{b}\n{d}%'
  71. }
  72. }]
  73. }
  74. this.chart.setOption(option)
  75. }
  76. },
  77. beforeDestroy() {
  78. if (this.chart) this.chart.dispose()
  79. }
  80. }
  81. </script>
  82. <style lang="scss" scoped>
  83. .item-distribution {
  84. .chart-container {
  85. height: 300rpx;
  86. }
  87. .legend-grid {
  88. display: grid;
  89. grid-template-columns: repeat(2, 1fr);
  90. gap: 8rpx;
  91. margin-top: 16rpx;
  92. }
  93. .legend-item {
  94. display: flex;
  95. align-items: center;
  96. font-size: 24rpx;
  97. .legend-dot {
  98. width: 12rpx;
  99. height: 12rpx;
  100. border-radius: 50%;
  101. margin-right: 8rpx;
  102. }
  103. .legend-text {
  104. color: rgba(255, 255, 255, 0.7);
  105. }
  106. }
  107. }
  108. </style>