Skip to content

Commit

Permalink
feat: add charts on endless challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
Baiqiang committed Oct 27, 2024
1 parent d6a9d23 commit e2b56b1
Show file tree
Hide file tree
Showing 11 changed files with 582 additions and 177 deletions.
3 changes: 3 additions & 0 deletions components/chart.client.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<apexchart />
</template>
2 changes: 1 addition & 1 deletion components/competition/form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ function getTmpURL(file: File) {
<FormInput
v-model="form.solution"
type="textarea"
:rows="4"
:rows="6"
:label="$t('weekly.solution.label') + (solutionSubmitted ? $t('weekly.submitted') : '')"
:state="solutionState"
:attrs="{ required: true, disabled: solutionDisabled }"
Expand Down
4 changes: 0 additions & 4 deletions components/endless/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ const { data } = await useApi<Endless[]>('/endless/on-going')
const { data: data2 } = await useApi<Endless[]>('/endless/ended')
const endlesses = ref<Endless[]>(data.value || [])
const endedEndlesses = ref<Endless[]>(data2.value || [])
const { t } = useI18n()
useSeoMeta({
title: t('endless.title'),
})
</script>

<template>
Expand Down
134 changes: 133 additions & 1 deletion components/endless/stat/personal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const props = defineProps<{
endless: Endless
}>()
const { data } = await useApi<{ submissions: Submission[] }>(`/endless/${props.endless.alias}/user-stats`)
const { t, locale } = useI18n()
const user = useUser()
interface PersonalResult {
level: number
Expand Down Expand Up @@ -120,6 +122,130 @@ const currentCell = reactive({
type: 0,
index: -1,
})
const lineOptions = computed(() => {
return {
chart: {
height: 350,
type: 'line',
events: {
beforeZoom(ctx: any) {
ctx.w.config.xaxis.range = undefined
},
},
},
stroke: {
width: 2,
},
title: {
text: `${localeName(user.name, locale.value)} - ${props.endless.name}`,
},
tooltip: {
followCursor: true,
},
grid: {
row: {
colors: ['#f3f3f3', 'transparent'],
opacity: 0.5,
},
},
xaxis: {
categories: stats.value.results.map(r => r.level).reverse(),
range: 30,
},
yaxis: {
labels: {
formatter(value: number, { seriesIndex }: { seriesIndex: number }) {
if (seriesIndex === 0 || seriesIndex === undefined)
return value
return value?.toFixed(2)
},
},
min: Math.min(...stats.value.results.map(r => r.moves / 100)) - 1,
max: Math.max(...stats.value.results.map(r => r.moves / 100)) + 1,
stepSize: 1,
},
}
})
const lineSeries = computed(() => {
return [
{
name: t('endless.stats.moves'),
data: stats.value.results.map(r => formatResult(r.moves)).reverse(),
},
{
name: 'Mo3',
data: stats.value.results.map(r => Number.isNaN(r.mo3) ? null : formatResult(r.mo3, 2)).reverse(),
},
{
name: 'Ao5',
data: stats.value.results.map(r => Number.isNaN(r.ao5) ? null : formatResult(r.ao5, 2)).reverse(),
},
{
name: 'Ao12',
data: stats.value.results.map(r => Number.isNaN(r.ao12) ? null : formatResult(r.ao12, 2)).reverse(),
},
{
name: t('result.mean'),
data: stats.value.results.map(r => formatResult(r.mean, 2)).reverse(),
},
]
})
const barOptions = computed(() => {
return {
chart: {
height: 350,
type: 'bar',
stacked: true,
zoom: {
enabled: false,
},
},
plotOptions: {
bar: {
dataLabels: {
total: {
enabled: true,
style: {
// fontSize: '16px',
// fontWeight: 600,
},
},
},
},
},
tooltip: {
shared: true,
intersect: false,
followCursor: true,
},
title: {
text: `${localeName(user.name, locale.value)} - ${props.endless.name}`,
},
xaxis: {
categories: stats.value.movesCount.map(m => formatResult(m.moves)),
},
yaxis: {
labels: {
formatter(value: number) {
return value.toFixed(0)
},
},
},
}
})
const barSeries = computed(() => {
return [
{
name: t('endless.stats.count'),
data: stats.value.movesCount.map(m => m.count),
},
{
name: t('weekly.unlimited.label'),
data: stats.value.movesCount.map(m => m.unlimited),
},
]
})
function enterCell(type: number, index: number) {
currentCell.type = type
Expand Down Expand Up @@ -196,7 +322,7 @@ function getClass(value: number, best: number, worst: number, unlimited = false)
<template>
<div class="mt-4">
<h4 class="font-bold mb-2">
{{ $t(`endless.stats.personal`) }}
{{ $t('endless.stats.personal') }}
</h4>
<div class="grid auto-cols-max gap-x-2 gap-y-0 text-center">
<div class="grid grid-cols-subgrid col-span-6 font-bold bg-gray-200 py-1">
Expand Down Expand Up @@ -240,6 +366,9 @@ function getClass(value: number, best: number, worst: number, unlimited = false)
</div>
</div>
</div>
<div>
<Chart :options="lineOptions" :series="lineSeries" />
</div>
<div class="grid auto-cols-max gap-x-2 gap-y-0 text-center mt-4">
<div class="grid grid-cols-subgrid col-span-3 font-bold bg-gray-200 py-1">
<div class="px-2">
Expand All @@ -264,6 +393,9 @@ function getClass(value: number, best: number, worst: number, unlimited = false)
</div>
</div>
</div>
<div>
<Chart :options="barOptions" :series="barSeries" />
</div>
</div>
</template>

Expand Down
9 changes: 9 additions & 0 deletions declarations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {
ComponentCustomOptions as _ComponentCustomOptions,
ComponentCustomProperties as _ComponentCustomProperties,
} from 'vue'

declare module '@vue/runtime-core' {
interface ComponentCustomProperties extends _ComponentCustomProperties {}
interface ComponentCustomOptions extends _ComponentCustomOptions {}
}
1 change: 1 addition & 0 deletions messages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export default {
personal: 'Personal Stats',
moves: 'Moves',
count: 'Count',
level: 'Level',
},
openAt: 'Open at {time}.',
kickedAt: 'Kicked at {time}.',
Expand Down
1 change: 1 addition & 0 deletions messages/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export default {
personal: '个人统计',
moves: '步数',
count: '次数',
level: '层数',
},
openAt: '{time}开放。',
kickedAt: '{time}破关。',
Expand Down
74 changes: 44 additions & 30 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ export default defineNuxtConfig({
titleTemplate: '%s - Fewest Moves',
},
},

runtimeConfig: {
public: {
mode: 'production',
baseURL: 'https://api.333.fm/',
},
},

modules: [
// '@nuxtjs/eslint-module',
'@nuxtjs/tailwindcss',
Expand All @@ -22,43 +24,47 @@ export default defineNuxtConfig({
'@pinia-plugin-persistedstate/nuxt',
'@freeloop/nuxt-transitions',
'dayjs-nuxt',
'nuxt-gtag',
'@vite-pwa/nuxt',
process.env.NODE_ENV === 'development'
? ['@vite-pwa/nuxt', {
registerType: 'autoUpdate',
manifest: {
name: '333.fm',
short_name: '333.fm',
theme_color: '#6366f1',
display: 'standalone',
icons: [
{
src: 'logo.svg',
sizes: '72x72 96x96 128x128 144x144 152x152 192x192 384x384 512x512',
type: 'image/svg+xml',
},
],
},
workbox: {
globPatterns: ['**/*.{js,css,html,png,svg,ico}'],
},
client: {
installPrompt: true,
},
devOptions: {
enabled: true,
suppressWarnings: true,
navigateFallbackAllowlist: [/^\/$/],
type: 'module',
},
}]
: undefined,
],

css: ['viewerjs/dist/viewer.css'],
pwa: {
registerType: 'autoUpdate',
manifest: {
name: '333.fm',
short_name: '333.fm',
theme_color: '#6366f1',
display: 'standalone',
icons: [
{
src: 'logo.svg',
sizes: '72x72 96x96 128x128 144x144 152x152 192x192 384x384 512x512',
type: 'image/svg+xml',
},
],
},
workbox: {
globPatterns: ['**/*.{js,css,html,png,svg,ico}'],
},
client: {
installPrompt: true,
},
devOptions: {
enabled: true,
suppressWarnings: true,
navigateFallbackAllowlist: [/^\/$/],
type: 'module',
},
},

dayjs: {
locales: ['en', 'zh-cn'],
defaultLocale: 'en',
plugins: ['relativeTime', 'utc', 'timezone', 'advancedFormat', 'weekOfYear', 'localizedFormat'],
},

i18n: {
strategy: 'no_prefix',
detectBrowserLanguage: {
Expand All @@ -76,22 +82,26 @@ export default defineNuxtConfig({
},
],
},

googleFonts: {
download: true,
families: {
Poppins: [400, 600],
Inter: [300, 400, 500, 600],
},
},

gtag: {
id: 'G-4DDRHC6TDB',
},

experimental: {
asyncContext: true,
headNext: true,
// disable this to run in QQ browser for iOS
appManifest: false,
},

$development: {
vite: {
server: {
Expand All @@ -102,10 +112,14 @@ export default defineNuxtConfig({
},
},
},

devtools: {
enabled: true,
},

typescript: {
shim: false,
},
})

compatibilityDate: '2024-10-26',
})
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@
"lint:fix": "eslint . --fix"
},
"dependencies": {
"apexcharts": "^3.54.1",
"insertionfinder": "^0.5.0",
"tailwind-merge": "^2.5.3",
"tailwind-merge": "^2.5.4",
"three": "^0.169.0",
"two.js": "^0.8.14",
"v-viewer": "^3.0.20",
"viewerjs": "^1.11.6",
"vue": "^3.5.11",
"vue-router": "^4.4.5"
"vue": "^3.5.12",
"vue-router": "^4.4.5",
"vue3-apexcharts": "^1.7.0"
},
"devDependencies": {
"@antfu/eslint-config": "^3.7.3",
"@antfu/eslint-config": "^3.8.0",
"@freeloop/nuxt-transitions": "^0.1.8",
"@nuxt/devtools": "latest",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"@nuxtjs/eslint-module": "^4.1.0",
"@nuxtjs/google-fonts": "^3.2.0",
"@nuxtjs/i18n": "^8.5.5",
"@nuxtjs/tailwindcss": "^6.12.1",
"@nuxtjs/tailwindcss": "^6.12.2",
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
"@pinia/nuxt": "^0.5.5",
"@tailwindcss/forms": "^0.5.9",
Expand All @@ -39,7 +41,7 @@
"@vueuse/core": "^11.1.0",
"@vueuse/nuxt": "^11.1.0",
"dayjs-nuxt": "^2.1.11",
"eslint": "^9.12.0",
"eslint": "^9.13.0",
"less": "^4.2.0",
"nuxt": "^3.13.2",
"nuxt-gtag": "^3.0.1",
Expand Down
Loading

0 comments on commit e2b56b1

Please sign in to comment.