|
@@ -0,0 +1,167 @@
|
|
|
+<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>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import MxChart from '@/components/MxChart/index'
|
|
|
+import config from '@/common/mx-config'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'elective-generation-charts',
|
|
|
+ components: { MxChart },
|
|
|
+ props: ['chartBinding'],
|
|
|
+ computed: {
|
|
|
+ chartOptions() {
|
|
|
+ const options = this.chartBinding.generation.options
|
|
|
+ let data = this.chartBinding.chartData?.accumulates
|
|
|
+ let generation = this.chartBinding.chartData?.generation
|
|
|
+ let desc = '录取超缺数量'
|
|
|
+ if (this.chartBinding.generation.active == options.primary.value) {
|
|
|
+ generation = options.primary.value // force override primary chart data
|
|
|
+ data = this.chartBinding.generation.summary.find(item => item.generation == generation)?.categories
|
|
|
+ desc = '报名超缺数量'
|
|
|
+ }
|
|
|
+ if (!data?.length) return {}
|
|
|
+ const currentOpt = Object.values(options).find(opt => opt.value == generation)
|
|
|
+
|
|
|
+ // xAxis data - round groups
|
|
|
+ const roundGroups = this.chartBinding.generation.roundGroups
|
|
|
+ const xAxis = roundGroups.map(rg => rg.groupName)
|
|
|
+
|
|
|
+ // yAxis data
|
|
|
+ let series = []
|
|
|
+ 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(
|
|
|
+ roundGroups,
|
|
|
+ rg => rg.expectedCount * 1,
|
|
|
+ rg => (single.find(item => item.category == 'actualCount')?.values
|
|
|
+ .find(item => item.groupId == rg.groupId)?.value || 0) * 1,
|
|
|
+ stackName,
|
|
|
+ [prefix + '报名人数', , prefix + '缺少人数', prefix + '超出人数']
|
|
|
+ )
|
|
|
+ })
|
|
|
+ series = preferenceSeries.reduce((prev, cur) => prev.concat(cur), [])
|
|
|
+ } else {
|
|
|
+ // 本来是创建3条线:基础线,缺少线,超出线,但图表的提示展示不方便
|
|
|
+ // 所以这里创建4条线:期望线,实际线,缺少线,超出线。(期望线,实际线保持相同颜色)
|
|
|
+ series = this.barSeriesMissingAndOverFactory(
|
|
|
+ roundGroups,
|
|
|
+ rg => rg.expectedCount * 1,
|
|
|
+ rg => {
|
|
|
+ const approvedCount = data.find(item => item.category == 'approvedCount')?.values
|
|
|
+ .find(item => item.groupId == rg.groupId)?.value || 0
|
|
|
+ const forcedCount = data.find(item => item.category == 'forcedCount')?.values
|
|
|
+ .find(item => item.groupId == rg.groupId)?.value || 0
|
|
|
+ const enrollCount = approvedCount * 1 + forcedCount * 1
|
|
|
+ return enrollCount
|
|
|
+ },
|
|
|
+ 'Indicator',
|
|
|
+ []
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return this.barOptionFactory('组合统计/' + currentOpt.title, desc, xAxis, series)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ barOptionFactory(title, subTitle, xAxis, series) {
|
|
|
+ return {
|
|
|
+ title: {
|
|
|
+ text: title,
|
|
|
+ subtext: subTitle,
|
|
|
+ left: 'center'
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: xAxis
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value'
|
|
|
+ },
|
|
|
+ series: series,
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ barSeriesMissingAndOverFactory(sourceArr, baseGetter, actualGetter, stackName, lineNames) {
|
|
|
+ // 本来是创建3条线:基础线,缺少线,超出线,但图表的提示展示不方便
|
|
|
+ // 所以这里创建4条线:期望线,实际线,缺少线,超出线。(期望线,实际线保持相同颜色)
|
|
|
+ const series = []
|
|
|
+ const commonDefines = {
|
|
|
+ type: 'bar',
|
|
|
+ stack: stackName,
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series',
|
|
|
+ itemStyle: {
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowOffsetX: 0,
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const actualLine = {
|
|
|
+ ...commonDefines,
|
|
|
+ name: lineNames[0] || '录取人数',
|
|
|
+ data: []
|
|
|
+ }
|
|
|
+ const expectedLine = {
|
|
|
+ ...commonDefines,
|
|
|
+ name: lineNames[1] || '设置人数',
|
|
|
+ data: []
|
|
|
+ }
|
|
|
+ const missingLine = {
|
|
|
+ ...commonDefines,
|
|
|
+ name: lineNames[2] || '缺少人数',
|
|
|
+ data: []
|
|
|
+ }
|
|
|
+ const overLine = {
|
|
|
+ ...commonDefines,
|
|
|
+ name: lineNames[3] || '超出人数',
|
|
|
+ data: []
|
|
|
+ }
|
|
|
+ sourceArr.forEach(item => {
|
|
|
+ const settingCount = baseGetter(item)
|
|
|
+ const enrollCount = actualGetter(item)
|
|
|
+ if (settingCount <= 0 || settingCount == enrollCount) {
|
|
|
+ expectedLine.data.push(0)
|
|
|
+ actualLine.data.push({ value: enrollCount, itemStyle: { color: config.color.primary_report } })
|
|
|
+ missingLine.data.push(0)
|
|
|
+ overLine.data.push(0)
|
|
|
+ } else {
|
|
|
+ const subCount = Math.abs(settingCount - enrollCount)
|
|
|
+ const baseCount = Math.min(settingCount, enrollCount)
|
|
|
+ if (enrollCount > settingCount) {
|
|
|
+ expectedLine.data.push({ value: baseCount, itemStyle: { color: config.color.primary_report } })
|
|
|
+ actualLine.data.push(0)
|
|
|
+ missingLine.data.push(0)
|
|
|
+ overLine.data.push({ value: subCount, itemStyle: { color: config.color.error } })
|
|
|
+ } else {
|
|
|
+ expectedLine.data.push(0)
|
|
|
+ actualLine.data.push({ value: baseCount, itemStyle: { color: config.color.primary_report } })
|
|
|
+ missingLine.data.push({ value: subCount, itemStyle: { color: config.color.yellow_report } })
|
|
|
+ overLine.data.push(0)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ series.push(actualLine, expectedLine, missingLine, overLine)
|
|
|
+ return series
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+
|
|
|
+</style>
|