update
This commit is contained in:
@@ -52,13 +52,13 @@ interface ClassComparison {
|
|||||||
iqr: number
|
iqr: number
|
||||||
std_dev: number
|
std_dev: number
|
||||||
top_10_avg: number
|
top_10_avg: number
|
||||||
|
middle_80_avg: number
|
||||||
bottom_10_avg: number
|
bottom_10_avg: number
|
||||||
top_25_avg: number
|
|
||||||
bottom_25_avg: number
|
|
||||||
excellent_rate: number
|
excellent_rate: number
|
||||||
pass_rate: number
|
pass_rate: number
|
||||||
active_rate: number
|
active_rate: number
|
||||||
ac_rate: number
|
ac_rate: number
|
||||||
|
composite_score: number
|
||||||
recent_total_ac?: number
|
recent_total_ac?: number
|
||||||
recent_avg_ac?: number
|
recent_avg_ac?: number
|
||||||
recent_median_ac?: number
|
recent_median_ac?: number
|
||||||
@@ -170,6 +170,24 @@ function getClassColor(index: number) {
|
|||||||
return colors[index % colors.length]
|
return colors[index % colors.length]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 综合分对比图
|
||||||
|
const compositeScoreChartData = computed(() => {
|
||||||
|
if (comparisons.value.length === 0) return null
|
||||||
|
|
||||||
|
const labels = comparisons.value.map((c) => c.class_name)
|
||||||
|
const datasets = [
|
||||||
|
{
|
||||||
|
label: "综合分",
|
||||||
|
data: comparisons.value.map((c) => c.composite_score),
|
||||||
|
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
||||||
|
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
return { labels, datasets }
|
||||||
|
})
|
||||||
|
|
||||||
// 总AC数对比图 - 每个班级用不同颜色
|
// 总AC数对比图 - 每个班级用不同颜色
|
||||||
const totalAcChartData = computed(() => {
|
const totalAcChartData = computed(() => {
|
||||||
if (comparisons.value.length === 0) return null
|
if (comparisons.value.length === 0) return null
|
||||||
@@ -278,14 +296,14 @@ const activeRateChartData = computed(() => {
|
|||||||
return { labels, datasets }
|
return { labels, datasets }
|
||||||
})
|
})
|
||||||
|
|
||||||
// 前10名平均对比图
|
// 前10%平均对比图
|
||||||
const top10AvgChartData = computed(() => {
|
const top10AvgChartData = computed(() => {
|
||||||
if (comparisons.value.length === 0) return null
|
if (comparisons.value.length === 0) return null
|
||||||
|
|
||||||
const labels = comparisons.value.map((c) => c.class_name)
|
const labels = comparisons.value.map((c) => c.class_name)
|
||||||
const datasets = [
|
const datasets = [
|
||||||
{
|
{
|
||||||
label: "前10名平均",
|
label: "前10%平均",
|
||||||
data: comparisons.value.map((c) => c.top_10_avg),
|
data: comparisons.value.map((c) => c.top_10_avg),
|
||||||
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
||||||
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
||||||
@@ -296,14 +314,14 @@ const top10AvgChartData = computed(() => {
|
|||||||
return { labels, datasets }
|
return { labels, datasets }
|
||||||
})
|
})
|
||||||
|
|
||||||
// 后10名平均对比图
|
// 后10%平均对比图
|
||||||
const bottom10AvgChartData = computed(() => {
|
const bottom10AvgChartData = computed(() => {
|
||||||
if (comparisons.value.length === 0) return null
|
if (comparisons.value.length === 0) return null
|
||||||
|
|
||||||
const labels = comparisons.value.map((c) => c.class_name)
|
const labels = comparisons.value.map((c) => c.class_name)
|
||||||
const datasets = [
|
const datasets = [
|
||||||
{
|
{
|
||||||
label: "后10名平均",
|
label: "后10%平均",
|
||||||
data: comparisons.value.map((c) => c.bottom_10_avg),
|
data: comparisons.value.map((c) => c.bottom_10_avg),
|
||||||
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
||||||
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
||||||
@@ -314,33 +332,15 @@ const bottom10AvgChartData = computed(() => {
|
|||||||
return { labels, datasets }
|
return { labels, datasets }
|
||||||
})
|
})
|
||||||
|
|
||||||
// 前25%平均对比图
|
// 中间80%均值对比图
|
||||||
const top25AvgChartData = computed(() => {
|
const middle80AvgChartData = computed(() => {
|
||||||
if (comparisons.value.length === 0) return null
|
if (comparisons.value.length === 0) return null
|
||||||
|
|
||||||
const labels = comparisons.value.map((c) => c.class_name)
|
const labels = comparisons.value.map((c) => c.class_name)
|
||||||
const datasets = [
|
const datasets = [
|
||||||
{
|
{
|
||||||
label: "前25%平均",
|
label: "中间80%均值",
|
||||||
data: comparisons.value.map((c) => c.top_25_avg),
|
data: comparisons.value.map((c) => c.middle_80_avg),
|
||||||
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
|
||||||
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
|
||||||
borderWidth: 2,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
return { labels, datasets }
|
|
||||||
})
|
|
||||||
|
|
||||||
// 后25%平均对比图
|
|
||||||
const bottom25AvgChartData = computed(() => {
|
|
||||||
if (comparisons.value.length === 0) return null
|
|
||||||
|
|
||||||
const labels = comparisons.value.map((c) => c.class_name)
|
|
||||||
const datasets = [
|
|
||||||
{
|
|
||||||
label: "后25%平均",
|
|
||||||
data: comparisons.value.map((c) => c.bottom_25_avg),
|
|
||||||
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
backgroundColor: comparisons.value.map((_, i) => getClassColor(i).bg),
|
||||||
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
borderColor: comparisons.value.map((_, i) => getClassColor(i).border),
|
||||||
borderWidth: 2,
|
borderWidth: 2,
|
||||||
@@ -474,6 +474,17 @@ const chartOptions = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const compositeScoreChartOptions = {
|
||||||
|
...chartOptions,
|
||||||
|
scales: {
|
||||||
|
...chartOptions.scales,
|
||||||
|
y: {
|
||||||
|
...chartOptions.scales.y,
|
||||||
|
max: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const radarChartOptions = {
|
const radarChartOptions = {
|
||||||
responsive: true,
|
responsive: true,
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
@@ -575,6 +586,9 @@ const radarChartOptions = {
|
|||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-tag :type="getRankColor(index).type" size="large">
|
<n-tag :type="getRankColor(index).type" size="large">
|
||||||
#{{ getRankColor(index).text }}
|
#{{ getRankColor(index).text }}
|
||||||
|
<span style="margin-left: 6px; font-size: 12px; opacity: 0.85">
|
||||||
|
{{ classData.composite_score }} 分
|
||||||
|
</span>
|
||||||
</n-tag>
|
</n-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -676,26 +690,21 @@ const radarChartOptions = {
|
|||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
|
|
||||||
<!-- 分层统计 -->
|
<!-- 分层统计 -->
|
||||||
<n-descriptions-item label="前10名平均">
|
<n-descriptions-item label="前10%均值">
|
||||||
<span style="color: #cf1322; font-weight: 600">{{
|
<span style="color: #cf1322; font-weight: 600">{{
|
||||||
classData.top_10_avg.toFixed(2)
|
classData.top_10_avg.toFixed(2)
|
||||||
}}</span>
|
}}</span>
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item label="后10名平均">
|
<n-descriptions-item label="中间80%均值">
|
||||||
|
<span style="color: #389e0d; font-weight: 600">{{
|
||||||
|
classData.middle_80_avg.toFixed(2)
|
||||||
|
}}</span>
|
||||||
|
</n-descriptions-item>
|
||||||
|
<n-descriptions-item label="后10%均值">
|
||||||
<span style="color: #096dd9; font-weight: 500">{{
|
<span style="color: #096dd9; font-weight: 500">{{
|
||||||
classData.bottom_10_avg.toFixed(2)
|
classData.bottom_10_avg.toFixed(2)
|
||||||
}}</span>
|
}}</span>
|
||||||
</n-descriptions-item>
|
</n-descriptions-item>
|
||||||
<n-descriptions-item label="前25%平均">
|
|
||||||
<span style="color: #f5222d; font-weight: 600">{{
|
|
||||||
classData.top_25_avg.toFixed(2)
|
|
||||||
}}</span>
|
|
||||||
</n-descriptions-item>
|
|
||||||
<n-descriptions-item label="后25%平均">
|
|
||||||
<span style="color: #531dab; font-weight: 500">{{
|
|
||||||
classData.bottom_25_avg.toFixed(2)
|
|
||||||
}}</span>
|
|
||||||
</n-descriptions-item>
|
|
||||||
|
|
||||||
<!-- 人数 -->
|
<!-- 人数 -->
|
||||||
<n-descriptions-item label="人数">
|
<n-descriptions-item label="人数">
|
||||||
@@ -793,6 +802,17 @@ const radarChartOptions = {
|
|||||||
|
|
||||||
<!-- 可视化图表 - 专注于对比 -->
|
<!-- 可视化图表 - 专注于对比 -->
|
||||||
<template v-if="comparisons.length > 0">
|
<template v-if="comparisons.length > 0">
|
||||||
|
<!-- 综合分对比 - 一眼看出胜负 -->
|
||||||
|
<n-card title="综合分对比(满分100)" style="margin-top: 20px">
|
||||||
|
<div style="height: 300px">
|
||||||
|
<Bar
|
||||||
|
v-if="compositeScoreChartData"
|
||||||
|
:data="compositeScoreChartData"
|
||||||
|
:options="compositeScoreChartOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</n-card>
|
||||||
|
|
||||||
<!-- AC核心指标对比 - 三个独立图表并排显示 -->
|
<!-- AC核心指标对比 - 三个独立图表并排显示 -->
|
||||||
<n-card title="AC核心指标对比" style="margin-top: 20px">
|
<n-card title="AC核心指标对比" style="margin-top: 20px">
|
||||||
<n-grid :cols="3" :x-gap="16" :y-gap="16">
|
<n-grid :cols="3" :x-gap="16" :y-gap="16">
|
||||||
@@ -859,9 +879,9 @@ const radarChartOptions = {
|
|||||||
</n-grid>
|
</n-grid>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
|
||||||
<!-- 分层统计对比 - 四个独立图表并排显示 -->
|
<!-- 分层统计对比 - 三个独立图表并排显示 -->
|
||||||
<n-card title="分层统计对比" style="margin-top: 20px">
|
<n-card title="分层统计对比" style="margin-top: 20px">
|
||||||
<n-grid :cols="2" :x-gap="16" :y-gap="16">
|
<n-grid :cols="3" :x-gap="16" :y-gap="16">
|
||||||
<n-gi>
|
<n-gi>
|
||||||
<div style="height: 300px">
|
<div style="height: 300px">
|
||||||
<Bar
|
<Bar
|
||||||
@@ -871,6 +891,15 @@ const radarChartOptions = {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
|
<n-gi>
|
||||||
|
<div style="height: 300px">
|
||||||
|
<Bar
|
||||||
|
v-if="middle80AvgChartData"
|
||||||
|
:data="middle80AvgChartData"
|
||||||
|
:options="chartOptions"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</n-gi>
|
||||||
<n-gi>
|
<n-gi>
|
||||||
<div style="height: 300px">
|
<div style="height: 300px">
|
||||||
<Bar
|
<Bar
|
||||||
@@ -880,24 +909,6 @@ const radarChartOptions = {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
<n-gi>
|
|
||||||
<div style="height: 300px">
|
|
||||||
<Bar
|
|
||||||
v-if="top25AvgChartData"
|
|
||||||
:data="top25AvgChartData"
|
|
||||||
:options="chartOptions"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</n-gi>
|
|
||||||
<n-gi>
|
|
||||||
<div style="height: 300px">
|
|
||||||
<Bar
|
|
||||||
v-if="bottom25AvgChartData"
|
|
||||||
:data="bottom25AvgChartData"
|
|
||||||
:options="chartOptions"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</n-gi>
|
|
||||||
</n-grid>
|
</n-grid>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
|
||||||
@@ -928,6 +939,17 @@ const radarChartOptions = {
|
|||||||
render: (_, index) => getRankColor(index).text,
|
render: (_, index) => getRankColor(index).text,
|
||||||
width: 80,
|
width: 80,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '综合分',
|
||||||
|
key: 'composite_score',
|
||||||
|
width: 90,
|
||||||
|
render: (row) =>
|
||||||
|
h(
|
||||||
|
'span',
|
||||||
|
{ style: { color: '#722ed1', fontWeight: '700', fontSize: '15px' } },
|
||||||
|
row.composite_score.toFixed(1),
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '班级',
|
title: '班级',
|
||||||
key: 'class_name',
|
key: 'class_name',
|
||||||
@@ -980,7 +1002,7 @@ const radarChartOptions = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '前10名平均',
|
title: '前10%均值',
|
||||||
key: 'top_10_avg',
|
key: 'top_10_avg',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (row) =>
|
render: (row) =>
|
||||||
@@ -991,7 +1013,18 @@ const radarChartOptions = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '后10名平均',
|
title: '中间80%均值',
|
||||||
|
key: 'middle_80_avg',
|
||||||
|
width: 110,
|
||||||
|
render: (row) =>
|
||||||
|
h(
|
||||||
|
'span',
|
||||||
|
{ style: { color: '#389e0d', fontWeight: '600' } },
|
||||||
|
row.middle_80_avg.toFixed(2),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '后10%均值',
|
||||||
key: 'bottom_10_avg',
|
key: 'bottom_10_avg',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (row) =>
|
render: (row) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user