CET-vue-3.0/src/views/dashboard/Analysis/index.vue

407 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div style="background: #ececec; padding: 15px">
<a-card title="四级总通过率查询" :loading="loading" :bordered="false">
<template #extra>
<a-cascader v-model:value="collegeMajor" :options="collegeMajorOptions" change-on-select />
<a-select v-model:value="entrydate" style="margin-left: 10px; width: 100px" :options="entrydateOptions" />
<a-button style="margin-left: 10px" type="primary" @click="query">查询</a-button>
<!-- <a-button @click=test()>test</a-button> -->
</template>
<a-row :gutter="12">
<a-col :xl="13">
<div style="padding-left: 10px; min-height: 400px">
<div v-if="topCollege != null" style="margin-bottom: 5px">
<span style="font-size: 15px">当前数据为 </span>
<span style="color: red; font-size: 18px">{{ topCollege }}</span>
<span v-if="topMajor != null && topMajor != ''" style="color: red; font-size: 18px"> / {{ topMajor }}</span>
<span style="font-size: 15px"> 的 </span>
<span style="color: red; font-size: 20px">{{ topEntrydate }}</span>
<span style="font-size: 15px"> 级数据</span>
</div>
<a-table :dataSource="dataSourceCet4" :columns="columns" :pagination="false" bordered>
<template #passRateSlot>
累计总通过率
<a-tooltip :title="'累计通过人数 / ' + totalName + '总人数'" placement="top">
<a-icon type="question-circle" />
</a-tooltip>
</template>
</a-table>
<div style="display: flex; justify-content: space-between; font-size: 15px; margin-top: 10px" v-if="total && total > 0">
<span>{{ totalName }}总人数:{{ total }}</span>
<span>累计通过人数: {{ passNumberBottom }}</span>
<span>累计总通过率: {{ passRateBottom }}</span>
</div>
</div>
</a-col>
<a-col :xl="11">
<a-card style="margin-top: 33px; margin-bottom: 12px">
<div style="width: 100%; height: 215px" class="piechart" id="piechart"> </div>
</a-card>
<a-card>
<div style="width: 100%; height: 180px" id="map2"> </div>
</a-card>
</a-col>
</a-row>
<!-- <div style="height: 300px;">
<a-empty style="margin-top: 100px" />
</div> -->
</a-card>
</div>
</template>
<script>
import { defHttp } from '/@/utils/http/axios';
import * as echarts from 'echarts';
export default {
data() {
return {
loading: false,
dataSourceCet4: [],
columns: [
{
title: '学年',
dataIndex: 'grade',
key: 'grade',
align: 'center',
customCell: (_, index) => ({
rowSpan: index % 2 === 0 ? 2 : 0, //每两行合并一次grade列的单元格rowSpan为跨度
}),
},
{
title: '考试批次',
dataIndex: 'batch',
key: 'batch',
align: 'center',
},
{
title: '参加人数',
dataIndex: 'attendNumber',
key: 'attendNumber',
align: 'center',
},
{
title: '通过人数',
dataIndex: 'passNumber',
key: 'passNumber',
align: 'center',
},
{
title: '本批次通过率',
dataIndex: 'batchpassrate',
key: 'batchpassrate',
align: 'center',
},
{
slots: { title: 'passRateSlot' },
dataIndex: 'gradepassrate',
key: 'gradepassrate',
align: 'center',
customCell: (_, index) => ({
rowSpan: index % 2 === 0 ? 2 : 0,
}),
},
],
Url: {
getEntrydate: '/cet/getEntrydate',
getCollege: '/cet/getCollege',
getData: '/cet/getData',
getCollegeMajor: '/cet/getCollegeMajor',
},
total: 0,
totalName: '',
passNumberBottom: 0,
passRateBottom: 0,
passRatePie: [],
lineXData: [],
lineYData: [],
collegeOptions: [],
collegeMajorOptions: [],
entrydateOptions: [],
college: null,
entrydate: 2017, //年级选择器
//设置默认值为全校
collegeMajor: ['全校'], //学院专业选择器
topCollege: null, //顶部选择器
topMajor: null, //顶部选择器
topEntrydate: null, //顶部选择器
};
},
mounted() {
this.getEntrydateAndCollegeData();
this.getCollegeMajorData();
this.query();
//this.map2Chart();
},
methods: {
// 获取年级和学院数据
async getEntrydateAndCollegeData() {
const getEntrydate = await defHttp.get({ url: this.Url.getEntrydate });
const getCollege = await defHttp.get({ url: this.Url.getCollege });
this.collegeOptions = getCollege.colleges;
// 手动添加一个全校字段
this.collegeOptions.unshift({ value: '全校', label: '全校' });
this.college = this.collegeOptions[0].value;
this.entrydateOptions = getEntrydate.entrydates;
// this.entrydate = this.entrydateOptions[0].value;
},
//获取学院专业级联数据
async getCollegeMajorData() {
const res = await defHttp.get({ url: this.Url.getCollegeMajor });
//通过map方法将数据转换为级联选择器需要的数据格式
this.collegeMajorOptions = res.collegeMajor.map((item) => {
return {
value: item.college,
label: item.college,
children: item.major.map((major) => {
return {
value: major,
label: major,
};
}),
};
});
//手动添加一个专升本字段
this.collegeMajorOptions.unshift({ value: '专升本', label: '专升本' });
// 手动添加一个全校字段
this.collegeMajorOptions.unshift({ value: '全校', label: '全校' });
// this.collegeMajor = ['全校'];
console.log(this.collegeMajorOptions);
},
// 查询数据
async query() {
try {
//如果this.collegeMajor[1]不存在则设为null
let major = this.collegeMajor.length > 1 ? this.collegeMajor[1] : '';
this.topCollege = this.collegeMajor[0];
this.topMajor = major;
this.topEntrydate = this.entrydate;
if (this.college) this.loading = true;
let params = {
college: this.collegeMajor[0],
major: major,
entrydate: this.entrydate,
};
console.log('params', params);
const result = await defHttp.get({ url: this.Url.getData, params });
let tableData = [];
let piedata = [];
let passrate = 0;
let index = 0;
const passRate = {};
if (result.cet4['大一学年'] != undefined) {
passRate['大一学年'] = result.cet4['大一学年'];
}
if (result.cet4['大二学年'] != undefined) {
passRate['大二学年'] = result.cet4['大二学年'];
}
if (result.cet4['大三学年'] != undefined) {
passRate['大三学年'] = result.cet4['大三学年'];
}
if (result.cet4['大四学年'] != undefined) {
passRate['大四学年'] = result.cet4['大四学年'];
}
result.cet4 = passRate;
this.lineXData = [];
this.lineYData = [];
for (let grade in result.cet4) {
result.cet4[grade].forEach((item) => {
this.lineXData.push(item.batch);
this.lineYData.push((item.batchpassrate * 100).toFixed(1));
if (index % 2 == 0) {
piedata.push({ value: parseFloat(item.gradepassrate - passrate).toFixed(3), name: grade + '时通过' });
passrate = parseFloat(item.gradepassrate).toFixed(3);
}
index++;
tableData.push({
grade: grade,
attendNumber: item.attendNumber,
batch: item.batch,
gradepassrate: (item.gradepassrate * 100).toFixed(1) + '%',
passNumber: item.passNumber,
batchpassrate: (item.batchpassrate * 100).toFixed(1) + '%',
});
});
}
console.log('tableData', tableData);
this.dataSourceCet4 = tableData; //表格数据
this.total = result.total; //总人数
this.totalName = result.totalName; //总人数名称
this.passNumberBottom = result.passNumber; //通过人数
this.passRateBottom = (result.passRate * 100).toFixed(1) + '%'; //通过率
//内置饼图
this.passRatePie = []; //清空数据
this.passRatePie.push({ value: result.passRate, name: '已通过' });
this.passRatePie.push({ value: 1 - result.passRate, name: '未通过' });
piedata.push({ value: (1 - passrate).toFixed(3), name: '未通过' }); //外置饼图
setTimeout(() => {
this.drawPieChart(piedata);
this.map2Chart();
}, 100);
// this.drawPieChart();
} finally {
this.loading = false;
}
},
test() {
defHttp.get({ url: '/cet/getTest' });
},
map2Chart() {
var myChart = echarts.init(document.getElementById('map2'));
var option = {
title: {
text: '各批次通过率分析',
left: 'left',
top: '0%',
textStyle: {
fontSize: 16,
},
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
return (
params[0].name +
'<br/>' +
'<table>' +
'<tr><td>' +
params[0].marker +
'</td><td style="font-weight: bold;">' +
'&nbsp;&nbsp;&nbsp;&nbsp;' +
params[0].value +
'%' +
'</td></tr>' +
'<tr>' +
'</table>'
);
},
},
grid: {
top: '50px',
left: '50px',
right: '50px',
bottom: '30px',
},
xAxis: {
type: 'category',
data: this.lineXData,
},
yAxis: {
type: 'value',
},
series: [
{
data: this.lineYData,
type: 'line',
itemStyle: {
normal: {
label: {
show: true, //开启显示
position: 'top', //在上方显示
textStyle: {
//数值样式
color: 'black',
fontSize: 12,
},
formatter: '{c}%',
},
},
},
},
],
};
option && myChart.setOption(option);
},
drawPieChart(piedata) {
console.log(this.passRatePie);
console.log('piedata', piedata);
let myChart = echarts.init(document.getElementById('piechart'));
let option = {
tooltip: {
trigger: 'item',
confine: false,
avoidLabelOverlap: true,
//字体大小
itemStyle: {
fontSize: 100,
},
},
title: {
text: '四级通过率分析',
left: 'left',
top: '0%',
textStyle: {
fontSize: 16,
},
},
legend: {
top: 'center',
right: '0%',
orient: 'vertical',
},
color: ['#b3cde0', '#6497b1', '#005b96', '#03396c', '#e5e5e5'],
series: [
//外圈饼图
{
name: '四级通过率',
type: 'pie',
center: ['30%', '50%'],
radius: ['35%', '70%'],
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2,
},
label: {
show: true,
fontSize: 14,
overflow: 'truncate',
minMargin: -1,
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
label: {
show: true,
fontSize: 15,
fontWeight: 'bold',
},
},
data: piedata,
},
],
};
myChart.setOption(option);
},
},
};
</script>
<style lang="less" scoped>
.container {
display: flex;
background-color: #fff;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
}
.title {
font-size: 34px;
color: rgb(8, 8, 8);
font-weight: bold;
}
</style>