distributionChart.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <template>
  2. <section>
  3. <div class="control">
  4. <el-row type="flex" align="middle">
  5. <el-col :span="4">
  6. <el-select v-model="curStatus" size="small" @change="statusChange">
  7. <el-option
  8. v-for="item in statusList"
  9. :key="item.code"
  10. :disabled="activeTab === '2'&&item.code === 1"
  11. :label="item.label"
  12. :value="item.code"
  13. />
  14. </el-select>
  15. </el-col>
  16. <el-col :span="4" :offset="16" class="col-flex-end">
  17. <div class="bar-pie" :class="[barOrPie==='bar'?'active':'']" @click="changeBarOrPie('bar')">柱状图</div>
  18. <div class="bar-pie" :class="[barOrPie==='pie'?'active':'']" @click="changeBarOrPie('pie')">饼图</div>
  19. </el-col>
  20. </el-row>
  21. </div>
  22. <div class="chart-contain">
  23. <normal-echart v-if="echartsOption" :chart-id="id" :option="echartsOption" />
  24. </div>
  25. </section>
  26. </template>
  27. <script>
  28. import normalEchart from '@/components/chart/normalEchart'
  29. export default {
  30. components: { normalEchart },
  31. props: {
  32. id: {
  33. type: String,
  34. default: 'distribute-chart',
  35. required: false
  36. },
  37. statusList: {
  38. type: Array,
  39. default: () => [],
  40. required: true
  41. },
  42. chartData: {
  43. type: Object,
  44. default: () => null,
  45. required: false
  46. },
  47. status: {
  48. type: Number,
  49. default: NaN,
  50. required: true
  51. },
  52. activeTab: {
  53. type: String,
  54. default: '1',
  55. required: false
  56. }
  57. },
  58. data() {
  59. return {
  60. echartsOption: null,
  61. curStatus: 1, // 当前状态
  62. barOrPie: 'bar' // 柱状图or饼图
  63. }
  64. },
  65. watch: {
  66. chartData: {
  67. handler(newV) {
  68. this.changeBarOrPie(this.barOrPie)
  69. },
  70. deep: true,
  71. immediate: true
  72. },
  73. status: {
  74. handler(newV) {
  75. this.curStatus = newV
  76. },
  77. immediate: true
  78. },
  79. activeTab: {
  80. handler(newV) {
  81. this.activeTab = newV
  82. },
  83. immediate: true
  84. }
  85. },
  86. mounted() {
  87. this.changeBarOrPie(this.barOrPie)
  88. },
  89. methods: {
  90. statusChange(e) {
  91. this.$emit('update:status', this.curStatus)
  92. this.$emit('change')
  93. },
  94. changeBarOrPie(type) { // 饼图柱状图切换
  95. this.barOrPie = type
  96. if (!this.chartData) return
  97. if (type === 'bar') {
  98. this.echartsOption = {
  99. color: ['#3AA1FF'],
  100. tooltip: { trigger: 'axis', axisPointer: { type: 'line' }}, // 默认为直线,可选为:'line' | 'shadow'
  101. grid: { left: '0', right: '0', top: '10%', bottom: '0', containLabel: true },
  102. xAxis: [{ type: 'category', data: this.chartData.xaxis, axisLabel: { interval: 0, rotate: 0 }, axisTick: { alignWithLabel: true }}],
  103. yAxis: [{ type: 'value', axisLine: { show: false }, splitLine: { lineStyle: { type: 'dashed' }}}],
  104. series: [{
  105. name: '数量', type: 'bar', barWidth: '20px', data: this.chartData.yaxis[0] && this.chartData.yaxis[0].data || [],
  106. itemStyle: { normal: { label: { show: true, formatter: '{c}', position: 'top' }}}
  107. }]
  108. }
  109. } else {
  110. const newArr = this.chartData.xaxis.map((item, index) => {
  111. return {
  112. value: this.chartData.yaxis[0] && this.chartData.yaxis[0].data[index] || null,
  113. name: item
  114. }
  115. })
  116. this.echartsOption = {
  117. color: ['#1890FF', '#13C2C2', '#2FC25B', '#FACC14', '#F04864', '#8543E0'],
  118. grid: { left: '0', right: '0', top: '5%', bottom: '0' },
  119. tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' },
  120. legend: { orient: 'vertical', left: 'right', top: 'center', data: this.chartData.xaxis },
  121. series: [{
  122. name: '数量', type: 'pie', radius: ['45%', '60%'], right: '30%', label: { position: 'outer', alignTo: 'edge', margin: 20 }, data: newArr,
  123. itemStyle: { normal: { label: { show: true, formatter: '{b} : {c} ({d}%)' }, labelLine: { show: true }}}
  124. }]
  125. }
  126. }
  127. }
  128. }
  129. }
  130. </script>
  131. <style lang="scss" scoped>
  132. .chart-contain {
  133. position: relative;
  134. height: 400px;
  135. width: 84%;
  136. margin: 20px auto;
  137. }
  138. .control{
  139. width: 84%;
  140. margin: auto;
  141. margin-top: 20px;
  142. }
  143. .bar-pie {
  144. font-size: 14px;
  145. width: 40%;
  146. display: inline-block;
  147. padding: 6px 10px;
  148. margin-left: 5%;
  149. color: #50A6FF;
  150. border: 1px solid #50A6FF;
  151. border-radius: 4px;
  152. text-align: center;
  153. cursor: pointer;
  154. }
  155. .active {
  156. color: #ffffff;
  157. background: #50A6FF;
  158. }
  159. </style>