feat: new tidi stuff
This commit is contained in:
parent
a0569a41d0
commit
c2151b929a
7
components.d.ts
vendored
7
components.d.ts
vendored
@ -56,6 +56,13 @@ declare module 'vue' {
|
|||||||
CollapsibleTrigger: typeof import('./src/components/ui/collapsible/CollapsibleTrigger.vue')['default']
|
CollapsibleTrigger: typeof import('./src/components/ui/collapsible/CollapsibleTrigger.vue')['default']
|
||||||
CoolBack: typeof import('./src/components/CoolBack.vue')['default']
|
CoolBack: typeof import('./src/components/CoolBack.vue')['default']
|
||||||
DenseFramework: typeof import('./src/components/DenseFramework.vue')['default']
|
DenseFramework: typeof import('./src/components/DenseFramework.vue')['default']
|
||||||
|
Drawer: typeof import('./src/components/ui/drawer/Drawer.vue')['default']
|
||||||
|
DrawerContent: typeof import('./src/components/ui/drawer/DrawerContent.vue')['default']
|
||||||
|
DrawerDescription: typeof import('./src/components/ui/drawer/DrawerDescription.vue')['default']
|
||||||
|
DrawerFooter: typeof import('./src/components/ui/drawer/DrawerFooter.vue')['default']
|
||||||
|
DrawerHeader: typeof import('./src/components/ui/drawer/DrawerHeader.vue')['default']
|
||||||
|
DrawerOverlay: typeof import('./src/components/ui/drawer/DrawerOverlay.vue')['default']
|
||||||
|
DrawerTitle: typeof import('./src/components/ui/drawer/DrawerTitle.vue')['default']
|
||||||
DropdownMenu: typeof import('./src/components/ui/dropdown-menu/DropdownMenu.vue')['default']
|
DropdownMenu: typeof import('./src/components/ui/dropdown-menu/DropdownMenu.vue')['default']
|
||||||
DropdownMenuCheckboxItem: typeof import('./src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue')['default']
|
DropdownMenuCheckboxItem: typeof import('./src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue')['default']
|
||||||
DropdownMenuContent: typeof import('./src/components/ui/dropdown-menu/DropdownMenuContent.vue')['default']
|
DropdownMenuContent: typeof import('./src/components/ui/dropdown-menu/DropdownMenuContent.vue')['default']
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
"shadcn-vue": "^0.11.3",
|
"shadcn-vue": "^0.11.3",
|
||||||
"tailwind-merge": "^2.5.5",
|
"tailwind-merge": "^2.5.5",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"vaul-vue": "^0.2.0",
|
||||||
"vee-validate": "^4.15.0",
|
"vee-validate": "^4.15.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
|
|||||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@ -48,6 +48,9 @@ importers:
|
|||||||
tailwindcss-animate:
|
tailwindcss-animate:
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7
|
version: 1.0.7
|
||||||
|
vaul-vue:
|
||||||
|
specifier: ^0.2.0
|
||||||
|
version: 0.2.0(radix-vue@1.9.11(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3))
|
||||||
vee-validate:
|
vee-validate:
|
||||||
specifier: ^4.15.0
|
specifier: ^4.15.0
|
||||||
version: 4.15.0(vue@3.5.13(typescript@5.6.3))
|
version: 4.15.0(vue@3.5.13(typescript@5.6.3))
|
||||||
@ -3899,6 +3902,12 @@ packages:
|
|||||||
validate-npm-package-license@3.0.4:
|
validate-npm-package-license@3.0.4:
|
||||||
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
||||||
|
|
||||||
|
vaul-vue@0.2.0:
|
||||||
|
resolution: {integrity: sha512-YV0zqxc8NiVzr1z/Awwbaty0UDDchxj5BfhFbLiYu+Uz0rCfSaDK2zwmuXZvejBJKLGbWw9I5GLHJRse14lQew==}
|
||||||
|
peerDependencies:
|
||||||
|
radix-vue: ^1.4.0
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
vee-validate@4.15.0:
|
vee-validate@4.15.0:
|
||||||
resolution: {integrity: sha512-PGJh1QCFwCBjbHu5aN6vB8macYVWrajbDvgo1Y/8fz9n/RVIkLmZCJDpUgu7+mUmCOPMxeyq7vXUOhbwAqdXcA==}
|
resolution: {integrity: sha512-PGJh1QCFwCBjbHu5aN6vB8macYVWrajbDvgo1Y/8fz9n/RVIkLmZCJDpUgu7+mUmCOPMxeyq7vXUOhbwAqdXcA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -8610,6 +8619,14 @@ snapshots:
|
|||||||
spdx-correct: 3.2.0
|
spdx-correct: 3.2.0
|
||||||
spdx-expression-parse: 3.0.1
|
spdx-expression-parse: 3.0.1
|
||||||
|
|
||||||
|
vaul-vue@0.2.0(radix-vue@1.9.11(vue@3.5.13(typescript@5.6.3)))(vue@3.5.13(typescript@5.6.3)):
|
||||||
|
dependencies:
|
||||||
|
'@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.6.3))
|
||||||
|
radix-vue: 1.9.11(vue@3.5.13(typescript@5.6.3))
|
||||||
|
vue: 3.5.13(typescript@5.6.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
|
||||||
vee-validate@4.15.0(vue@3.5.13(typescript@5.6.3)):
|
vee-validate@4.15.0(vue@3.5.13(typescript@5.6.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/devtools-api': 7.7.0
|
'@vue/devtools-api': 7.7.0
|
||||||
|
|||||||
@ -122,9 +122,13 @@ const data = {
|
|||||||
isActive: true,
|
isActive: true,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
title: '行星波月统计',
|
title: '行星波振幅',
|
||||||
url: '/tidi/waves',
|
url: '/tidi/waves',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '行星波月统计',
|
||||||
|
url: '/tidi/month_stats',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,33 +3,32 @@ defineEmits(['submit', 'download'])
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Drawer>
|
<!-- <Drawer>
|
||||||
<DrawerTrigger as-child class="min-w-[20rem]">
|
<DrawerTrigger as-child class="min-w-[20rem]">
|
||||||
<Button variant="ghost" size="icon" class="md:hidden">
|
<Button variant="ghost" size="icon" class="md:hidden">
|
||||||
<Settings class="size-4" />
|
|
||||||
<span class="sr-only">参数设置</span>
|
<span class="sr-only">参数设置</span>
|
||||||
</Button>
|
</Button>
|
||||||
</DrawerTrigger>
|
</DrawerTrigger>
|
||||||
<DrawerContent class="max-h-[80vh]">
|
<DrawerContent class="max-h-[80vh]">
|
||||||
<DrawerHeader>
|
<DrawerHeader>
|
||||||
<DrawerTitle />
|
<DrawerTitle />
|
||||||
</DrawerHeader>
|
</DrawerHeader> -->
|
||||||
<form class="grid min-w-[20rem] w-full items-start gap-6 overflow-auto p-4 pt-0">
|
<form class="grid min-w-[20rem] w-full items-start gap-6 overflow-auto p-4 pt-0">
|
||||||
<fieldset class="grid gap-6 border rounded-lg p-4">
|
<fieldset class="grid gap-6 border rounded-lg p-4">
|
||||||
<legend class="px-1 text-sm font-medium -ml-1">
|
<legend class="px-1 text-sm font-medium -ml-1">
|
||||||
参数设置
|
参数设置
|
||||||
</legend>
|
</legend>
|
||||||
<div class="grid gap-3">
|
<div class="grid gap-3">
|
||||||
<slot />
|
<slot />
|
||||||
<Button type="submit" class="mt-5 w-full" @click.prevent="$emit('submit')">
|
<Button type="submit" class="mt-5 w-full" @click.prevent="$emit('submit')">
|
||||||
绘制
|
绘制
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit" class="mt-5 w-full" @click.prevent="$emit('download')">
|
<Button type="submit" class="mt-5 w-full" @click.prevent="$emit('download')">
|
||||||
下载
|
下载
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</DrawerContent>
|
<!-- </DrawerContent>
|
||||||
</Drawer>
|
</Drawer> -->
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
19
src/components/ui/drawer/Drawer.vue
Normal file
19
src/components/ui/drawer/Drawer.vue
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerRootEmits, DrawerRootProps } from 'vaul-vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { DrawerRoot } from 'vaul-vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<DrawerRootProps>(), {
|
||||||
|
shouldScaleBackground: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits<DrawerRootEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerRoot v-bind="forwarded">
|
||||||
|
<slot />
|
||||||
|
</DrawerRoot>
|
||||||
|
</template>
|
||||||
28
src/components/ui/drawer/DrawerContent.vue
Normal file
28
src/components/ui/drawer/DrawerContent.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DialogContentEmits, DialogContentProps } from 'radix-vue'
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { useForwardPropsEmits } from 'radix-vue'
|
||||||
|
import { DrawerContent, DrawerPortal } from 'vaul-vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
import DrawerOverlay from './DrawerOverlay.vue'
|
||||||
|
|
||||||
|
const props = defineProps<DialogContentProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
const emits = defineEmits<DialogContentEmits>()
|
||||||
|
|
||||||
|
const forwarded = useForwardPropsEmits(props, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerPortal>
|
||||||
|
<DrawerOverlay />
|
||||||
|
<DrawerContent
|
||||||
|
v-bind="forwarded" :class="cn(
|
||||||
|
'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
|
||||||
|
props.class,
|
||||||
|
)"
|
||||||
|
>
|
||||||
|
<div class="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
||||||
|
<slot />
|
||||||
|
</DrawerContent>
|
||||||
|
</DrawerPortal>
|
||||||
|
</template>
|
||||||
20
src/components/ui/drawer/DrawerDescription.vue
Normal file
20
src/components/ui/drawer/DrawerDescription.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerDescriptionProps } from 'vaul-vue'
|
||||||
|
import { DrawerDescription } from 'vaul-vue'
|
||||||
|
import { computed, type HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerDescriptionProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerDescription v-bind="delegatedProps" :class="cn('text-sm text-muted-foreground', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerDescription>
|
||||||
|
</template>
|
||||||
14
src/components/ui/drawer/DrawerFooter.vue
Normal file
14
src/components/ui/drawer/DrawerFooter.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('mt-auto flex flex-col gap-2 p-4', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
14
src/components/ui/drawer/DrawerHeader.vue
Normal file
14
src/components/ui/drawer/DrawerHeader.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: HtmlHTMLAttributes['class']
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cn('grid gap-1.5 p-4 text-center sm:text-left', props.class)">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
18
src/components/ui/drawer/DrawerOverlay.vue
Normal file
18
src/components/ui/drawer/DrawerOverlay.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DialogOverlayProps } from 'radix-vue'
|
||||||
|
import { DrawerOverlay } from 'vaul-vue'
|
||||||
|
import { computed, type HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DialogOverlayProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerOverlay v-bind="delegatedProps" :class="cn('fixed inset-0 z-50 bg-black/80', props.class)" />
|
||||||
|
</template>
|
||||||
20
src/components/ui/drawer/DrawerTitle.vue
Normal file
20
src/components/ui/drawer/DrawerTitle.vue
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { DrawerTitleProps } from 'vaul-vue'
|
||||||
|
import { DrawerTitle } from 'vaul-vue'
|
||||||
|
import { computed, type HtmlHTMLAttributes } from 'vue'
|
||||||
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<DrawerTitleProps & { class?: HtmlHTMLAttributes['class'] }>()
|
||||||
|
|
||||||
|
const delegatedProps = computed(() => {
|
||||||
|
const { class: _, ...delegated } = props
|
||||||
|
|
||||||
|
return delegated
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DrawerTitle v-bind="delegatedProps" :class="cn('text-lg font-semibold leading-none tracking-tight', props.class)">
|
||||||
|
<slot />
|
||||||
|
</DrawerTitle>
|
||||||
|
</template>
|
||||||
8
src/components/ui/drawer/index.ts
Normal file
8
src/components/ui/drawer/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export { default as Drawer } from './Drawer.vue'
|
||||||
|
export { default as DrawerContent } from './DrawerContent.vue'
|
||||||
|
export { default as DrawerDescription } from './DrawerDescription.vue'
|
||||||
|
export { default as DrawerFooter } from './DrawerFooter.vue'
|
||||||
|
export { default as DrawerHeader } from './DrawerHeader.vue'
|
||||||
|
export { default as DrawerOverlay } from './DrawerOverlay.vue'
|
||||||
|
export { default as DrawerTitle } from './DrawerTitle.vue'
|
||||||
|
export { DrawerClose, DrawerPortal, DrawerTrigger } from 'vaul-vue'
|
||||||
@ -21,12 +21,14 @@ const allPaths = ref([] as string[])
|
|||||||
const selected = reactive({
|
const selected = reactive({
|
||||||
selectedMode: '观测的二阶多项式拟合',
|
selectedMode: '观测的二阶多项式拟合',
|
||||||
selectedPath: '',
|
selectedPath: '',
|
||||||
|
station: 'LIN',
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await baseFetch<string []>(`${API_BASE_URL}/balloon/metadata`).json().then(({ data }) => {
|
await baseFetch<string []>(`${API_BASE_URL}/balloon/metadata`).json().then(({ data }) => {
|
||||||
const das = data.value!
|
const das = data.value!
|
||||||
allPaths.value = das
|
allPaths.value = das
|
||||||
|
selected.selectedPath = das[0]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -89,6 +91,20 @@ async function customHandle(resp: Response) {
|
|||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
<Label>选择台站</Label>
|
||||||
|
<Select v-model="selected.station">
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="选择台站" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>台站</SelectLabel>
|
||||||
|
<SelectItem value="LIN">
|
||||||
|
LIN
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
<Label>选择日期</Label>
|
<Label>选择日期</Label>
|
||||||
<Select v-model="selected.selectedPath">
|
<Select v-model="selected.selectedPath">
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
|
|||||||
@ -40,7 +40,7 @@ const urll = computed(() => {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await refreshPath()
|
await refreshPath()
|
||||||
selected.path = saberPaths.value[0]
|
selected.path = saberPaths.value[1]
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => selected.path, async () => {
|
watch(() => selected.path, async () => {
|
||||||
@ -49,7 +49,7 @@ watch(() => selected.path, async () => {
|
|||||||
}
|
}
|
||||||
await refreshCurrentSaberDays(selected.path)
|
await refreshCurrentSaberDays(selected.path)
|
||||||
if (selected.day === '' && currentSaberDays.value.length > 0) {
|
if (selected.day === '' && currentSaberDays.value.length > 0) {
|
||||||
selected.day = currentSaberDays.value[0]
|
selected.day = currentSaberDays.value[1]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -94,7 +94,7 @@ watch(() => selected.path, async () => {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Day</SelectLabel>
|
<SelectLabel>Day</SelectLabel>
|
||||||
<SelectItem v-for="day in currentSaberDays" :key="day" :value="day">
|
<SelectItem v-for="day in currentSaberDays.slice(1)" :key="day" :value="day">
|
||||||
{{ parseDayOfYear (day.toString()).toLocaleDateString("zh", {
|
{{ parseDayOfYear (day.toString()).toLocaleDateString("zh", {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
|
|||||||
@ -43,11 +43,14 @@ const urll = computed(() => {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await refreshPath()
|
await refreshPath()
|
||||||
selected.path = saberPaths.value[0]
|
selected.path = saberPaths.value[1]
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => selected.path, async () => {
|
watch(() => selected.path, async () => {
|
||||||
await refreshCurrentSaberDays(selected.path)
|
await refreshCurrentSaberDays(selected.path)
|
||||||
|
if (selected.day === '' && currentSaberDays.value.length > 0) {
|
||||||
|
selected.day = currentSaberDays.value[1]
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -91,7 +94,7 @@ watch(() => selected.path, async () => {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Day</SelectLabel>
|
<SelectLabel>Day</SelectLabel>
|
||||||
<SelectItem v-for="day in currentSaberDays" :key="day" :value="day">
|
<SelectItem v-for="day in currentSaberDays.slice(1)" :key="day" :value="day">
|
||||||
{{ parseDayOfYear(day.toString()).toLocaleDateString("zh", {
|
{{ parseDayOfYear(day.toString()).toLocaleDateString("zh", {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const lat_ranges = [
|
|||||||
const selected = reactive({
|
const selected = reactive({
|
||||||
path: './saber/data\\2012\\SABER_Temp_O3_April2012_v2.0.nc',
|
path: './saber/data\\2012\\SABER_Temp_O3_April2012_v2.0.nc',
|
||||||
day: '',
|
day: '',
|
||||||
height_no: 1,
|
height_no: '1',
|
||||||
lat_ranges: '0,10',
|
lat_ranges: '0,10',
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -40,15 +40,32 @@ const urll = computed(() => {
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await refreshPath()
|
await refreshPath()
|
||||||
selected.path = saberPaths.value[0]
|
selected.path = saberPaths.value[1]
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => selected.path, async () => {
|
watch(() => selected.path, async () => {
|
||||||
await refreshCurrentSaberDays(selected.path)
|
await refreshCurrentSaberDays(selected.path)
|
||||||
if (saberPaths.value.length > 0) {
|
if (saberPaths.value.length > 0) {
|
||||||
selected.path = saberPaths.value[0]
|
selected.path = saberPaths.value[1]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function mapHeightValue(input: number) {
|
||||||
|
// Input range: 1 to 157
|
||||||
|
// Output range: 30 to 90
|
||||||
|
const inputMin = 1
|
||||||
|
const inputMax = 157
|
||||||
|
const outputMin = 30
|
||||||
|
const outputMax = 90
|
||||||
|
|
||||||
|
// Calculate slope
|
||||||
|
const m = (outputMax - outputMin) / (inputMax - inputMin)
|
||||||
|
// Calculate y-intercept
|
||||||
|
const b = outputMin - m * inputMin
|
||||||
|
|
||||||
|
// Apply linear mapping
|
||||||
|
return m * input + b
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -91,7 +108,7 @@ watch(() => selected.path, async () => {
|
|||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Day</SelectLabel>
|
<SelectLabel>Day</SelectLabel>
|
||||||
<SelectItem v-for="day in currentSaberDays" :key="day" :value="day">
|
<SelectItem v-for="day in currentSaberDays.slice(1)" :key="day" :value="day">
|
||||||
{{ parseDayOfYear(day.toString()).toLocaleDateString("zh", {
|
{{ parseDayOfYear(day.toString()).toLocaleDateString("zh", {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
@ -102,13 +119,19 @@ watch(() => selected.path, async () => {
|
|||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<Label for="age">高度</Label>
|
<Label for="age">高度</Label>
|
||||||
<NumberField id="age" :default-value="18" :min="0">
|
<Select v-model="selected.height_no">
|
||||||
<NumberFieldContent>
|
<SelectTrigger>
|
||||||
<NumberFieldDecrement />
|
<SelectValue placeholder="选择高度" />
|
||||||
<NumberFieldInput />
|
</SelectTrigger>
|
||||||
<NumberFieldIncrement />
|
<SelectContent>
|
||||||
</NumberFieldContent>
|
<SelectGroup>
|
||||||
</NumberField>
|
<SelectLabel>高度</SelectLabel>
|
||||||
|
<SelectItem v-for="height_no in 157" :key="height_no" :value="height_no.toString()">
|
||||||
|
{{ mapHeightValue(height_no).toFixed(2) }} km
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DenseFramework>
|
</DenseFramework>
|
||||||
|
|||||||
92
src/pages/tidi/month_stats.vue
Normal file
92
src/pages/tidi/month_stats.vue
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<route lang="json">
|
||||||
|
{
|
||||||
|
"meta":{
|
||||||
|
"title":"TIDI月统计",
|
||||||
|
"description":"TIDI月统计",
|
||||||
|
"group":"TIDI",
|
||||||
|
"item_name":"月统计"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const selected = reactive({
|
||||||
|
year: '2015',
|
||||||
|
mode: 'v1',
|
||||||
|
lat_range: '0 ~ 20',
|
||||||
|
})
|
||||||
|
|
||||||
|
const allYears = ref([] as string[])
|
||||||
|
const lat_ranges = ['0 ~ 20']
|
||||||
|
|
||||||
|
const queryUrl = computed(() => {
|
||||||
|
const query = new URLSearchParams()
|
||||||
|
query.set('year', selected.year)
|
||||||
|
const mode = selected.mode
|
||||||
|
return `/tidi/render/month_stats_${mode}?${query}`
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const resp = await baseFetch(`/tidi/metadata`).json()
|
||||||
|
allYears.value = Array.from(new Set(resp.data.value.path.map((a: string) => {
|
||||||
|
const year_pattern = /data\/(\d{4})\//
|
||||||
|
return a.match(year_pattern)?.[1]
|
||||||
|
})))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DenseFramework :image-query="queryUrl">
|
||||||
|
<Label>选择模式</Label>
|
||||||
|
<Tabs v-model="selected.mode" default-value="v1">
|
||||||
|
<TabsList class="grid grid-cols-1 w-full">
|
||||||
|
<TabsTrigger value="v1">
|
||||||
|
重力波势能(取log)随高度变化热力图
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger value="v2">
|
||||||
|
重力波势能(取log)变化折线图
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
</Tabs>
|
||||||
|
<Label>纬度带</Label>
|
||||||
|
<Select v-model="selected.lat_range">
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="选择纬度带" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>纬度带</SelectLabel>
|
||||||
|
<SelectItem
|
||||||
|
v-for="lat_range in lat_ranges"
|
||||||
|
:key="lat_range"
|
||||||
|
:value="lat_range"
|
||||||
|
>
|
||||||
|
{{ lat_range }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
<Label>年份</Label>
|
||||||
|
<Select v-model="selected.year">
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="选择年份" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>年份</SelectLabel>
|
||||||
|
<SelectItem
|
||||||
|
v-for="y in allYears"
|
||||||
|
:key="y"
|
||||||
|
:value="y"
|
||||||
|
>
|
||||||
|
{{ y }}
|
||||||
|
</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</select>
|
||||||
|
</DenseFramework>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<route lang="json">
|
<route lang="json">
|
||||||
{
|
{
|
||||||
"meta":{
|
"meta":{
|
||||||
"title":"TIDI 行星波月统计",
|
"title":"TIDI 行星波振幅",
|
||||||
"icon":"mdi:telescope",
|
"icon":"mdi:telescope",
|
||||||
"group":"TIDI",
|
"group":"TIDI",
|
||||||
"item_name":"行星波月统计"
|
"item_name":"行星波振幅"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
typed-router.d.ts
vendored
1
typed-router.d.ts
vendored
@ -30,6 +30,7 @@ declare module 'vue-router/auto-routes' {
|
|||||||
'/saber/day_fft_ifft_plot': RouteRecordInfo<'/saber/day_fft_ifft_plot', '/saber/day_fft_ifft_plot', Record<never, never>, Record<never, never>>,
|
'/saber/day_fft_ifft_plot': RouteRecordInfo<'/saber/day_fft_ifft_plot', '/saber/day_fft_ifft_plot', Record<never, never>, Record<never, never>>,
|
||||||
'/saber/month_power_wave_plot': RouteRecordInfo<'/saber/month_power_wave_plot', '/saber/month_power_wave_plot', Record<never, never>, Record<never, never>>,
|
'/saber/month_power_wave_plot': RouteRecordInfo<'/saber/month_power_wave_plot', '/saber/month_power_wave_plot', Record<never, never>, Record<never, never>>,
|
||||||
'/saber/plot_wave_fitting': RouteRecordInfo<'/saber/plot_wave_fitting', '/saber/plot_wave_fitting', Record<never, never>, Record<never, never>>,
|
'/saber/plot_wave_fitting': RouteRecordInfo<'/saber/plot_wave_fitting', '/saber/plot_wave_fitting', Record<never, never>, Record<never, never>>,
|
||||||
|
'/tidi/month_stats': RouteRecordInfo<'/tidi/month_stats', '/tidi/month_stats', Record<never, never>, Record<never, never>>,
|
||||||
'/tidi/waves': RouteRecordInfo<'/tidi/waves', '/tidi/waves', Record<never, never>, Record<never, never>>,
|
'/tidi/waves': RouteRecordInfo<'/tidi/waves', '/tidi/waves', Record<never, never>, Record<never, never>>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user