DailySeizureChart.vue 5.3 KB

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