SeizureInfo.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <template>
  2. <div class="seizure-info">
  3. <div class="total-section">
  4. <div class="donut-container">
  5. <div class="chart-container" ref="seizureDonut"></div>
  6. </div>
  7. <div class="dept-bar-container">
  8. <div class="chart-container" ref="deptSeizureBar"></div>
  9. </div>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. import * as echarts from 'echarts'
  15. export default {
  16. name: 'SeizureInfo',
  17. props: {
  18. chartsData: {
  19. type: Object,
  20. default: () => ({
  21. total: 1982,
  22. depts: {
  23. labels: ['旅检一部', '旅检二部', '旅检三部'],
  24. data: [620, 680, 682]
  25. }
  26. })
  27. }
  28. },
  29. data() {
  30. return {
  31. charts: {}
  32. }
  33. },
  34. mounted() {
  35. this.$nextTick(() => {
  36. this.initCharts()
  37. })
  38. },
  39. watch: {
  40. chartsData: {
  41. deep: true,
  42. handler() {
  43. this.$nextTick(() => {
  44. this.disposeCharts()
  45. this.initCharts()
  46. })
  47. }
  48. }
  49. },
  50. methods: {
  51. disposeCharts() {
  52. Object.values(this.charts).forEach(chart => {
  53. if (chart) chart.dispose()
  54. })
  55. this.charts = {}
  56. },
  57. initCharts() {
  58. this.initSeizureDonut()
  59. this.initDeptSeizureBar()
  60. },
  61. initSeizureDonut() {
  62. if (!this.$refs.seizureDonut) return
  63. this.charts.seizureDonut = echarts.init(this.$refs.seizureDonut)
  64. const option = {
  65. responsive: true,
  66. maintainAspectRatio: false,
  67. series: [{
  68. type: 'pie',
  69. radius: ['60%', '80%'],
  70. data: [
  71. { value: this.chartsData.total, name: '查获总数' }
  72. ],
  73. itemStyle: {
  74. color: {
  75. type: 'linear',
  76. x: 0,
  77. y: 0,
  78. x2: 1,
  79. y2: 1,
  80. colorStops: [{
  81. offset: 0, color: '#A78BFA'
  82. }, {
  83. offset: 1, color: '#6366F1'
  84. }]
  85. }
  86. },
  87. label: {
  88. show: false
  89. }
  90. }],
  91. graphic: [
  92. {
  93. type: 'text',
  94. left: 'center',
  95. top: '38%',
  96. style: {
  97. text: String(this.chartsData.total),
  98. fill: '#333',
  99. fontSize: 14,
  100. fontWeight: 'bold',
  101. textAlign: 'center'
  102. },
  103. z: 100
  104. },
  105. {
  106. type: 'text',
  107. left: 'center',
  108. top: '58%',
  109. style: {
  110. text: '查获总数',
  111. fill: '#333',
  112. fontSize: 15,
  113. textAlign: 'center'
  114. },
  115. z: 100
  116. }
  117. ]
  118. }
  119. this.charts.seizureDonut.setOption(option)
  120. },
  121. initDeptSeizureBar() {
  122. if (!this.$refs.deptSeizureBar) return
  123. this.charts.deptSeizureBar = echarts.init(this.$refs.deptSeizureBar)
  124. const option = {
  125. responsive: true,
  126. maintainAspectRatio: false,
  127. tooltip: {
  128. trigger: 'axis',
  129. axisPointer: { type: 'shadow' }
  130. },
  131. legend: {
  132. data: ['查获数量'],
  133. textStyle: { color: '#666', fontSize: 10 },
  134. top: 0
  135. },
  136. grid: {
  137. left: '15%',
  138. right: '5%',
  139. bottom: '15%',
  140. top: '22%'
  141. },
  142. xAxis: {
  143. type: 'category',
  144. data: this.chartsData.depts.labels,
  145. axisLine: {
  146. lineStyle: {
  147. color: 'rgba(0, 0, 0, 0.1)'
  148. }
  149. },
  150. axisLabel: {
  151. color: '#666',
  152. fontSize: 9
  153. }
  154. },
  155. yAxis: {
  156. type: 'value',
  157. axisLine: {
  158. show: false
  159. },
  160. axisTick: {
  161. show: false
  162. },
  163. splitLine: {
  164. lineStyle: {
  165. color: 'rgba(0, 0, 0, 0.05)'
  166. }
  167. },
  168. axisLabel: {
  169. color: '#666',
  170. fontSize: 9
  171. }
  172. },
  173. series: [{
  174. type: 'bar',
  175. data: this.chartsData.depts.data,
  176. itemStyle: {
  177. color: {
  178. type: 'linear',
  179. x: 0,
  180. y: 0,
  181. x2: 0,
  182. y2: 1,
  183. colorStops: [{
  184. offset: 0, color: '#60A5FA'
  185. }, {
  186. offset: 1, color: '#3B82F6'
  187. }]
  188. }
  189. },
  190. barWidth: '50%'
  191. }]
  192. }
  193. this.charts.deptSeizureBar.setOption(option)
  194. }
  195. },
  196. beforeDestroy() {
  197. Object.values(this.charts).forEach(chart => {
  198. if (chart) chart.dispose()
  199. })
  200. }
  201. }
  202. </script>
  203. <style lang="scss" scoped>
  204. .seizure-info {
  205. .total-section {
  206. display: flex;
  207. flex-direction: column;
  208. align-items: center;
  209. }
  210. .donut-container {
  211. position: relative;
  212. width: 240rpx;
  213. height: 240rpx;
  214. margin-bottom: 24rpx;
  215. .chart-container {
  216. min-height: 240rpx;
  217. width: 100%;
  218. height: 100%;
  219. }
  220. }
  221. .dept-bar-container {
  222. width: 100%;
  223. height: 240rpx;
  224. .chart-container {
  225. width: 100%;
  226. height: 100%;
  227. }
  228. }
  229. }
  230. </style>