Ver Fonte

generation + pie charts

hare8999@163.com há 3 anos atrás
pai
commit
f94e0e0f0c

+ 2 - 2
mock/modules/elective-generation.js

@@ -3,7 +3,7 @@ const Random = Mock['Random']
 
 const mockGeneration = 5 // primary
 const mockGroups = [1, 2, 3, 4, 5, 6]
-const mockPreferenceCount = 3 // 1 or 3 // 1志愿/3志愿
+const mockPreferenceCount = 1 // 1 or 3 // 1志愿/3志愿
 
 module.exports = [
   {
@@ -31,7 +31,7 @@ module.exports = [
           currentGeneration: mockGeneration,
 
           // +
-          disenrollCount: Random.integer(100, 200)
+          disenrollCount: Random.integer(20, 100)
         }
       }
     }

+ 1 - 1
src/components/MxChart/index.vue

@@ -39,7 +39,7 @@ export default {
     options: function(opt) {
       if (!this.chart || !opt) return
       console.log('mx-chart set option', this.options)
-      this.chart.setOption(opt)
+      this.chart.setOption(opt, true) // true: notMerge
     }
   },
   mounted() {

+ 89 - 12
src/views/elective/generation/components/elective-generation-charts.vue

@@ -1,11 +1,21 @@
 <template>
-  <div class="fx-row fx-bet-cen">
-    <div class="fx-1">
-      <mx-chart :options="chartOptions" :height="'450px'"></mx-chart>
-    </div>
-    <div>
-      <mx-chart></mx-chart>
+  <div class="fx-column">
+    <div class="fx-row fx-bet-cen">
+      <div class="fx-1">
+        <mx-chart ref="bar" :options="chartOptions.bar" :height="'450px'"></mx-chart>
+      </div>
+      <div v-if="chartOptions.pie" class="fx-row fx-cen-cen" style="width: 400px">
+        <mx-chart ref="pie" :options="chartOptions.pie" :height="'400px'"></mx-chart>
+      </div>
     </div>
+    <template v-if="chartOptions.pies&&chartOptions.pies.length">
+      <el-divider></el-divider>
+      <div class="fx-row fx-bet-cen">
+        <div v-for="(pie,idx) in chartOptions.pies" :key="idx" class="fx-1 fx-row fx-cen-cen">
+          <mx-chart ref="pies" :options="pie" :height="'400px'"></mx-chart>
+        </div>
+      </div>
+    </template>
   </div>
 </template>
 
@@ -37,25 +47,51 @@ export default {
 
       // yAxis data
       let series = []
+      let valueNameGroup = null
+      let valueNameGroups = []
       if (generation == options.primary.value) {
         // 初选报名需要单独处理
         const multiplePreference = data.length > 1
         const preferenceSeries = data.map((single, idx) => {
           const prefix = multiplePreference ? `第${idx + 1}志愿/` : ''
           const stackName = 'preference_' + idx
-          return this.barSeriesMissingAndOverFactory(
+          const singleGroup = { dimension: !multiplePreference ? '报名人数' : `第${idx + 1}志愿`, values: [] }
+          const singleSeries = this.barSeriesMissingAndOverFactory(
             roundGroups,
             rg => rg.expectedCount * 1,
-            rg => (single.find(item => item.category == 'actualCount')?.values
-              .find(item => item.groupId == rg.groupId)?.value || 0) * 1,
+            rg => {
+              let actualCount = single.find(item => item.category == 'actualCount')?.values
+                .find(item => item.groupId == rg.groupId)?.value || 0
+              actualCount = actualCount * 1
+              singleGroup.values.push({ value: actualCount, name: rg.groupName })
+              return actualCount
+            },
             stackName,
             [prefix + '报名人数', , prefix + '缺少人数', prefix + '超出人数']
           )
+          let unfinishedCount = single.find(item => item.category == 'actualCount')?.values?.first()?.value || 0
+          unfinishedCount = unfinishedCount * 1
+          singleGroup.values.push({ value: unfinishedCount, name: '未报名' })
+          valueNameGroups.push(singleGroup)
+          return singleSeries
         })
         series = preferenceSeries.reduce((prev, cur) => prev.concat(cur), [])
+        if (valueNameGroups.length > 1) {
+          valueNameGroup = valueNameGroups.reduce((prev, cur) => {
+            const merge = this.deepClone(cur) // NOTE: DO NOT modify raw item
+            merge.dimension = '报名人次'
+            merge.values.forEach(val => {
+              const match = prev.values.find(i => i.name == val.name)
+              val.value = val.value * 1 + (match?.value || 0) * 1
+            })
+            return merge
+          }, { values: [] })
+        } else {
+          valueNameGroup = valueNameGroups?.first()
+          valueNameGroups = []
+        }
       } else {
-        // 本来是创建3条线:基础线,缺少线,超出线,但图表的提示展示不方便
-        // 所以这里创建4条线:期望线,实际线,缺少线,超出线。(期望线,实际线保持相同颜色)
+        valueNameGroup = { dimension: '录取人数', values: [] }
         series = this.barSeriesMissingAndOverFactory(
           roundGroups,
           rg => rg.expectedCount * 1,
@@ -65,16 +101,57 @@ export default {
             const forcedCount = data.find(item => item.category == 'forcedCount')?.values
               .find(item => item.groupId == rg.groupId)?.value || 0
             const enrollCount = approvedCount * 1 + forcedCount * 1
+            valueNameGroup.values.push({ value: enrollCount, name: rg.groupName })
             return enrollCount
           },
           'Indicator',
           []
         )
+        valueNameGroup.values.push({ value: this.chartBinding.generation.status.disenrollCount, name: '未录取' })
+      }
+      setTimeout(() => {
+        this.$refs.bar?.resize()
+        this.$refs.pie?.resize()
+      }, 200)
+      return {
+        bar: this.barOptionFactory('组合统计/' + currentOpt.title, desc, xAxis, series),
+        pie: valueNameGroup && this.pieOptionFactory('组合统计/' + currentOpt.title, valueNameGroup.dimension, '', valueNameGroup.values),
+        pies: valueNameGroups.map(g => this.pieOptionFactory('组合统计/' + currentOpt.title, g.dimension, '', g.values))
       }
-      return this.barOptionFactory('组合统计/' + currentOpt.title, desc, xAxis, series)
     }
   },
   methods: {
+    pieOptionFactory(title, subTitle, dimensionName, valueNamePairs) {
+      return {
+        title: {
+          text: title,
+          subtext: subTitle,
+          left: 'center'
+        },
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left'
+        },
+        series: [
+          {
+            name: dimensionName,
+            type: 'pie',
+            radius: '50%',
+            data: valueNamePairs,
+            emphasis: {
+              itemStyle: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+    },
     barOptionFactory(title, subTitle, xAxis, series) {
       return {
         title: {