student.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <el-card>
  3. <div slot="header" class="clearfix">
  4. <span>学员变动</span>
  5. <el-button
  6. @click="isHistogram = !isHistogram"
  7. style="float: right; padding: 0px 0"
  8. type="text"
  9. >{{isHistogram ? '学员转化漏斗图' : '学员柱状图'}}</el-button>
  10. </div>
  11. <statistic :col="5" class="statistic" :cols="0">
  12. <statistic-item v-for="(item, key) in items" :key="key" :class="{active: active === key}" @click="active = key">
  13. <span>
  14. {{item.title}}
  15. <el-tooltip v-if="item.desc" :content="item.desc" :open-delay=".3" placement="top">
  16. <i style="margin-left: 5px;cursor: pointer;" class="el-icon-warning-outline"/>
  17. </el-tooltip>
  18. </span>
  19. <span>
  20. <count-to :endVal="item.percent"/>{{key === 'STUDENT_CONVERSION' ? '%' : ''}}
  21. </span>
  22. </statistic-item>
  23. </statistic>
  24. <ve-histogram
  25. style="width: 100%;"
  26. height="350px"
  27. :data="chartData"
  28. :data-empty="dataEmpty"
  29. :data-zoom="dataZoom"
  30. v-if="isHistogram"
  31. ></ve-histogram>
  32. <ve-funnel v-else style="width: 100%;" height="350px" :data="funnelData" :data-empty="dataEmpty"></ve-funnel>
  33. </el-card>
  34. </template>
  35. <script>
  36. import countTo from 'vue-count-to'
  37. import veHistogram from 'v-charts/lib/histogram.common'
  38. import veFunnel from 'v-charts/lib/funnel.common'
  39. export default {
  40. props: ['data'],
  41. components: {
  42. 've-funnel': veFunnel,
  43. 've-histogram': veHistogram,
  44. 'count-to': countTo
  45. },
  46. computed: {
  47. items() {
  48. return {
  49. MUSIC_GROUP_STUDENT: this.data['MUSIC_GROUP_STUDENT'] || {},
  50. OTHER_STUDENT: this.data['OTHER_STUDENT'] || {},
  51. NEWLY_STUDENT_NUM: this.data['NEWLY_STUDENT_NUM'] || {},
  52. QUIT_MUSIC_GROUP_STUDENT_NUM: this.data['QUIT_MUSIC_GROUP_STUDENT_NUM'] || {},
  53. STUDENT_CONVERSION: this.data['STUDENT_CONVERSION'] || {},
  54. }
  55. },
  56. dataZoom() {
  57. return [
  58. {
  59. type: 'slider',
  60. start: 60,
  61. end: 100
  62. }
  63. ]
  64. },
  65. chartData() {
  66. const values = Object.values(this.items)
  67. const months = {}
  68. for (const item of values) {
  69. for (const row of (item.indexMonthData || [])) {
  70. const key = this.$helpers.dayjs(row.month).format('YYYY-MM-DD')
  71. if (!months[key]) {
  72. months[key] = {
  73. '日期': key,
  74. }
  75. }
  76. months[key][item.title] = row.percent
  77. }
  78. }
  79. return {
  80. columns: ['日期', ...values.map(item => item.title)],
  81. rows: Object.values(months)
  82. }
  83. },
  84. funnelData() {
  85. const { indexMonthData = [] } = this.data['STUDENT_CONVERSION'] || {}
  86. return {
  87. columns: ['类型', '数值'],
  88. rows: indexMonthData.map(item => ({
  89. '类型': item.title,
  90. '数值': item.percent
  91. }))
  92. }
  93. },
  94. dataEmpty() {
  95. return !this.chartData.rows.length
  96. },
  97. },
  98. data () {
  99. return {
  100. active: 'NEWLY_STUDENT_NUM',
  101. isHistogram: true,
  102. }
  103. },
  104. }
  105. </script>
  106. <style lang="less" scoped>
  107. // .statistic{
  108. // /deep/ .statistic-content{
  109. // cursor: pointer;
  110. // &.active > span{
  111. // color: #14928a !important;
  112. // }
  113. // }
  114. // }
  115. </style>