253 lines
6.5 KiB
Vue
253 lines
6.5 KiB
Vue
<template>
|
|
<div class="preprocess-view">
|
|
<el-card v-loading="loading" class="method-card-container">
|
|
<template #header>
|
|
<div class="card-header">
|
|
<span>预处理方法列表</span>
|
|
<el-button type="primary" @click="refreshMethods">刷新</el-button>
|
|
</div>
|
|
</template>
|
|
|
|
<el-tabs v-model="activeTab">
|
|
<!-- 数据缩放 -->
|
|
<el-tab-pane label="数据缩放" name="data_scaler">
|
|
<el-scrollbar height="400px">
|
|
<el-space wrap>
|
|
<el-card
|
|
v-for="method in methodGroups.data_scaler || []"
|
|
:key="method"
|
|
class="method-card"
|
|
@click="showMethodDetails(method)"
|
|
>
|
|
{{ method }}
|
|
</el-card>
|
|
</el-space>
|
|
</el-scrollbar>
|
|
</el-tab-pane>
|
|
|
|
<!-- 缺失值处理 -->
|
|
<el-tab-pane label="缺失值处理" name="missing_value_handler">
|
|
<el-scrollbar height="400px">
|
|
<el-space wrap>
|
|
<el-card
|
|
v-for="method in methodGroups.missing_value_handler || []"
|
|
:key="method"
|
|
class="method-card"
|
|
@click="showMethodDetails(method)"
|
|
>
|
|
{{ method }}
|
|
</el-card>
|
|
</el-space>
|
|
</el-scrollbar>
|
|
</el-tab-pane>
|
|
|
|
<!-- 异常值检测 -->
|
|
<el-tab-pane label="异常值检测" name="outlier_detector">
|
|
<el-scrollbar height="400px">
|
|
<el-space wrap>
|
|
<el-card
|
|
v-for="method in methodGroups.outlier_detector || []"
|
|
:key="method"
|
|
class="method-card"
|
|
@click="showMethodDetails(method)"
|
|
>
|
|
{{ method }}
|
|
</el-card>
|
|
</el-space>
|
|
</el-scrollbar>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</el-card>
|
|
|
|
<!-- 方法详情对话框 -->
|
|
<el-dialog
|
|
v-model="detailsVisible"
|
|
:title="methodDetails?.name"
|
|
width="60%"
|
|
>
|
|
<div v-loading="detailsLoading">
|
|
<el-descriptions :column="1" border>
|
|
<el-descriptions-item label="方法名称">
|
|
{{ methodDetails?.name }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="描述">
|
|
{{ methodDetails?.description }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="原理">
|
|
{{ methodDetails?.principle }}
|
|
</el-descriptions-item>
|
|
</el-descriptions>
|
|
|
|
<div class="mt-4">
|
|
<h4>优点</h4>
|
|
<el-tag
|
|
v-for="(adv, index) in methodDetails?.advantages"
|
|
:key="index"
|
|
class="mx-1"
|
|
type="success"
|
|
>
|
|
{{ adv }}
|
|
</el-tag>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<h4>缺点</h4>
|
|
<el-tag
|
|
v-for="(dis, index) in methodDetails?.disadvantages"
|
|
:key="index"
|
|
class="mx-1"
|
|
type="danger"
|
|
>
|
|
{{ dis }}
|
|
</el-tag>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<h4>适用场景</h4>
|
|
<el-tag
|
|
v-for="(scene, index) in methodDetails?.applicable_scenarios"
|
|
:key="index"
|
|
class="mx-1"
|
|
type="warning"
|
|
>
|
|
{{ scene }}
|
|
</el-tag>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<h4>参数说明</h4>
|
|
<el-table :data="methodDetails?.parameters || []" border>
|
|
<el-table-column prop="name" label="参数名" />
|
|
<el-table-column prop="type" label="类型" />
|
|
<el-table-column prop="default" label="默认值" />
|
|
<el-table-column prop="description" label="说明" />
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue'
|
|
import { ElMessage } from 'element-plus'
|
|
import { getPreprocessMethods, getPreprocessMethodDetails } from '@/api/data'
|
|
import type { PreprocessMethod, MethodDetail } from '@/types/data'
|
|
|
|
// 修改 PreprocessMethod 接口以匹配后端返回的数据结构
|
|
interface PreprocessMethodGroup {
|
|
name: string
|
|
description: string
|
|
method: string[]
|
|
}
|
|
|
|
const activeTab = ref('missing_value_handler')
|
|
const loading = ref(false)
|
|
const methodGroups = ref<Record<string, string[]>>({
|
|
data_scaler: [],
|
|
missing_value_handler: [],
|
|
outlier_detector: []
|
|
})
|
|
const detailsVisible = ref(false)
|
|
const detailsLoading = ref(false)
|
|
const methodDetails = ref<MethodDetail | null>(null)
|
|
|
|
// 加载方法列表
|
|
const loadMethods = async () => {
|
|
loading.value = true
|
|
try {
|
|
const response = await getPreprocessMethods()
|
|
if (response.status === 'success' && Array.isArray(response.methods)) {
|
|
// 将返回的数据按类型分组
|
|
methodGroups.value = response.methods.reduce((groups: Record<string, string[]>, group: PreprocessMethodGroup) => {
|
|
groups[group.name] = group.method
|
|
return groups
|
|
}, {
|
|
data_scaler: [],
|
|
missing_value_handler: [],
|
|
outlier_detector: []
|
|
})
|
|
} else {
|
|
ElMessage.error('加载预处理方法失败')
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load preprocess methods:', error)
|
|
ElMessage.error('加载预处理方法失败')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 显示方法详情
|
|
const showMethodDetails = async (methodName: string) => {
|
|
detailsVisible.value = true
|
|
detailsLoading.value = true
|
|
try {
|
|
const response = await getPreprocessMethodDetails(methodName)
|
|
if (response.status === 'success' && response.method) {
|
|
methodDetails.value = response.method
|
|
} else {
|
|
ElMessage.error('加载方法详情失败')
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load method details:', error)
|
|
ElMessage.error('加载方法详情失败')
|
|
} finally {
|
|
detailsLoading.value = false
|
|
}
|
|
}
|
|
|
|
// 刷新方法列表
|
|
const refreshMethods = () => {
|
|
loadMethods()
|
|
}
|
|
|
|
onMounted(() => {
|
|
loadMethods()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.preprocess-view {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.method-card-container {
|
|
height: 100%;
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.method-card {
|
|
width: 200px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
margin: 10px;
|
|
}
|
|
|
|
.method-card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
|
}
|
|
|
|
.el-space {
|
|
padding: 10px;
|
|
}
|
|
|
|
.mt-4 {
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.mx-1 {
|
|
margin: 0 0.25rem;
|
|
}
|
|
|
|
h4 {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
</style> |