Sink/app/components/dashboard/analysis/Views.vue
ccbikai 2bbb905ac8 perf: optimize dashboard components and lazy loading
Enhances dashboard performance through strategic component optimizations:

- Removes redundant v-if condition from chart component
- Implements lazy loading for the resource-intensive globe component
- Bumps package version to 0.1.12

These changes improve initial load time and runtime performance while maintaining functionality.
2025-05-20 21:46:49 +08:00

90 lines
2.1 KiB
Vue

<script setup>
import { AreaChart } from '@/components/ui/chart-area'
import { BarChart } from '@/components/ui/chart-bar'
const props = defineProps({
mode: {
type: String,
default: 'full',
},
chartType: {
type: String,
default: 'area',
},
})
const views = ref([])
const chart = computed(() => (props.chartType === 'area' && views.value.length > 1) ? AreaChart : BarChart)
const id = inject('id')
const time = inject('time')
const filters = inject('filters')
const OneHour = 60 * 60 // 1 hour in seconds
const OneDay = 24 * 60 * 60 // 1 day in seconds
function getUnit(startAt, endAt) {
if (startAt && endAt && endAt - startAt <= OneHour)
return 'minute'
if (startAt && endAt && endAt - startAt <= OneDay)
return 'hour'
return 'day'
}
async function getLinkViews() {
views.value = []
const { data } = await useAPI('/api/stats/views', {
query: {
id: id.value,
unit: getUnit(time.value.startAt, time.value.endAt),
clientTimezone: getTimeZone(),
startAt: time.value.startAt,
endAt: time.value.endAt,
...filters.value,
},
})
views.value = (data || []).map((item) => {
item.visitors = +item.visitors
item.visits = +item.visits
return item
})
}
watch([time, filters], getLinkViews, {
deep: true,
})
onMounted(async () => {
getLinkViews()
})
function formatTime(tick) {
if (Number.isInteger(tick) && views.value[tick]) {
if (getUnit(time.value.startAt, time.value.endAt) === 'hour')
return views.value[tick].time.split(' ')[1] || ''
return views.value[tick].time
}
return ''
}
</script>
<template>
<Card class="px-0 py-6 md:px-6">
<CardTitle v-if="mode === 'full'" class="px-6 md:px-0">
{{ $t('dashboard.views') }}
</CardTitle>
<component
:is="chart"
class="w-full h-full"
index="time"
:data="views"
:categories="mode === 'full' ? ['visits', 'visitors'] : ['visits']"
:x-formatter="formatTime"
:y-formatter="formatNumber"
:show-grid-line="mode === 'full'"
:show-legend="mode === 'full'"
/>
</Card>
</template>