CET-vue-3.0/src/views/cet/cet-ana-1.vue

867 lines
27 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 :bordered="false">
<div>
<div class="query">
<span style="font-size: 15px; margin-right: 10px; display: flex; justify-content: center; align-items: center; font-weight: bold"
>年级:
</span>
<a-select v-model:value="oneentrydate" style="width: 200px" :options="entrydateOptions" />
<a-button style="margin-left: 10px" type="primary" @click="allQuery">查询</a-button>
</div>
<a-card :bordered="true">
<a-row :gutter="12">
<a-col :xl="16">
<a-card :loading="map1loading">
<div id="span">
<div style="display: flex; justify-content: center; align-items: center">
<span style="font-size: 16px">点击柱状图可查看该学院&nbsp; </span>
<span style="font-size: 16px; color: red">各年级四级通过率</span>
</div>
<!-- <span style=" font-size: 18px;">&nbsp 变化</span> -->
</div>
<div id="map1" style="width: 100%; height: 500px"></div>
</a-card>
</a-col>
<a-col :xl="8">
<a-card :loading="map2loading" :style="{ marginBottom: '12px' }">
<div id="map2" style="width: 100%; height: 230px"></div>
</a-card>
<a-card :loading="map3loading">
<div id="map3" style="width: 100%; height: 230px"></div>
</a-card>
</a-col>
</a-row>
</a-card>
</div>
</a-card>
</div>
</template>
<script>
import { defHttp } from '/@/utils/http/axios';
import * as echarts from 'echarts';
import { message } from 'ant-design-vue';
export default {
data() {
return {
activeKey: '1',
allCollege: [],
showBox: false,
showGroup: false,
oneentrydate: null,
collegeentrydate: [],
majorentrydate: [],
lastMajorEntrydate: [],
checkedOptions: [],
collegetab2: [],
collegeMajorOptions: [],
collegeMajor: [],
Url: {
getBatch: '/cet/getBatch',
getEntrydate: '/cet/getEntrydate',
getCollege: '/cet/getCollege',
getCollegeRate: '/cet/getRateByCollege',
getAllRate: '/cet/getAllRate',
getCollegeMajor: '/cet/getCollegeMajor',
getMajor: '/cet/getMajorByCollege',
getMajorRate: '/cet/getRateByMajor',
getRateByMajor: '/cet/getRateByMajor',
},
map1loading: false,
map2loading: false,
map3loading: false,
collegeOptions: [],
batchOptions: [],
levelOptions: [
{ value: 'cet4', label: '英语四级' },
{ value: 'cet6', label: '英语六级' },
],
visible: false,
level: null,
college: [],
batch: null,
entrydateOptions: [],
entrydate: [],
majorCheckOn: [],
//对不同的学院选择的专业进行记忆化
lastCollegeMajor: [],
majorLength: 0,
majorOptions: [],
//对学院对比学院进行记忆化上次选择结果
lastCollege: [],
//对学院对比学院进行记忆化上次选择结果
lastCollegeEntrydate: [],
};
},
mounted() {
this.getCollegeOptions();
// this.getBatch();
this.getEntrydate();
this.allQuery();
this.getCollegeMajorData();
},
methods: {
allQuery() {
this.map1loading = true;
this.map2loading = true; // 新增
this.map3loading = true; // 新增
let college = ['全校'];
let query = 'tab1';
if (this.oneentrydate == null) {
this.oneentrydate = '2017';
}
this.query(query, college, [this.oneentrydate]);
this.majorPassRate();
this.gradePassRate();
},
async majorQuery() {
if (this.majorentrydate.length == 0) {
message.error('请选择年级');
return;
}
if (this.collegeMajor.length == 0 || this.collegeMajor == null) {
message.error('请选择学院');
return;
}
if (this.lastCollegeMajor.length == 0 || this.lastCollegeMajor == null) {
message.error('请选择专业');
return;
}
this.tab3loading = true;
let res = null;
try {
let params = {
college: this.lastCollegeMajor,
entrydate: this.majorentrydate,
};
res = await defHttp.post({ url: this.Url.getRateByMajor, params });
} finally {
console.log(res, 'res');
this.tab3loading = false;
this.$nextTick(() => {
this.drawChart(res.data, 'tab3');
});
}
},
//获取学院专业级联数据
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.collegeMajor = ['东语学院'];
console.log(this.collegeMajor, 'collegeMajor');
console.log(this.collegeMajorOptions, 'collegeMajorOptions1');
},
getCollegeOptions() {
defHttp.get({ url: this.Url.getCollege }).then((res) => {
this.collegeOptions = res.colleges;
// 手动添加一个全校字段
// this.collegeOptions.unshift({ value: '全校', label: '全校' });
// this.collegeOptions.forEach(option => {
// if (option.value !== '全校') {
// option.disabled = true;
//}
// });
// this.college = ['全校'];
// this.collegetab2 = ['地理科学学院', '文学院'];
console.log(this.collegeOptions, 'collegeOptions');
});
},
// 年级通过率
async gradePassRate() {
this.map2loading = true;
const getEntrydate = await defHttp.get({ url: this.Url.getEntrydate });
this.entrydateOptions = getEntrydate.entrydates;
let entrydate = this.entrydateOptions.map((item) => item.value);
const name = ['西语学院'];
let queryParams = {
college: name,
entrydate: entrydate,
level: 'cet4',
};
let url = this.Url.getCollegeRate;
let result = await defHttp.post({ url: url, data: queryParams });
if (!result) {
return;
}
result = result.data[name];
let collegeOption = {
title: {
text: name + '四级通过率',
textStyle: {
fontSize: 14,
},
},
xAxis: {
data: result.map((item) => item.entrydate),
},
//显示数据
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
//生成tooltip,加上小圆球
let result = params[0].name + '<br>';
for (let i = 0; i < params.length; i++) {
result += params[i].marker + name + ' : ' + params[i].value + '%' + '<br>';
}
return result;
},
},
series: {
type: 'line',
data: result.map((item) => item.passRate),
label: {
show: true, // 开启标签显示
position: 'top', // 设置标签显示的位置为上方
formatter: function (params) {
// 在标签文本后面添加百分号
return params.value + '%';
},
// 你可以设置其他的标签样式选项,如颜色、字体大小等
},
universalTransition: {
// enabled: true,
// divideShape: 'clone',
},
},
yAxis: {},
animationDurationUpdate: 500,
};
this.map2loading = false;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById('map2'));
myChart.setOption(collegeOption);
});
},
// 各专业通过率
async majorPassRate() {
this.map3loading = true;
const name = '西语学院';
let queryParams = {
college: [[name]],
entrydate: [this.oneentrydate],
level: 'cet4',
};
let url = this.Url.getMajorRate;
console.log(queryParams, 'queryParams');
let result = await defHttp.post({ url: url, data: queryParams });
if (!result) {
return;
}
//result = result.data[name];
// 遍历 result.data 中的所有专业
const majors = Object.keys(result.data); // 获取所有专业名称
const passRates = majors.map((major) => {
const entries = result.data[major];
return entries.length > 0 ? parseFloat(entries[0].passRate) : 0; // 获取通过率
});
let xData = majors.map((label) => label.split('').join('\n')); //将x轴竖着展示
var majorOption = {
tooltip: {
trigger: 'item',
conginee: false,
//字体大小
itemStytle: {
fontSize: 100,
},
formatter: function (params) {
// 在默认格式基础上添加 %
return `${params.marker}${params.name} ${params.value}%`;
},
},
title: {
text: name + '各专业四级通过率',
textStyle: {
fontSize: 14,
},
},
xAxis: {
type: 'category',
data: xData,
axisLabel: {
interval: 0, //代表显示所有x轴标签显示
//rotate: -10, //代表倾斜30度显示
},
//data: result.map((item) => item.major),
//data: ['英语', '翻译', '法语', '葡萄牙语', '西班牙语'],
},
yAxis: {
type: 'value',
},
series: [
{
label: {
show: true,
fontSize: 14,
overflow: 'truncate',
position: 'top',
formatter: function (params) {
// 在标签文本后面添加百分号
return params.value + '%';
},
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
//鼠标进入时的标签
label: {
show: false,
fontSize: 14,
fontWeight: 'bold',
},
},
data: passRates,
//data: result.map((item) => item.passRate),
//data: [200, 150, 80, 70, 110, 130],
type: 'bar',
},
],
animationDurationUpdate: 500,
};
this.map3loading = false;
this.$nextTick(() => {
var myChart = echarts.init(document.getElementById('map3'));
myChart.setOption(majorOption);
});
},
dataChart(data, tab) {
let seriesData = [];
let xData = [];
let colors = [
'#5370c5',
'#ffffff',
'#fac858',
'#ee6666',
'#73c0de',
'#FF6A6A',
'#FFA500',
'#EE2C2C',
'#90EE90',
'#008B8B',
'#FFC0CB',
'#FFDAB9',
'#FFDEAD',
'#FFE4B5',
'#FFE4C4',
'#FFE4E1',
'#FFEBCD',
'#FFEFD5',
'#FFFAF0',
'#FFFAFA',
'#FFFFE0',
'#FFFFF0',
'#FFFFFF',
'#F0F8FF',
'#FAEBD7',
'#FAF0E6',
'#FAFAD2',
'#F5FFFA',
'#F8F8FF',
'#F0FFF0',
'#F0FFFF',
'#F0E68C',
'#F0F8FF',
'#F0FFF0',
'#F0FFFF',
'#F4A460',
'#F5DEB3',
'#F5F5DC',
'#F5F5F5',
'#F5FFFA',
'#F8F8FF',
'#F9EBEA',
'#FAD7A0',
'#FAF0E6',
'#FAFAD2',
'#FAF0E6 ',
];
let j = 0;
for (let i in data) {
xData = [];
let yData = [];
for (let key in data[i]) {
xData.push(data[i][key].college);
// 将数据转换为百分比(加上%
yData.push(data[i][key].passRate);
}
xData = xData.map((label) => label.split('').join('\n')); //将x轴竖着展示
seriesData.push({
name: i + '级累计总通过率',
type: 'bar',
//设置柱状图大小
barWidth: 1,
data: yData,
//柱子间距
barGap: '30%',
//颜色
itemStyle: {
normal: {
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}%',
textStyle: {
//数值样式
color: 'black',
fontSize: 13,
},
},
color: colors[j++],
},
},
});
if (j == colors.length) {
j = 0;
}
let rankData = yData
.slice()
.sort((a, b) => b - a)
.map((value) => yData.indexOf(value) + 1);
//如果选择全校,增加排名
seriesData.push({
name: i + '级累计总通过率排名',
type: 'line',
yAxisIndex: 1,
data: rankData,
bar: {},
show: false,
itemStyle: {
normal: {
label: {
show: false, //开启显示
position: 'top', //在上方显示
formatter: '{c}',
textStyle: {
//数值样式
color: 'black',
fontSize: 8,
},
},
color: colors[j++],
},
},
});
if (j == colors.length) {
j = 0;
}
}
let myChart = null;
myChart = echarts.init(document.getElementById('map1'));
// 指定图表的配置项和数据
// const college1 = this.college;
let option = {
title: {
text: '本年级学院四级通过率排名',
textStyle: {
fontSize: 16,
},
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
//生成tooltip,加上小圆球
let result = params[0].name + '<br>';
for (let i = 0; i < params.length; i++) {
result += params[i].marker + params[i].seriesName + ' : ' + params[i].value + '%' + '<br>';
}
if (tab == 'tab1') {
result =
params[0].name +
'<br/>' +
'<table>' +
'<tr><td>' +
params[0].marker +
params[0].seriesName +
'</td><td style="font-weight: bold;">' +
'&nbsp;&nbsp;&nbsp;&nbsp;' +
params[0].value +
'%' +
'</td></tr>' +
'<tr><td>' +
params[1].marker +
params[1].seriesName +
'</td><td style="font-weight: bold;">' +
'&nbsp;&nbsp;&nbsp;&nbsp;' +
params[1].value +
'</td></tr>' +
'</table>';
}
return result;
},
},
toolbox: {
// show: true,
// feature: {
// magicType: { show: true, type: ['line', 'bar'] },
// restore: { show: true },
// saveAsImage: { show: true },
// },
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: xData,
axisLabel: {
interval: 0, //代表显示所有x轴标签显示
rotate: 0, //代表倾斜0度显示
},
},
],
yAxis: [
{
type: 'value',
name: '通过率',
axisLabel: {
formatter: '{value} %',
},
},
{
type: 'value',
name: '排名',
show: false,
},
],
series: seriesData,
};
option.series = [
{
name: '累计总通过率',
type: 'bar',
data: seriesData[0].data,
//设置柱状图大小
barWidth: 16,
// barWidth: '60%',
itemStyle: {
normal: {
label: {
show: true, //开启显示
position: 'top', //在上方显示
formatter: '{c}%',
textStyle: {
//数值样式
color: 'black',
fontSize: 10,
},
},
color: colors[0],
},
},
},
{
name: '排名',
type: 'bar',
data: seriesData[1].data,
label: {
show: false,
position: 'inside',
formatter: '{c}',
},
yAxisIndex: 1,
color: colors[1],
},
];
myChart.setOption(option, true);
// 使用刚指定的配置项和数据显示图表。
myChart.on('click', async (params) => {
let name = params.name;
//将name的换行符去掉
name = name.replace(/\n/g, '');
console.log(
this.collegeOptions.map((item) => item.value),
'collegeOptions'
);
console.log(this.collegeOptions.map((item) => item.value).includes(name), 'bool');
if (params != null && params != undefined && params.name != '' && this.collegeOptions.map((item) => item.value).includes(name)) {
console.log(params, 'params');
let entrydate = this.entrydateOptions.map((item) => item.value);
let queryParams = {
college: [name],
entrydate: entrydate,
level: 'cet4',
};
let url = this.Url.getCollegeRate;
this.map2loading = true;
this.map3loading = true;
let result = await defHttp.post({ url: url, data: queryParams });
if (!result) {
return;
}
result = result.data[name];
let collegeOption = {
title: {
text: name + '四级通过率',
textStyle: {
fontSize: 14,
},
},
xAxis: {
data: result.map((item) => item.entrydate),
},
//显示数据
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
//生成tooltip,加上小圆球
let result = params[0].name + '<br>';
for (let i = 0; i < params.length; i++) {
result += params[i].marker + name + ' : ' + params[i].value + '%' + '<br>';
}
return result;
},
},
series: {
type: 'line',
data: result.map((item) => item.passRate),
label: {
show: true, // 开启标签显示
position: 'top', // 设置标签显示的位置为上方
formatter: function (params) {
// 在标签文本后面添加百分号
return params.value + '%';
},
// 你可以设置其他的标签样式选项,如颜色、字体大小等
},
universalTransition: {
// enabled: true,
// divideShape: 'clone',
},
},
yAxis: {},
animationDurationUpdate: 500,
};
//点击事件中的个专业四级通过率
let querMajorParam = {
college: [[name]],
entrydate: [this.oneentrydate],
level: 'cet4',
};
let urlMajor = this.Url.getMajorRate;
let resultMajor = await defHttp.post({ url: urlMajor, data: querMajorParam });
if (!resultMajor) {
return;
}
//result = result.data[name];
// 遍历 result.data 中的所有专业
const majors = Object.keys(resultMajor.data); // 获取所有专业名称
const passRates = majors.map((major) => {
const entries = resultMajor.data[major];
return entries.length > 0 ? parseFloat(entries[0].passRate) : 0; // 获取通过率
});
xData = majors.map((label) => label.split('').join('\n')); //将x轴竖着展示
var majorOption = {
tooltip: {
trigger: 'item',
conginee: false,
//字体大小
itemStytle: {
fontSize: 100,
},
},
title: {
text: name + '各专业四级通过率',
textStyle: {
fontSize: 14,
},
},
xAxis: {
type: 'category',
data: xData,
axisLabel: {
interval: 0, //代表显示所有x轴标签显示
//rotate: -10, //代表倾斜30度显示
},
//data: result.map((item) => item.major),
//data: ['英语', '翻译', '法语', '葡萄牙语', '西班牙语'],
},
yAxis: {
type: 'value',
},
series: [
{
//显示时的标签
label: {
show: true,
fontSize: 14,
overflow: 'truncate',
position: 'top',
formatter: function (params) {
// 在标签文本后面添加百分号
return params.value + '%';
},
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
//鼠标进入时的标签
label: {
show: false,
fontSize: 14,
fontWeight: 'bold',
},
},
data: passRates,
//data: result.map((item) => item.passRate),
//data: [200, 150, 80, 70, 110, 130],
type: 'bar',
},
],
animationDurationUpdate: 500,
};
this.map3loading = false;
this.map2loading = false;
this.$nextTick(() => {
var map2Chart = echarts.init(document.getElementById('map2'));
map2Chart.setOption(collegeOption, true);
var map3Chart = echarts.init(document.getElementById('map3'));
map3Chart.setOption(majorOption, true);
});
}
});
},
// 获取批次数据
async getBatch() {
const getBatch = await defHttp.get({ url: this.Url.getBatch });
this.batchOptions = getBatch.batches;
this.batch = this.batchOptions[0].value;
this.level = this.levelOptions[0].value;
},
//获取年级数据
async getEntrydate() {
const getEntrydate = await defHttp.get({ url: this.Url.getEntrydate });
this.entrydateOptions = getEntrydate.entrydates;
this.oneentrydate = this.entrydateOptions[0].value;
// this.collegeentrydate = [this.entrydateOptions[0].value];
// this.majorentrydate = [this.entrydateOptions[0].value];
// this.entrydate.push (this.entrydateOptions[0].value);
},
// 查询数据
async query(query, college, entrydate) {
this.visible = false;
let result = null;
// console.log(this.college, this.entrydate);
// //如果this.college和this.batch为null则先赋静态值
// if (this.college === null || this.college.length === 0) {
// this.college = ['全校'];
// }
// if (!this.entrydate || this.entrydate.length === 0) {
// this.entrydate = ['2017'];
// }
try {
// console.log(this.college, this.entrydate)
let params = {
college: college,
entrydate: entrydate,
level: 'cet4',
};
let url = query == 'tab1' ? this.Url.getAllRate : this.Url.getCollegeRate;
console.log(params.college, 'college');
result = await defHttp.post({ url: url, params });
//使数据按照passRate从大到小排序
// result.data.sort((a, b) => {
// return b.passRate - a.passRate;
// });
console.log('data', result.data);
} finally {
this.map1loading = false;
this.$nextTick(() => {
this.dataChart(result.data, query);
});
}
},
},
};
</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);
}
.query {
//居左
display: flex;
justify-content: flex-end;
align-items: center;
margin-left: 24px;
padding-bottom: 10px;
}
.tab3 {
justify-content: flex-start;
align-items: center;
margin-left: 24px;
}
.title {
font-size: 34px;
color: rgb(8, 8, 8);
font-weight: bold;
}
</style>