bar.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <div ref="dom" class="charts chart-bar"></div>
  3. </template>
  4. <script>
  5. import echarts from 'echarts'
  6. import tdTheme from './theme.json'
  7. import {
  8. on,
  9. off
  10. } from '@/libs/tools'
  11. echarts.registerTheme('tdTheme', tdTheme)
  12. export default {
  13. name: 'ChartBar',
  14. props: {
  15. // 单列柱状图,列name为x轴,value为y轴
  16. value: {
  17. type: Array,
  18. default: function () {
  19. return []
  20. }
  21. },
  22. text: String,
  23. subtext: String,
  24. color: String,
  25. // 当有多列柱状图展示时的X轴坐标数据
  26. xAxisData: {
  27. type: Array,
  28. default: function () {
  29. return []
  30. }
  31. },
  32. // y轴坐标最大值
  33. yMax: {
  34. type: [Number, String],
  35. default: 100
  36. },
  37. // y轴坐标单位
  38. yUnit: {
  39. type: String,
  40. default: ''
  41. },
  42. // 当有多列柱状图展示时的y轴坐标数据
  43. seriesData: {
  44. type: Array,
  45. default: function () {
  46. return []
  47. }
  48. },
  49. // x轴标签旋转角度
  50. xAxisRotate: {
  51. type: Number,
  52. default: 0
  53. }
  54. },
  55. watch: {
  56. xAxisData: {
  57. handler (nVal, oVal) {
  58. // console.log(nVal, 'nnnnnnnn')
  59. if (nVal) {
  60. // 根据x轴时间长度控制滚动条位置及显示状态 x轴长度大于25时,显示滚动条并且滚动条结束位置在80%
  61. if (nVal.length > 25) {
  62. this.isShowZoom = true
  63. this.xZoomEnd = 80
  64. } else {
  65. this.isShowZoom = false
  66. this.xZoomEnd = 100
  67. }
  68. if (nVal.length > 30) {
  69. this.xZoomEnd = 70
  70. }
  71. if (nVal.length > 35) {
  72. this.xZoomEnd = 60
  73. }
  74. if (nVal.length > 40) {
  75. this.xZoomEnd = 50
  76. }
  77. if (nVal.length > 45) {
  78. this.xZoomEnd = 40
  79. }
  80. if (nVal.length > 50) {
  81. this.xZoomEnd = 30
  82. }
  83. this.pageInit()
  84. }
  85. },
  86. deep: true,
  87. immediate: true // 代表如果在 wacth 里声明了 xAxisData 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行
  88. },
  89. xAxisRotate: {
  90. handler (nVal, oVal) {
  91. if (nVal !== '') {
  92. this.pageInit()
  93. }
  94. },
  95. deep: true,
  96. immediate: true
  97. },
  98. value: {
  99. handler (nVal, oVal) {
  100. if (nVal) {
  101. this.pageInit()
  102. }
  103. },
  104. deep: true,
  105. immediate: true
  106. }
  107. },
  108. data () {
  109. return {
  110. dom: null,
  111. isShowZoom: false, // 是否展示滚动条
  112. xZoomEnd: 100 // x轴滚动条结束位置
  113. }
  114. },
  115. methods: {
  116. resize () {
  117. this.dom.resize()
  118. },
  119. pageInit () {
  120. const legend = this.seriesData.map(_ => _.name)
  121. this.$nextTick(() => {
  122. const keys = this.value.map(item => item = item.name)
  123. const values = this.value.map(item => item = item.value)
  124. const xAxisData = this.value.length ? keys : this.xAxisData
  125. const seriesData = this.value.length ? values : this.seriesData
  126. const option = {
  127. color: [this.color],
  128. title: {
  129. text: this.text,
  130. subtext: this.subtext,
  131. x: 'left'
  132. },
  133. legend: {
  134. data: legend
  135. },
  136. tooltip: {
  137. trigger: 'axis'
  138. },
  139. dataZoom: [{
  140. type: 'slider',
  141. show: this.isShowZoom, // flase直接隐藏图形
  142. xAxisIndex: [0],
  143. left: '9%', // 滚动条靠左侧的百分比
  144. bottom: -5,
  145. start: 0, // 滚动条的起始位置
  146. end: this.xZoomEnd, // 滚动条的截止位置(按比例分割你的柱状图x轴长度)
  147. zoomLock: true // 锁定区域禁止缩放(鼠标滚动会缩放,所以禁止)
  148. }],
  149. xAxis: {
  150. type: 'category',
  151. data: xAxisData,
  152. axisLabel: {
  153. interval: 0,
  154. rotate: this.xAxisRotate // 刻度标签旋转的角度,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。旋转的角度从 -90 度到 90 度。
  155. }
  156. },
  157. yAxis: {
  158. type: 'value',
  159. min: 0,
  160. max: this.yMax,
  161. axisLabel: {
  162. formatter: `{value} ${this.yUnit}`
  163. },
  164. // interval: 2,
  165. position: 'left'
  166. },
  167. grid: {
  168. left: '3%',
  169. right: '4%',
  170. bottom: '3%',
  171. containLabel: true
  172. }
  173. }
  174. if (this.value) {
  175. option.series = [{
  176. data: seriesData,
  177. type: 'bar',
  178. barWidth: 35,
  179. label: {
  180. normal: {
  181. show: true,
  182. position: 'top'
  183. }
  184. }
  185. }]
  186. } else {
  187. console.log(this.seriesData, '111111111')
  188. option.series = this.seriesData
  189. }
  190. // console.log(option.series, 'ppppppp')
  191. this.dom = echarts.init(this.$refs.dom, 'tdTheme')
  192. this.dom.setOption(option)
  193. this.dom.resize() // 解决首次加载宽度超出容器bug
  194. on(window, 'resize', this.resize)
  195. })
  196. }
  197. },
  198. mounted () {
  199. this.pageInit()
  200. },
  201. beforeDestroy () {
  202. off(window, 'resize', this.resize)
  203. }
  204. }
  205. </script>