Sink/app/components/dashboard/analysis/metrics/Locations.vue
ccbikai 70d6632fd0 refactor: remove redundant watcher cleanup in Vue comps
Removes unnecessary manual watcher cleanup via stopWatchQueryChange across multiple Vue components.

Vue 3's watch() automatically handles cleanup when components are unmounted, making explicit stopWatchQueryChange calls and onBeforeUnmount handlers redundant.

This change:
- Improves code maintainability
- Reduces boilerplate code
- Follows Vue 3 best practices for reactive system cleanup
2025-05-18 19:13:04 +08:00

87 lines
2.1 KiB
Vue

<script setup>
import { ChartTooltip } from '@/components/ui/chart'
import { VisSingleContainer, VisTopoJSONMap, VisTopoJSONMapSelectors } from '@unovis/vue'
const id = inject('id')
const time = inject('time')
const filters = inject('filters')
const worldMapTopoJSON = ref({})
const areaData = ref([])
async function getWorldMapJSON() {
const data = await $fetch('/world.json')
worldMapTopoJSON.value = data
}
async function getMapData() {
areaData.value = []
const { data } = await useAPI('/api/stats/metrics', {
query: {
type: 'country',
id: id.value,
startAt: time.value.startAt,
endAt: time.value.endAt,
...filters.value,
},
})
if (Array.isArray(data)) {
areaData.value = data.map((country) => {
country.id = country.name
return country
})
}
}
watch([time, filters], getMapData, {
deep: true,
})
onMounted(() => {
getWorldMapJSON()
getMapData()
})
const valueFormatter = v => v
const Tooltip = {
props: ['title', 'data'],
setup(props) {
const title = props.data[1]?.value?.name
const data = [{
name: props.title,
value: props.data[3]?.value?.count,
color: 'black',
}]
return () => h(ChartTooltip, { title, data })
},
}
</script>
<template>
<Card class="flex flex-col md:h-[500px]">
<CardHeader>
<CardTitle>{{ $t('dashboard.locations') }}</CardTitle>
</CardHeader>
<CardContent class="flex-1 flex [&_[data-radix-aspect-ratio-wrapper]]:flex-1">
<AspectRatio :ratio="65 / 30">
<VisSingleContainer
v-if="worldMapTopoJSON.type"
:data="{ areas: areaData }"
class="h-full"
>
<VisTopoJSONMap
:topojson="worldMapTopoJSON"
map-feature-name="countries"
/>
<ChartSingleTooltip
index="id"
:selector="VisTopoJSONMapSelectors.feature"
:items="areaData"
:value-formatter="valueFormatter"
:custom-tooltip="Tooltip"
/>
</VisSingleContainer>
</AspectRatio>
</CardContent>
</Card>
</template>