add charts.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { DIFFICULTY } from "utils/constants"
|
||||
import { Pie } from "vue-chartjs"
|
||||
import { DIFFICULTY, JUDGE_STATUS } from "utils/constants"
|
||||
import { getACRate, getTagColor, parseTime } from "utils/functions"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
import { Problem } from "utils/types"
|
||||
@@ -7,7 +8,30 @@ import { Problem } from "utils/types"
|
||||
interface Props {
|
||||
problem: Problem
|
||||
}
|
||||
defineProps<Props>()
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const data = computed(() => {
|
||||
const status = props.problem.statistic_info
|
||||
const labels = []
|
||||
for (let i in status) {
|
||||
if (status[i] === 0) {
|
||||
delete status[i]
|
||||
}
|
||||
// @ts-ignore
|
||||
labels.push(JUDGE_STATUS[i]["name"])
|
||||
}
|
||||
return {
|
||||
labels,
|
||||
datasets: [{ data: Object.values(status), hoverOffset: 4 }],
|
||||
}
|
||||
})
|
||||
|
||||
const options = ref({
|
||||
responsive: true,
|
||||
plugins: {
|
||||
title: { text: "提交结果的比例", display: true, font: { size: 20 } },
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -49,4 +73,14 @@ defineProps<Props>()
|
||||
</n-space>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
<div class="pie">
|
||||
<Pie :data="data" :options="options" />
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.pie {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
88
src/oj/rank/components/Chart.vue
Normal file
88
src/oj/rank/components/Chart.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import { Bar } from "vue-chartjs"
|
||||
import { Rank } from "~/utils/types"
|
||||
|
||||
const props = defineProps<{ rankData: Rank[] }>()
|
||||
|
||||
const data = computed(() => ({
|
||||
labels: props.rankData.map((rank) => rank.user.username),
|
||||
datasets: [
|
||||
{
|
||||
label: "已解决",
|
||||
data: props.rankData.map((rank) => rank.accepted_number),
|
||||
backgroundColor: [
|
||||
"rgba(255, 99, 132, 0.2)",
|
||||
"rgba(255, 159, 64, 0.2)",
|
||||
"rgba(55, 66, 250, 0.2)",
|
||||
"rgba(75, 192, 192, 0.2)",
|
||||
"rgba(54, 162, 235, 0.2)",
|
||||
"rgba(153, 102, 255, 0.2)",
|
||||
"rgba(48, 51, 107, 0.2)",
|
||||
"rgba(249, 202, 36, 0.2)",
|
||||
"rgba(106, 176, 76, 0.2)",
|
||||
"rgba(119, 139, 235, 0.2)",
|
||||
],
|
||||
borderColor: [
|
||||
"rgba(255, 99, 132, 0.6)",
|
||||
"rgba(255, 159, 64, 0.6)",
|
||||
"rgba(55, 66, 250, 0.6)",
|
||||
"rgba(75, 192, 192, 0.6)",
|
||||
"rgba(54, 162, 235, 0.6)",
|
||||
"rgba(153, 102, 255, 0.6)",
|
||||
"rgba(48, 51, 107, 0.6)",
|
||||
"rgba(249, 202, 36, 0.6)",
|
||||
"rgba(106, 176, 76, 0.6)",
|
||||
"rgba(119, 139, 235, 0.6)",
|
||||
],
|
||||
hoverBackgroundColor: [
|
||||
"rgba(255, 99, 132, 0.8)",
|
||||
"rgba(255, 159, 64, 0.8)",
|
||||
"rgba(55, 66, 250, 0.8)",
|
||||
"rgba(75, 192, 192, 0.8)",
|
||||
"rgba(54, 162, 235, 0.8)",
|
||||
"rgba(153, 102, 255, 0.8)",
|
||||
"rgba(48, 51, 107, 0.8)",
|
||||
"rgba(249, 202, 36, 0.8)",
|
||||
"rgba(106, 176, 76, 0.8)",
|
||||
"rgba(119, 139, 235, 0.8)",
|
||||
],
|
||||
hoverBorderColor: [
|
||||
"rgba(255, 99, 132, 1)",
|
||||
"rgba(255, 159, 64, 1)",
|
||||
"rgba(55, 66, 250, 1)",
|
||||
"rgba(75, 192, 192, 1)",
|
||||
"rgba(54, 162, 235, 1)",
|
||||
"rgba(153, 102, 255, 1)",
|
||||
"rgba(48, 51, 107, 1)",
|
||||
"rgba(249, 202, 36, 1)",
|
||||
"rgba(106, 176, 76, 1)",
|
||||
"rgba(119, 139, 235, 1)",
|
||||
],
|
||||
borderWidth: 2,
|
||||
},
|
||||
{
|
||||
label: "总提交数",
|
||||
data: props.rankData.map((rank) => rank.submission_number),
|
||||
hidden: true,
|
||||
},
|
||||
],
|
||||
}))
|
||||
|
||||
const options = ref({
|
||||
plugins: {
|
||||
title: {
|
||||
text: "全校前十名的提交者(不包括超管)",
|
||||
display: true,
|
||||
font: { size: 20 },
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<Bar class="chart" :data="data" :options="options" />
|
||||
</template>
|
||||
<style scoped>
|
||||
.chart {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { DataTableColumn, NButton, NButtonGroup } from "naive-ui"
|
||||
import { DataTableColumn, NButton } from "naive-ui"
|
||||
import Chart from "./components/Chart.vue"
|
||||
import Pagination from "~/shared/Pagination.vue"
|
||||
import { Rank } from "utils/types"
|
||||
import { getRank } from "oj/api"
|
||||
@@ -11,13 +12,18 @@ const query = reactive({
|
||||
limit: 10,
|
||||
page: 1,
|
||||
})
|
||||
const rankData = ref<Rank[]>([])
|
||||
|
||||
async function listRanks() {
|
||||
const offset = (query.page - 1) * query.limit
|
||||
const res = await getRank(offset, query.limit)
|
||||
data.value = res.data.results
|
||||
total.value = res.data.total
|
||||
if (query.page === 1) {
|
||||
rankData.value = data.value
|
||||
}
|
||||
}
|
||||
|
||||
const columns: DataTableColumn<Rank>[] = [
|
||||
{
|
||||
title: "排名",
|
||||
@@ -61,6 +67,7 @@ onMounted(listRanks)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Chart v-if="!!rankData.length" :rankData="rankData" />
|
||||
<n-data-table striped size="small" :data="data" :columns="columns" />
|
||||
<Pagination
|
||||
:total="total"
|
||||
|
||||
Reference in New Issue
Block a user