CET-vue-3.0/src/views/cet/universityDashboard.vue

1196 lines
37 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: 5px 5px">
<a-card :loading="loading" :bordered="false">
<template #extra>
<div class="search-row">
<!-- <div v-if="topCollege != null" style="margin-bottom: 5px;margin-right: 10px;">
<span style="font-size: 15px">当前数据为 </span>
<span style="color: red; font-size: 20px">{{ 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: 18px">{{ topEntrydate }}</span>
<span style="font-size: 15px"> 级数据</span>
</div> -->
<!--<a-cascader v-model:value="collegeMajor" expand-trigger="hover" :options="collegeMajorOptions" change-on-select />-->
<!-- 主外层容器:包括一级和二级菜单并排 -->
<div class="dropdown-wrapper" ref="step1" @blur="loseFocus" tabindex="0">
<div class="dropdown-trigger" @click="toggleDropdown">
<span class="trigger-label">{{ selectedLabel || '请选择学院' }}</span>
<DownOutlined class="trigger-icon" />
</div>
<div v-if="dropdownVisible" class="dropdown-panel">
<!-- 一级菜单独立一列 -->
<div class="main-menu">
<div class="main-menu-scroll">
<div v-for="item in collegeMajorOptions" :key="item.key" class="menu-item">
<span @click.stop="selectItem(item)" style="width: 90%">{{ item.label }}</span>
<span v-if="item.children" class="expand-icon" @click.stop="expandSubMenu(item)">
<RightOutlined />
</span>
</div>
</div>
</div>
<!-- 二级菜单独立一列 -->
<div v-if="subMenuVisible" class="sub-menu">
<div class="sub-menu-scroll">
<div v-for="subItem in currentSubMenu" :key="subItem.key" class="menu-item">
<span @click.stop="selectItem(subItem)" style="width: 100%">{{ subItem.label }}</span>
</div>
</div>
</div>
</div>
</div>
<a-select v-model:value="entrydate" ref="step2" style="margin-left: 10px; width: 100px" :options="entrydateOptions" />
<a-button style="margin-left: 10px" type="primary" ref="step3" @click="query">查询</a-button>
<div class="stats-container">
<span style="padding-left: 240px">{{ totalName }}总人数:{{ total }}</span>
<span>累计通过人数: {{ passNumberBottom }}</span>
<span>累计总通过率: {{ passRateBottom }}</span>
</div>
</div>
<!-- <a-button @click=test()>test</a-button> -->
</template>
<a-row :gutter="12">
<a-col :xl="14">
<div style="padding-left: 10px; min-height: 200px">
<a-table size="small" :dataSource="dataSourceCet4" :columns="columns" ref="step4" :pagination="false" bordered :scroll="{ y: 290 }">
<template #passRateSlot>
累计总通过率
<a-tooltip :title="'累计通过人数 / ' + totalName + '总人数'" placement="top">
<a-icon type="question-circle" />
</a-tooltip>
</template>
</a-table>
</div>
</a-col>
<a-col :xl="10">
<a-card class="card-with-piechart" ref="step5">
<div style="width: 100%; height: 200px" class="piechart" id="piechart"> </div>
</a-card>
</a-col>
</a-row>
<!-- <div style="height: 300px;">
<a-empty style="margin-top: 100px" />
</div> -->
</a-card>
</div>
<div class="bottom-box">
<div class="left-side">
<a-card :loading="loading" :bordered="false" ref="step6">
<div style="width: 100%; height: 350px" id="map2"> </div>
</a-card>
</div>
<div class="right-side">
<!-- <a-row :gutter="12"> -->
<!-- <a-col :xl="16"> -->
<a-card :loading="map1loading" ref="step7">
<!-- <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> -->
<div id="map1" style="width: 100%; height: 350px"></div>
</a-card>
<!-- </a-col> -->
<!-- </a-row> -->
</div>
</div>
<Tour :current="currentStep" :open="stepOpen" :steps="steps" @close="handleOpen(false)" @update:current="updateCurrent" />
</template>
<script>
import { defHttp } from '/@/utils/http/axios';
import * as echarts from 'echarts';
import { message } from 'ant-design-vue';
import { DownOutlined, RightOutlined } from '@ant-design/icons-vue';
import { Tour } from 'ant-design-vue'; // 从 ant-design-vue 导入 Tour 组件
export default {
components: {
DownOutlined,
RightOutlined,
Tour,
},
data() {
return {
stepOpen: false,
currentStep: 0,
steps: [],
activeKey: '1',
allCollege: [],
showBox: false,
showGroup: false,
oneentrydate: null,
collegeentrydate: [],
majorentrydate: [],
lastMajorEntrydate: [],
checkedOptions: [],
collegetab2: [],
collegeMajorOptions: [],
loading: false,
dataSourceCet4: [],
dropdownVisible: false,
subMenuVisible: false,
subSubMenuVisible: false,
selectedLabel: '全校',
currentSubMenu: [],
currentSubSubMenu: [],
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',
getBatch: '/cet/getBatch',
getEntrydate: '/cet/getEntrydate',
getCollegeRate: '/cet/getRateByCollege',
getAllRate: '/cet/getAllRate',
getMajor: '/cet/getMajorByCollege',
getMajorRate: '/cet/getRateByMajor',
getRateByMajor: '/cet/getRateByMajor',
},
map1loading: false,
collegeOptions: [],
batchOptions: [],
levelOptions: [
{ value: 'cet4', label: '英语四级' },
{ value: 'cet6', label: '英语六级' },
],
visible: false,
level: null,
batch: null,
entrydateOptions: [],
majorCheckOn: [],
//对不同的学院选择的专业进行记忆化
lastCollegeMajor: [],
majorLength: 0,
majorOptions: [],
//对学院对比学院进行记忆化上次选择结果
lastCollege: [],
//对学院对比学院进行记忆化上次选择结果
lastCollegeEntrydate: [],
total: 0,
totalName: '',
passNumberBottom: 0,
passRateBottom: 0,
passRatePie: [],
lineXData: [],
lineYData: [],
college: null,
entrydate: 2017, //年级选择器
//设置默认值为全校
collegeMajor: ['全校'], //学院专业选择器
topCollege: null, //顶部选择器
topMajor: null, //顶部选择器
topEntrydate: null, //顶部选择器
};
},
mounted() {
this.getEntrydateAndCollegeData();
this.getCollegeMajorData();
this.query();
// this.allQuery();
this.getCollegeOptions();
this.getEntrydate();
this.$nextTick(() => {
this.initStep();
});
this.isFirstAsk();
},
methods: {
isFirstAsk() {
const isFirstAsk = localStorage.getItem('isFirstAsk');
// 如果是第一次访问isFirstAsk 为空或为 true
//测试引导功能放开注释
//this.handleOpen(true);
if (isFirstAsk === null || isFirstAsk === 'true') {
this.handleOpen(true);
// 将 isFirstAsk 存入 localStorage确保下一次不会再执行
localStorage.setItem('isFirstAsk', 'false');
}
},
initStep() {
console.log('initstep');
this.steps = [
{
title: '选择学院/专业',
description: '请点击选择框选择学院和专业',
// Vue 2 中可以通过传入一个渲染函数来生成封面元素
//cover: function (h) {
// return h('img', {
// attrs: {
// alt: 'tour.png',
// src: 'https://user-images.githubusercontent.com/5378891/197385811-55df8480-7ff4-44bd-9d43-a7dade598d70.png'
// }
// });
//},
// 通过箭头函数保持 this 指向 Vue 实例,从而获取 ref
target: () => this.$refs.step1,
},
{
title: '选择年级',
description: '请点击选择框选择年级',
target: () => this.$refs.step2.$el,
},
{
title: '确认查询',
description: '请点击查询按钮进行查询并绘制图表',
target: () => this.$refs.step3.$el,
},
{
title: '表单介绍',
description: '该学院/专业该年级各个批次的成绩情况',
target: () => this.$refs.step4.$el,
},
{
title: '图表介绍',
description: '该学院/专业该年级在不同年级通过考试的人数占比',
target: () => this.$refs.step5.$el,
},
{
title: '图表介绍',
description: '该学院/专业该年级各个批次的通过率折线图',
target: () => this.$refs.step6.$el,
},
{
title: '图表介绍',
description: '本年级全校各学院通过率排名,点击学院柱状图可查看该学院的其他信息',
target: () => this.$refs.step7.$el,
},
];
},
loseFocus() {
this.dropdownVisible = false;
},
handleOpen(val) {
console.log('handleOpen');
this.stepOpen = val;
},
updateCurrent(val) {
this.currentStep = val;
},
toggleDropdown() {
this.dropdownVisible = !this.dropdownVisible;
this.subMenuVisible = false;
this.subSubMenuVisible = false;
},
selectItem(item) {
// 如果是二级菜单(来自 currentSubMenu找到它的父级
const parent = this.collegeMajorOptions.find((p) => p.children && p.children.some((child) => child.value === item.value));
//console.log('1111', parent.label);
console.log('2222', this.collegeMajorOptions);
//清空collegeMajor
this.collegeMajor = [];
if (parent) {
this.selectedLabel = `${parent.label} / ${item.label}`;
this.collegeMajor[0] = parent.value;
this.collegeMajor[1] = item.value;
} else {
this.selectedLabel = item.label;
this.collegeMajor[0] = item.value;
}
this.dropdownVisible = false;
this.subMenuVisible = false;
this.subSubMenuVisible = false;
console.log('444', this.selectedLabel);
},
expandSubMenu(item) {
this.currentSubMenu = item.children || [];
this.subMenuVisible = true;
this.subSubMenuVisible = false;
},
expandSubSubMenu(item) {
this.currentSubSubMenu = item.children || [];
this.subSubMenuVisible = true;
},
allQuery() {
this.map1loading = true;
console.log('查询===========ddddddddddd');
let college = ['全校'];
let query = 'tab1';
if (this.oneentrydate == null) {
this.oneentrydate = '2017';
}
this.queryChart(query, college, [this.entrydate]);
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;
},
// 各专业通过率
async majorPassRate() {
this.map3loading = true;
},
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: '20%',
//颜色
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;
}
}
console.log('实例化图表');
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) => {
const college = params.name.replace(/\n/g, ''); // 去掉所有换行符
this.selectedLabel = college;
//清空数组
this.collegeMajor = [];
this.collegeMajor[0] = college;
this.query();
console.log('123', college);
console.log(
this.collegeOptions.map((item) => item.value),
'collegeOptions'
);
console.log(this.collegeOptions.map((item) => item.value).includes(name), 'bool');
});
},
// 获取批次数据
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 queryChart(query, college, entrydate) {
console.log('dddddddddddddddddddddddd');
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: [String(entrydate[0])],
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(() => {
console.log('调用==============');
this.dataChart(result.data, query);
});
}
},
// 获取年级和学院数据
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.collegeMajorOptions.unshift({ value: '全校', label: '全校' });
// this.collegeMajor = ['全校'];
console.log(this.collegeMajorOptions);
},
// 查询数据
async query() {
try {
this.allQuery();
//如果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;
console.log('55555', this.collegeMajor);
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);
tableData.forEach((item) => {
const year = item.batch.substring(0, 4);
console.log('year', year);
if (item.batch.includes('12-01')) {
item.batch = `${year}冬季`;
} else if (item.batch.includes('06-01')) {
item.batch = `${year}夏季`;
} else if (item.batch.includes('09-01')) {
item.batch = `${year}夏季`;
} else if (item.batch.includes('03-01')) {
item.batch = `${year}春季`;
}
});
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',
top: '15%',
left: '50px',
right: '50px',
// bottom: '30px',
bottom: '30%',
},
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: 15,
},
},
legend: {
top: 'center',
right: '0%',
orient: 'vertical',
},
color: ['#b3cde0', '#6497b1', '#005b96', '#03396c', '#e5e5e5'],
series: [
//外圈饼图
{
name: '四级通过率',
type: 'pie',
center: ['30%', '60%'],
radius: ['30%', '70%'],
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2,
},
label: {
show: true,
fontSize: 13,
overflow: 'truncate',
minMargin: -1,
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
label: {
show: true,
fontSize: 13,
fontWeight: 'bold',
},
},
data: piedata,
},
],
};
myChart.setOption(option);
},
},
};
</script>
<style lang="less" scoped>
* {
font-size: 12px;
}
::v-deep .ant-card-body {
padding: 4px;
}
::v-deep {
.ant-table-cell {
font-size: 12px;
}
}
.card-with-piechart {
margin-top: 1px;
margin-bottom: 20px;
padding-top: 10px;
height: 100%; /* 调整高度 */
}
.container {
display: flex;
background-color: #fff;
// padding: 15px;
padding: 5px 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;
}
.stats-container {
margin-right: 270px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 90px;
// margin-top: 10px;
//padding-right: px;
// background-color: #f8f8f8f8;
// /* 背景颜色 */
// border-radius: 12px;
// /* 圆角边框 */
}
.stats-container span {
padding: 15px 30px;
/* 调整内边距 */
font-size: 15px;
color: #292929;
/* 文本颜色 */
white-space: nowrap;
/* 防止文本换行 */
flex: 1;
/* 每个项目占据相同的空间 */
text-align: center;
/* 文本居中 */
margin: 0 5px;
/* 调整外边距 */
}
.bottom-box {
display: flex;
column-gap: 10px;
padding: 0 5px;
.left-side {
// margin-top: 41px;
width: 40%;
}
.right-side {
position: relative;
flex: 1;
}
}
.search-row {
display: flex;
align-items: center;
}
.query {
right: 3%;
top: 10px;
position: absolute;
padding-left: 20px;
margin-bottom: 10px;
display: flex;
align-items: center;
z-index: 9999;
}
.dropdown-wrapper {
position: relative; /* ✅ 让下拉菜单基于此定位 */
display: inline-block;
}
.dropdown-trigger {
width: 160px; /* ✅ 设置选择框宽度 */
height: 32px;
border: 1px solid #ccc; /* ✅ 添加边框 */
padding: 6px 12px;
border-radius: 4px;
background-color: #fff;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
}
.dropdown-panel {
position: absolute;
top: 100%; /* ✅ 紧贴选择框底部 */
left: 0;
background: white;
border: 1px solid #ddd;
z-index: 1000;
display: flex;
}
.main-menu,
.sub-menu {
min-width: 160px;
max-height: 300px; /* ✅ 控制每一级高度 */
overflow-y: auto; /* ✅ 各自独立滚动 */
overflow-x: hidden;
border-right: 1px solid #eee;
}
.menu-item {
padding: 6px 12px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
white-space: nowrap;
}
.menu-item:hover {
background: #f5f5f5;
}
.expand-icon {
margin-left: 8px;
color: #999;
}
</style>