171 lines
5.1 KiB
Vue
171 lines
5.1 KiB
Vue
<route lang="json">
|
||
{"meta":{
|
||
"title":"COSMIC",
|
||
"description":"行星波提取",
|
||
"group":"COSMIC",
|
||
"item_name":"行星波提取"
|
||
}}
|
||
</route>
|
||
|
||
<script setup lang="ts">
|
||
import {
|
||
CalendarDate,
|
||
createCalendar,
|
||
DateFormatter,
|
||
type DateValue,
|
||
getLocalTimeZone,
|
||
toCalendar,
|
||
} from '@internationalized/date'
|
||
import DenseFramework from '~/components/DenseFramework.vue'
|
||
import { cn } from '~/lib/utils'
|
||
|
||
const selectedT = ref<'5' | '10' | '16'>('5')
|
||
const selectedH = ref(50)
|
||
const selectedRange = ref('-30')
|
||
const selectedYear = ref('2008')
|
||
const ranges = ['-30', '-60', '30', '60']
|
||
const df = new DateFormatter('zh-CN', {
|
||
dateStyle: 'long',
|
||
})
|
||
const ca = createCalendar('zh-CN')
|
||
const targetDate = ref<DateValue>()
|
||
|
||
function getDayOfYear(date: Date) {
|
||
const start = new Date(date.getFullYear(), 0, 0)
|
||
// @ts-expect-error date - start
|
||
const diff = date - start
|
||
const oneDay = 1000 * 60 * 60 * 24
|
||
return Math.floor(diff / oneDay)
|
||
}
|
||
|
||
watch(selectedYear, () => {
|
||
targetDate.value = toCalendar(
|
||
new CalendarDate(Number.parseInt(selectedYear.value), 1, 1),
|
||
ca,
|
||
).add({ days: Math.floor(Number.parseInt(selectedT.value) * 1.5) })
|
||
})
|
||
|
||
const minDateValue = computed(() => {
|
||
const currentYearBeginDate = new CalendarDate(Number.parseInt(selectedYear.value), 1, 1)
|
||
return toCalendar(currentYearBeginDate, ca).add({ days: Math.floor(Number.parseInt(selectedT.value) * 1.5) })
|
||
})
|
||
|
||
const maxDateValue = computed(() => {
|
||
const currentYearBeginDate = new CalendarDate(Number.parseInt(selectedYear.value) + 1, 1, 1)
|
||
return toCalendar(currentYearBeginDate, ca).subtract({ days: Math.floor(Number.parseInt(selectedT.value) * 1.5) })
|
||
})
|
||
|
||
onMounted(() => {
|
||
targetDate.value = toCalendar(
|
||
new CalendarDate(Number.parseInt(selectedYear.value), 1, 1),
|
||
ca,
|
||
).add({ days: Math.floor(Number.parseInt(selectedT.value) * 1.5) })
|
||
})
|
||
const fetchUrl = computed(() => {
|
||
const query = new URLSearchParams()
|
||
if (!targetDate.value) {
|
||
return ''
|
||
}
|
||
const targetDay = getDayOfYear(targetDate.value.toDate(getLocalTimeZone()))
|
||
const startDay = targetDay - Math.floor(1.5 * Number.parseInt(selectedT.value))
|
||
query.set('T', selectedT.value)
|
||
query.set('target_h', selectedH.value.toString())
|
||
query.set('target_lat', selectedRange.value)
|
||
query.set('year', selectedYear.value)
|
||
query.set('start_day', startDay.toString())
|
||
return `/cosmic/render/planet_wave/perday?${query}`
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<DenseFramework :image-query="fetchUrl">
|
||
<Label>年份</Label>
|
||
<Select v-model="selectedYear">
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="选择年份" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectGroup>
|
||
<SelectLabel>年份</SelectLabel>
|
||
<SelectItem v-for="year in ['2008']" :key="year" :value="year">
|
||
{{ year }}
|
||
</SelectItem>
|
||
</SelectGroup>
|
||
</SelectContent>
|
||
</Select>
|
||
<Label for="T_range">行星波周期</Label>
|
||
<Tabs id="T_range" v-model="selectedT" default-value="5">
|
||
<TabsList class="grid grid-cols-3 w-full">
|
||
<TabsTrigger value="5">
|
||
5日
|
||
</TabsTrigger>
|
||
<TabsTrigger value="10">
|
||
10日
|
||
</TabsTrigger>
|
||
<TabsTrigger value="16">
|
||
16日
|
||
</TabsTrigger>
|
||
</TabsList>
|
||
</Tabs>
|
||
<!-- TODO: not implemented -->
|
||
<Label>高度(km)</Label>
|
||
<NumberField
|
||
id="start"
|
||
v-model:model-value="selectedH" :format-options="{
|
||
useGrouping: false,
|
||
}" :default-value="60"
|
||
:step="10"
|
||
:max="60"
|
||
:min="0"
|
||
>
|
||
<NumberFieldContent>
|
||
<NumberFieldDecrement />
|
||
<NumberFieldInput />
|
||
<NumberFieldIncrement />
|
||
</NumberFieldContent>
|
||
</NumberField>
|
||
<Label>纬度带(°)</Label>
|
||
<Select v-model="selectedRange">
|
||
<SelectTrigger>
|
||
<SelectValue placeholder="选择纬度带" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectGroup>
|
||
<SelectLabel>纬度带(°)</SelectLabel>
|
||
<SelectItem v-for="range in ranges" :key="range" :value="range">
|
||
{{ range }}
|
||
</SelectItem>
|
||
</SelectGroup>
|
||
</SelectContent>
|
||
</Select>
|
||
<Label>日期</Label>
|
||
<Popover>
|
||
<PopoverTrigger as-child>
|
||
<Button
|
||
variant="outline"
|
||
:class="cn(
|
||
'w-full justify-start text-left font-normal',
|
||
!targetDate && 'text-muted-foreground',
|
||
)"
|
||
>
|
||
<span i-md-calendar />
|
||
{{ targetDate ? df.format(targetDate.toDate(getLocalTimeZone())) : "选择日期" }}
|
||
</Button>
|
||
</PopoverTrigger>
|
||
<PopoverContent class="w-auto p-0">
|
||
<!-- @ts-expect-error dsa -->
|
||
<Calendar
|
||
v-model="targetDate " initial-focus
|
||
:is-date-disabled="(date:DateValue) => date < minDateValue || date > maxDateValue"
|
||
:prevent-deselect="true"
|
||
/>
|
||
</PopoverContent>
|
||
</Popover>
|
||
<div>
|
||
拟合起始日期 {{ targetDate?.subtract({ days: Math.floor(1.5 * Number.parseInt(selectedT)) }) }}
|
||
<br>
|
||
拟合结束日期 {{ targetDate?.add({ days: Math.floor(1.5 * Number.parseInt(selectedT)) }) }}
|
||
</div>
|
||
</DenseFramework>
|
||
</template>
|