BarChart.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <div>
  3. <div class="title" v-if="title">{{title}}</div>
  4. <div class="barChart" :id='"barChart"+index' :key="index"/>
  5. </div>
  6. </template>
  7. <script>
  8. import theme from '../../../styles/element-ui.scss';
  9. import elementResizeDetectorMaker from 'element-resize-detector'
  10. import * as echarts from 'echarts';
  11. export default {
  12. name: "BarChart",
  13. props: {
  14. index: {
  15. type: Number|String,
  16. default: 0
  17. },
  18. chartData: {
  19. type: Object,
  20. default: () => ({
  21. xdata: [],
  22. ydata: []
  23. })
  24. },
  25. title: {
  26. type: String
  27. },
  28. unit: {
  29. type: String,
  30. default: ''
  31. },
  32. leftUnit: {
  33. type: Boolean,
  34. default: false
  35. }
  36. },
  37. data() {
  38. return {
  39. chart: null
  40. }
  41. },
  42. watch: {
  43. chartData: {
  44. deep: true,
  45. handler(val) {
  46. this.setOptions()
  47. }
  48. }
  49. },
  50. mounted() {
  51. this.$nextTick(() => {
  52. this.initChart()
  53. })
  54. const _this = this;
  55. const erd = elementResizeDetectorMaker()
  56. erd.listenTo(document.getElementById('barChart'+this.index), element => {
  57. _this.$nextTick(() => {
  58. _this.chart.resize()
  59. })
  60. })
  61. },
  62. methods: {
  63. initChart() {
  64. this.chart = echarts.init(document.getElementById('barChart'+this.index), 'macarons')
  65. this.setOptions()
  66. },
  67. setOptions() {
  68. var ydata = this.chartData.ydata
  69. if (ydata && ydata.length > 1) {
  70. const p = [ydata[0], {
  71. value: ydata[1],
  72. itemStyle: {
  73. color: theme.colorPrimary
  74. }
  75. }]
  76. ydata = p
  77. }
  78. this.chart.setOption({
  79. xAxis: {
  80. data: this.chartData.xdata,
  81. axisTick: {
  82. show: false
  83. },
  84. axisLabel: {
  85. color: '#333',
  86. fontSize: 12
  87. },
  88. axisLine: {
  89. lineStyle: {
  90. color: '#ffffff'
  91. }
  92. },
  93. splitLine: {
  94. show: false,
  95. lineStyle: {
  96. color: '#FDEDFA'
  97. }
  98. }
  99. },
  100. yAxis: {
  101. show: false,
  102. axisLabel: {
  103. show: false,
  104. color: '#5E5E5E'
  105. },
  106. axisLine: {
  107. lineStyle: {
  108. color: '#fff'
  109. }
  110. },
  111. splitLine: {
  112. show: false
  113. }
  114. },
  115. grid: {
  116. show: true,
  117. bottom: 5,
  118. top: 35,
  119. borderColor: '#fff',
  120. containLabel: true
  121. },
  122. series: [{
  123. type: 'bar',
  124. itemStyle: {
  125. color: theme.colorAccent,
  126. barBorderRadius: [4, 4, 0, 0]
  127. },
  128. label: {
  129. show: true,
  130. color: '#000',
  131. position: 'top',
  132. fontWeight: 'bold',
  133. formatter: params => {
  134. var v = params.data.value !== undefined ? params.data.value : params.data
  135. if (this.leftUnit)
  136. return this.unit + v
  137. else
  138. return v + this.unit
  139. }
  140. },
  141. barWidth: 40,
  142. data: ydata,
  143. coordinateSystem: 'cartesian2d'
  144. }]
  145. })
  146. }
  147. }
  148. }
  149. </script>
  150. <style scoped="scoped" lang="scss">
  151. @import '../../../styles/element-ui.scss';
  152. .title {
  153. color: #333;
  154. text-align: center;
  155. font-size: 14px;
  156. position: relative;
  157. padding-bottom: 5px;
  158. }
  159. .title::after {
  160. left: 50%;
  161. bottom: -5px;
  162. width: 50px;
  163. height: 5px;
  164. content: '';
  165. border-radius: 10px;
  166. margin-left: -25px;
  167. background-color: $--color-primary;
  168. position: absolute;
  169. }
  170. .barChart {
  171. width: 100%;
  172. height: 18vh;
  173. }
  174. </style>