fmt
This commit is contained in:
@@ -142,4 +142,3 @@ const options = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card :title="title" size="small">
|
<n-card :title="title" size="small">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px"> 全面评估学习情况 </n-text>
|
||||||
全面评估学习情况
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<Chart type="bar" :data="data" :options="options" />
|
<Chart type="bar" :data="data" :options="options" />
|
||||||
@@ -173,11 +171,20 @@ const options = computed<ChartOptions<"bar" | "line">>(() => {
|
|||||||
return `${dsLabel}: ${ctx.formattedValue}`
|
return `${dsLabel}: ${ctx.formattedValue}`
|
||||||
},
|
},
|
||||||
footer: (items: TooltipItem<"bar">[]) => {
|
footer: (items: TooltipItem<"bar">[]) => {
|
||||||
const barItems = items.filter(item => (item.dataset as any).yAxisID === "y")
|
const barItems = items.filter(
|
||||||
|
(item) => (item.dataset as any).yAxisID === "y",
|
||||||
|
)
|
||||||
if (barItems.length >= 2) {
|
if (barItems.length >= 2) {
|
||||||
const problemCount = barItems.find(item => item.dataset.label === "完成题目数")?.parsed.y || 0
|
const problemCount =
|
||||||
const submissionCount = barItems.find(item => item.dataset.label === "总提交次数")?.parsed.y || 0
|
barItems.find((item) => item.dataset.label === "完成题目数")
|
||||||
const efficiency = submissionCount > 0 ? ((problemCount / submissionCount) * 100).toFixed(1) : "0"
|
?.parsed.y || 0
|
||||||
|
const submissionCount =
|
||||||
|
barItems.find((item) => item.dataset.label === "总提交次数")
|
||||||
|
?.parsed.y || 0
|
||||||
|
const efficiency =
|
||||||
|
submissionCount > 0
|
||||||
|
? ((problemCount / submissionCount) * 100).toFixed(1)
|
||||||
|
: "0"
|
||||||
return `AC率: ${efficiency}%`
|
return `AC率: ${efficiency}%`
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card :title="title" size="small" v-if="show">
|
<n-card :title="title" size="small" v-if="show">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">反映刷题质量提升</n-text>
|
||||||
反映刷题质量提升
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<Chart type="line" :data="data" :options="options" />
|
<Chart type="line" :data="data" :options="options" />
|
||||||
@@ -69,7 +67,8 @@ const efficiencyData = computed(() => {
|
|||||||
const efficiency = problemCount > 0 ? submissionCount / problemCount : 0
|
const efficiency = problemCount > 0 ? submissionCount / problemCount : 0
|
||||||
|
|
||||||
// 计算一次AC率(百分比)
|
// 计算一次AC率(百分比)
|
||||||
const onePassRate = problemCount > 0 ? (problemCount / submissionCount) * 100 : 0
|
const onePassRate =
|
||||||
|
problemCount > 0 ? (problemCount / submissionCount) * 100 : 0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: [
|
label: [
|
||||||
@@ -233,4 +232,3 @@ const options = computed<ChartOptions<"line">>(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card title="过去一年的提交热力图" size="small">
|
<n-card title="过去一年的提交热力图" size="small">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">激励持续学习</n-text>
|
||||||
激励持续学习
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<n-spin :show="aiStore.loading.heatmap">
|
<n-spin :show="aiStore.loading.heatmap">
|
||||||
<div class="heatmap-container" ref="containerRef">
|
<div class="heatmap-container" ref="containerRef">
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card :title="title" size="small" v-if="show">
|
<n-card :title="title" size="small" v-if="show">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">追踪学习成长轨迹</n-text>
|
||||||
追踪学习成长轨迹
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<Chart type="line" :data="data" :options="options" />
|
<Chart type="line" :data="data" :options="options" />
|
||||||
@@ -87,7 +85,8 @@ const progressData = computed(() => {
|
|||||||
totalProblems += problemCount
|
totalProblems += problemCount
|
||||||
|
|
||||||
// 计算累计平均等级
|
// 计算累计平均等级
|
||||||
const avgGradeValue = totalProblems > 0 ? totalWeightedGrade / totalProblems : 0
|
const avgGradeValue =
|
||||||
|
totalProblems > 0 ? totalWeightedGrade / totalProblems : 0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
label: [
|
label: [
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card title="解题排名分布" size="small" v-if="show">
|
<n-card title="解题排名分布" size="small" v-if="show">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">了解解题速度和竞争力</n-text>
|
||||||
了解解题速度和竞争力
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div style="height: 300px">
|
<div style="height: 300px">
|
||||||
<Pie :data="data" :options="options" />
|
<Pie :data="data" :options="options" />
|
||||||
@@ -13,13 +11,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Pie } from "vue-chartjs"
|
import { Pie } from "vue-chartjs"
|
||||||
import {
|
import { Chart as ChartJS, ArcElement, Title, Tooltip, Legend } from "chart.js"
|
||||||
Chart as ChartJS,
|
|
||||||
ArcElement,
|
|
||||||
Title,
|
|
||||||
Tooltip,
|
|
||||||
Legend,
|
|
||||||
} from "chart.js"
|
|
||||||
import { useAIStore } from "oj/store/ai"
|
import { useAIStore } from "oj/store/ai"
|
||||||
|
|
||||||
ChartJS.register(ArcElement, Title, Tooltip, Legend)
|
ChartJS.register(ArcElement, Title, Tooltip, Legend)
|
||||||
@@ -111,8 +103,12 @@ const options = {
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
label: (context: any) => {
|
label: (context: any) => {
|
||||||
const count = context.parsed
|
const count = context.parsed
|
||||||
const total = rankDistribution.value.reduce((sum, r) => sum + r.count, 0)
|
const total = rankDistribution.value.reduce(
|
||||||
const percentage = total > 0 ? ((count / total) * 100).toFixed(1) : "0.0"
|
(sum, r) => sum + r.count,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
const percentage =
|
||||||
|
total > 0 ? ((count / total) * 100).toFixed(1) : "0.0"
|
||||||
const label = context.label || ""
|
const label = context.label || ""
|
||||||
return `${label}: ${count} 道题 (${percentage}%)`
|
return `${label}: ${count} 道题 (${percentage}%)`
|
||||||
},
|
},
|
||||||
@@ -122,7 +118,10 @@ const options = {
|
|||||||
if (problems.length > 0 && problems.length <= 5) {
|
if (problems.length > 0 && problems.length <= 5) {
|
||||||
return problems
|
return problems
|
||||||
} else if (problems.length > 5) {
|
} else if (problems.length > 5) {
|
||||||
return [...problems.slice(0, 3), `... 还有 ${problems.length - 3} 道题`]
|
return [
|
||||||
|
...problems.slice(0, 3),
|
||||||
|
`... 还有 ${problems.length - 3} 道题`,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
},
|
},
|
||||||
@@ -131,4 +130,3 @@ const options = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card title="连续做题统计" size="small">
|
<n-card title="连续做题统计" size="small">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">激励持续学习</n-text>
|
||||||
激励持续学习
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<n-spin :show="aiStore.loading.heatmap">
|
<n-spin :show="aiStore.loading.heatmap">
|
||||||
<n-grid :cols="2" :x-gap="12" :y-gap="12">
|
<n-grid :cols="2" :x-gap="12" :y-gap="12">
|
||||||
@@ -11,7 +9,10 @@
|
|||||||
<n-statistic label="当前连续" :value="currentStreak">
|
<n-statistic label="当前连续" :value="currentStreak">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<span style="font-size: 14px">天</span>
|
<span style="font-size: 14px">天</span>
|
||||||
<span v-if="currentStreak > 0" style="font-size: 20px; margin-left: 4px">
|
<span
|
||||||
|
v-if="currentStreak > 0"
|
||||||
|
style="font-size: 20px; margin-left: 4px"
|
||||||
|
>
|
||||||
🔥
|
🔥
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -21,7 +22,10 @@
|
|||||||
<n-statistic label="最长连续" :value="maxStreak">
|
<n-statistic label="最长连续" :value="maxStreak">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<span style="font-size: 14px">天</span>
|
<span style="font-size: 14px">天</span>
|
||||||
<span v-if="maxStreak >= 7" style="font-size: 20px; margin-left: 4px">
|
<span
|
||||||
|
v-if="maxStreak >= 7"
|
||||||
|
style="font-size: 20px; margin-left: 4px"
|
||||||
|
>
|
||||||
⭐
|
⭐
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -45,12 +49,8 @@
|
|||||||
<n-divider style="margin: 12px 0" />
|
<n-divider style="margin: 12px 0" />
|
||||||
<n-flex vertical size="small">
|
<n-flex vertical size="small">
|
||||||
<n-text depth="2" style="font-size: 12px">
|
<n-text depth="2" style="font-size: 12px">
|
||||||
<span v-if="currentStreak === 0">
|
<span v-if="currentStreak === 0"> 开始做题,建立学习连续记录! </span>
|
||||||
开始做题,建立学习连续记录!
|
<span v-else-if="currentStreak < 3"> 继续保持,争取连续3天! </span>
|
||||||
</span>
|
|
||||||
<span v-else-if="currentStreak < 3">
|
|
||||||
继续保持,争取连续3天!
|
|
||||||
</span>
|
|
||||||
<span v-else-if="currentStreak < 7">
|
<span v-else-if="currentStreak < 7">
|
||||||
很棒!继续保持一周连续记录!
|
很棒!继续保持一周连续记录!
|
||||||
</span>
|
</span>
|
||||||
@@ -175,4 +175,3 @@ const maxStreak = computed(() => streakData.value.maxStreak)
|
|||||||
const weekCount = computed(() => streakData.value.weekCount)
|
const weekCount = computed(() => streakData.value.weekCount)
|
||||||
const monthCount = computed(() => streakData.value.monthCount)
|
const monthCount = computed(() => streakData.value.monthCount)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card :title="title" size="small" v-if="show">
|
<n-card :title="title" size="small" v-if="show">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">可视化知识点覆盖面</n-text>
|
||||||
可视化知识点覆盖面
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div class="chart">
|
<div class="chart">
|
||||||
<Radar :data="data" :options="options" />
|
<Radar :data="data" :options="options" />
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-card title="时间活跃度分析" size="small" v-if="show">
|
<n-card title="时间活跃度分析" size="small" v-if="show">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-text depth="3" style="font-size: 12px">
|
<n-text depth="3" style="font-size: 12px">发现最佳学习时段</n-text>
|
||||||
发现最佳学习时段
|
|
||||||
</n-text>
|
|
||||||
</template>
|
</template>
|
||||||
<div style="height: 300px">
|
<div style="height: 300px">
|
||||||
<Bar :data="data" :options="options" />
|
<Bar :data="data" :options="options" />
|
||||||
@@ -75,7 +73,9 @@ const data = computed(() => {
|
|||||||
const datasets = TIME_PERIODS.map((period, periodIndex) => {
|
const datasets = TIME_PERIODS.map((period, periodIndex) => {
|
||||||
return {
|
return {
|
||||||
label: period.label,
|
label: period.label,
|
||||||
data: WEEKDAYS.map((_, weekday) => activityMatrix.value[weekday][periodIndex]),
|
data: WEEKDAYS.map(
|
||||||
|
(_, weekday) => activityMatrix.value[weekday][periodIndex],
|
||||||
|
),
|
||||||
backgroundColor: getTimePeriodColor(periodIndex),
|
backgroundColor: getTimePeriodColor(periodIndex),
|
||||||
borderColor: getTimePeriodColor(periodIndex),
|
borderColor: getTimePeriodColor(periodIndex),
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
@@ -150,4 +150,3 @@ const options = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user