add heatmap
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
2025-09-25 15:25:47 +08:00
parent 0b28dbeef8
commit 4429e2f018
7 changed files with 64 additions and 17 deletions

View File

@@ -15,6 +15,7 @@
</n-gi>
<n-gi :span="3">
<n-flex vertical size="large">
<Heatmap />
<WeeklyChart :end="end" />
<AI v-if="aiStore.detailsData.solved.length" />
</n-flex>
@@ -26,9 +27,9 @@ import { isDesktop } from "~/shared/composables/breakpoints"
import { formatISO, sub, type Duration } from "date-fns"
import WeeklyChart from "./components/WeeklyChart.vue"
import Details from "./components/Details.vue"
import Heatmap from "./components/Heatmap.vue"
import AI from "./components/AI.vue"
import { useAIStore } from "../store/ai"
const aiStore = useAIStore()
const start = ref("")

View File

@@ -7,7 +7,7 @@
v-if="aiStore.detailsData.solved.length"
>
<span>{{ durationLabel }}</span>
<span>{{ aiStore.theFirstPerson }}一共解决 </span>
<span>一共解决 </span>
<b class="charming"> {{ aiStore.detailsData.solved.length }} </b>
<span> 道题</span>
<span v-if="aiStore.detailsData.contest_count > 0">
@@ -20,16 +20,17 @@
<span>{{ greeting }}</span>
</n-alert>
<n-flex vertical size="large" v-else>
<n-alert
type="error"
:title="aiStore.theFirstPerson + '还没有完成任何题目'"
></n-alert>
<n-alert type="error" title="你还没有完成任何题目"></n-alert>
<AI />
</n-flex>
<n-flex>
<TagsChart :tags="aiStore.detailsData.tags" />
<DifficultyChart :difficulty="aiStore.detailsData.difficulty" />
</n-flex>
<n-grid :cols="isDesktop ? 2 : 1" :x-gap="10" :y-gap="10">
<n-gi>
<TagsChart :tags="aiStore.detailsData.tags" />
</n-gi>
<n-gi>
<DifficultyChart :difficulty="aiStore.detailsData.difficulty" />
</n-gi>
</n-grid>
<n-data-table
v-if="aiStore.detailsData.solved.length"
striped
@@ -49,6 +50,7 @@ import AI from "./AI.vue"
import { parseTime } from "~/utils/functions"
import { SolvedProblem } from "~/utils/types"
import { useAIStore } from "~/oj/store/ai"
import { isDesktop } from "~/shared/composables/breakpoints"
const props = defineProps<{
start: string

View File

@@ -52,7 +52,7 @@ const options = {
</script>
<style scoped>
.chart {
height: 300px;
width: 300px;
height: 100%;
width: 100%;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div class="chart">
<n-h1 class="title">过去一年的提交次数热力图</n-h1>
<n-heatmap
:loading="!data.length"
:color-theme="getRandomColorTheme()"
size="large"
:data="data"
:tooltip="{ placement: 'top' }"
>
<template #tooltip="{ timestamp, value }">
<div>{{ new Date(timestamp).toLocaleDateString() }}</div>
<div>提交次数: {{ value }}</div>
</template>
</n-heatmap>
</div>
</template>
<script setup lang="ts">
import { type HeatmapData } from "naive-ui"
import { getAIHeatmapData } from "~/oj/api"
const data = ref<HeatmapData>([])
function getRandomColorTheme() {
const themes = ["green", "blue", "orange", "purple", "red"] as const
return themes[Math.floor(Math.random() * themes.length)]
}
onMounted(async () => {
const res = await getAIHeatmapData()
data.value = res.data
})
</script>
<style scoped>
.chart {
margin: 0 auto;
}
.title {
text-align: center;
font-size: 20px;
font-weight: bold;
}
</style>

View File

@@ -51,7 +51,7 @@ const options = computed(() => {
</script>
<style scoped>
.chart {
height: 300px;
width: 300px;
height: 100%;
width: 100%;
}
</style>

View File

@@ -255,3 +255,7 @@ export function getAIWeeklyData(
) {
return http.get("ai/weekly", { params: { end, duration } })
}
export function getAIHeatmapData() {
return http.get("ai/heatmap")
}

View File

@@ -25,8 +25,6 @@ export const useAIStore = defineStore("ai", () => {
const mdContent = ref("")
const theFirstPerson = "你"
async function fetchDetailsData(
start: string,
end: string,
@@ -140,7 +138,6 @@ export const useAIStore = defineStore("ai", () => {
weeklyData,
detailsData,
duration,
theFirstPerson,
loading,
mdContent,
}