DailySeizureChart.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <div class="daily-seizure-chart">
  3. <div class="chart-section">
  4. <div class="sub-title">总表</div>
  5. <div class="chart-container" ref="totalChart"></div>
  6. </div>
  7. <div class="chart-section">
  8. <div class="sub-title">{{title}}</div>
  9. <div class="chart-container" ref="deptChart"></div>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. import * as echarts from 'echarts'
  15. export default {
  16. name: 'DailySeizureChart',
  17. props: {
  18. title: {
  19. type: String,
  20. default: '部门对比'
  21. },
  22. chartsData: {
  23. type: Object,
  24. default: () => ({
  25. total: {
  26. labels: ['5/20', '5/21', '5/22', '5/23', '5/24', '5/25', '5/26'],
  27. data: [280, 320, 290, 350, 310, 280, 152]
  28. },
  29. dept: {
  30. labels: ['5/20', '5/21', '5/22', '5/23', '5/24', '5/25', '5/26'],
  31. deptData: [
  32. { name: '旅检一部', data: [90, 100, 95, 110, 100, 95, 52] },
  33. { name: '旅检二部', data: [95, 110, 100, 120, 105, 90, 50] },
  34. { name: '旅检三部', data: [95, 110, 95, 120, 105, 95, 50] }
  35. ]
  36. }
  37. })
  38. }
  39. },
  40. data() {
  41. return {
  42. charts: {}
  43. }
  44. },
  45. mounted() {
  46. this.$nextTick(() => {
  47. this.initCharts()
  48. })
  49. },
  50. watch: {
  51. chartsData: {
  52. deep: true,
  53. handler() {
  54. this.$nextTick(() => {
  55. this.disposeCharts()
  56. this.initCharts()
  57. })
  58. }
  59. }
  60. },
  61. methods: {
  62. disposeCharts() {
  63. Object.values(this.charts).forEach(chart => {
  64. if (chart) chart.dispose()
  65. })
  66. this.charts = {}
  67. },
  68. initCharts() {
  69. this.initTotalChart()
  70. this.initDeptChart()
  71. },
  72. initTotalChart() {
  73. if (!this.$refs.totalChart) return
  74. this.charts.total = echarts.init(this.$refs.totalChart)
  75. const option = {
  76. responsive: true,
  77. maintainAspectRatio: false,
  78. tooltip: {
  79. trigger: 'axis',
  80. axisPointer: { type: 'shadow' }
  81. },
  82. legend: {
  83. data: ['查获总数'],
  84. textStyle: { color: '#666', fontSize: 10 },
  85. top: 0
  86. },
  87. grid: {
  88. left: '10%',
  89. right: '5%',
  90. bottom: '18%',
  91. top: '22%'
  92. },
  93. xAxis: {
  94. type: 'category',
  95. data: this.chartsData.total.labels,
  96. axisLine: {
  97. lineStyle: {
  98. color: 'rgba(0, 0, 0, 0.1)'
  99. }
  100. },
  101. axisLabel: {
  102. color: '#666',
  103. fontSize: 10,
  104. rotate: 30
  105. }
  106. },
  107. yAxis: {
  108. type: 'value',
  109. axisLine: {
  110. show: false
  111. },
  112. axisTick: {
  113. show: false
  114. },
  115. splitLine: {
  116. lineStyle: {
  117. color: 'rgba(0, 0, 0, 0.05)'
  118. }
  119. },
  120. axisLabel: {
  121. color: '#666',
  122. fontSize: 10
  123. }
  124. },
  125. series: [{
  126. type: 'line',
  127. data: this.chartsData.total.data,
  128. smooth: true,
  129. itemStyle: {
  130. color: '#A78BFA'
  131. },
  132. areaStyle: {
  133. color: {
  134. type: 'linear',
  135. x: 0,
  136. y: 0,
  137. x2: 0,
  138. y2: 1,
  139. colorStops: [{
  140. offset: 0, color: '#A78BFA40'
  141. }, {
  142. offset: 1, color: '#A78BFA00'
  143. }]
  144. }
  145. }
  146. }]
  147. }
  148. this.charts.total.setOption(option)
  149. },
  150. initDeptChart() {
  151. if (!this.$refs.deptChart) return
  152. this.charts.dept = echarts.init(this.$refs.deptChart)
  153. const colors = ['#60A5FA', '#A78BFA', '#34D399']
  154. const series = (this.chartsData.dept.deptData || []).map((dept, index) => ({
  155. name: dept.name,
  156. type: 'line',
  157. data: dept.data,
  158. smooth: true,
  159. itemStyle: {
  160. color: colors[index % colors.length]
  161. }
  162. }))
  163. const option = {
  164. responsive: true,
  165. maintainAspectRatio: false,
  166. tooltip: {
  167. trigger: 'axis',
  168. axisPointer: { type: 'shadow' }
  169. },
  170. legend: {
  171. type:'scroll',
  172. data: (this.chartsData.dept.deptData || []).map(d => d.name),
  173. textStyle: {
  174. color: '#333',
  175. fontSize: 9
  176. },
  177. top: 0
  178. },
  179. grid: {
  180. left: '10%',
  181. right: '5%',
  182. bottom: '14%',
  183. top: '22%'
  184. },
  185. xAxis: {
  186. type: 'category',
  187. data: this.chartsData.dept.labels,
  188. axisLine: {
  189. lineStyle: {
  190. color: 'rgba(255, 255, 255, 0.1)'
  191. }
  192. },
  193. axisLabel: {
  194. color: '#333',
  195. fontSize: 10
  196. }
  197. },
  198. yAxis: {
  199. type: 'value',
  200. axisLine: {
  201. show: false
  202. },
  203. axisTick: {
  204. show: false
  205. },
  206. splitLine: {
  207. lineStyle: {
  208. color: 'rgba(255, 255, 255, 0.05)'
  209. }
  210. },
  211. axisLabel: {
  212. color: '#333',
  213. fontSize: 10
  214. }
  215. },
  216. series: series
  217. }
  218. this.charts.dept.setOption(option)
  219. }
  220. },
  221. beforeDestroy() {
  222. Object.values(this.charts).forEach(chart => {
  223. if (chart) chart.dispose()
  224. })
  225. }
  226. }
  227. </script>
  228. <style lang="scss" scoped>
  229. .daily-seizure-chart {
  230. .chart-section {
  231. margin-bottom: 32rpx;
  232. &:last-child {
  233. margin-bottom: 0;
  234. }
  235. }
  236. .sub-title {
  237. font-size: 24rpx;
  238. color: #666;
  239. margin-bottom: 16rpx;
  240. }
  241. .chart-container {
  242. height:450rpx;
  243. }
  244. }
  245. </style>