resume.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div class="chart-box">
  3. <div class="chart-item" v-for="(val, i) in list" :key="i">
  4. <Echarts :height="400" :option="val.option"></Echarts>
  5. </div>
  6. <!-- <div class="fullChart">
  7. <Echarts :height="400" :option="option"></Echarts>
  8. </div> -->
  9. </div>
  10. </template>
  11. <script setup>
  12. defineOptions({ name: 'resume-analysis'})
  13. import { ref, onMounted, watch, nextTick } from 'vue'
  14. import cloneDeep from 'lodash/cloneDeep'
  15. import { getJobCvAgeCount, getJobCvEduCount, getJobCvSexCount, getJobCvExpCount } from '@/api/recruit/enterprise/statistics'
  16. const props = defineProps({
  17. query: Object
  18. })
  19. // 柱状图公共option
  20. const barCommonOption = {
  21. title: {
  22. text: ''
  23. },
  24. xAxis: {
  25. type: 'category',
  26. name: '范围',
  27. axisLabel: {
  28. rotate: 30
  29. },
  30. data: []
  31. },
  32. yAxis: {
  33. type: 'value',
  34. name: '数量(人)'
  35. },
  36. grid: {
  37. left: '20',
  38. top: '70',
  39. right: '50',
  40. bottom: '10',
  41. containLabel: true
  42. },
  43. series: [
  44. {
  45. data: [],
  46. type: 'bar',
  47. barWidth: 40,
  48. label: {
  49. show: true
  50. }
  51. }
  52. ]
  53. }
  54. const list = ref([
  55. {
  56. api: getJobCvSexCount,
  57. isPie: true,
  58. option: {
  59. title: {
  60. text: '性别分布'
  61. },
  62. tooltip: {
  63. trigger: 'item'
  64. },
  65. legend: {
  66. top: '5%',
  67. left: 'center'
  68. },
  69. series: [
  70. {
  71. name: '性别分布',
  72. type: 'pie',
  73. radius: ['40%', '70%'],
  74. avoidLabelOverlap: false,
  75. itemStyle: {
  76. borderRadius: 10,
  77. borderColor: '#fff',
  78. borderWidth: 2
  79. },
  80. label: {
  81. show: true,
  82. formatter: e => {
  83. return e.data.key + ': ' + e.value + '人'
  84. }
  85. },
  86. labelLine: {
  87. show: true
  88. },
  89. data: []
  90. }
  91. ]
  92. }
  93. },
  94. {
  95. api: getJobCvAgeCount,
  96. title: '年龄分布',
  97. option: cloneDeep(barCommonOption)
  98. },
  99. {
  100. api: getJobCvExpCount,
  101. title: '工作年限分布',
  102. option: cloneDeep(barCommonOption)
  103. },
  104. {
  105. api: getJobCvEduCount,
  106. title: '学历分布',
  107. option: cloneDeep(barCommonOption)
  108. }
  109. ])
  110. const getStatistics = () => {
  111. list.value.forEach(async (e) => {
  112. const data = await e.api(props.query)
  113. if (e.isPie) {
  114. e.option.series[0].data = data
  115. } else {
  116. e.option.title.text = e.title
  117. e.option.xAxis.data = data.x
  118. e.option.series[0].data = data.y
  119. }
  120. })
  121. }
  122. onMounted(() => {
  123. nextTick(() => {
  124. getStatistics()
  125. })
  126. })
  127. watch(
  128. () => props.query,
  129. (val) => {
  130. if (val) getStatistics()
  131. },
  132. { deep: true }
  133. )
  134. </script>
  135. <style scoped lang="scss">
  136. .chart-box {
  137. width: 100%;
  138. display: flex;
  139. flex-wrap: wrap;
  140. .chart-item {
  141. width: calc((100% - 24px) / 2);
  142. min-width: calc((100% - 24px) / 2);
  143. max-width: calc((100% - 24px) / 2);
  144. overflow: hidden;
  145. transition: all .2s linear;
  146. background-color: #f7f8fa;
  147. border-radius: 8px;
  148. margin: 0 12px 12px 0;
  149. padding: 12px;
  150. &:nth-child(2n) {
  151. margin-right: 0;
  152. }
  153. }
  154. }
  155. .fullChart {
  156. width: 100%;
  157. background-color: #f7f8fa;
  158. border-radius: 8px;
  159. padding: 12px;
  160. }
  161. </style>