178 lines
4.3 KiB
Vue
178 lines
4.3 KiB
Vue
<template>
|
|
<el-dialog
|
|
v-model="dialogVisible"
|
|
title="数据预览"
|
|
width="80%"
|
|
>
|
|
<div v-loading="loading">
|
|
<!-- 数据集基本信息 -->
|
|
<el-descriptions title="数据集信息" :column="3" border>
|
|
<el-descriptions-item label="行数">
|
|
{{ dataInfo?.info?.rows || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="列数">
|
|
{{ dataInfo?.info?.columns || '-' }}
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="内存占用">
|
|
{{ dataInfo?.info?.memory_usage || '-' }}
|
|
</el-descriptions-item>
|
|
</el-descriptions>
|
|
|
|
<!-- 数据预览表格 -->
|
|
<div class="preview-section">
|
|
<h4>数据预览</h4>
|
|
<el-table
|
|
:data="dataInfo?.head || []"
|
|
style="width: 100%"
|
|
max-height="400"
|
|
border
|
|
>
|
|
<el-table-column
|
|
v-for="col in getColumns(dataInfo?.head)"
|
|
:key="col"
|
|
:prop="col"
|
|
:label="col"
|
|
/>
|
|
</el-table>
|
|
</div>
|
|
|
|
<!-- 数据统计信息 -->
|
|
<div class="statistics-section">
|
|
<h4>数据统计</h4>
|
|
<el-table
|
|
:data="getDescribeData(dataInfo?.describe)"
|
|
style="width: 100%"
|
|
border
|
|
>
|
|
<el-table-column prop="metric" label="统计量" width="180" />
|
|
<el-table-column
|
|
v-for="col in getDescribeColumns(dataInfo?.describe)"
|
|
:key="col"
|
|
:prop="col"
|
|
:label="col"
|
|
/>
|
|
</el-table>
|
|
</div>
|
|
|
|
<!-- 缺失值信息 -->
|
|
<div class="missing-section">
|
|
<h4>缺失值统计</h4>
|
|
<el-table
|
|
:data="getMissingData(dataInfo?.info?.missing_values)"
|
|
style="width: 100%"
|
|
border
|
|
>
|
|
<el-table-column prop="column" label="列名" />
|
|
<el-table-column prop="count" label="缺失值数量" />
|
|
<el-table-column prop="percentage" label="缺失比例">
|
|
<template #default="{ row }">
|
|
{{ row.percentage }}%
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, watch } from 'vue'
|
|
import type { DatasetInfo, DataPreview } from '@/types/data'
|
|
import { readCSV } from '@/api/data'
|
|
|
|
const props = defineProps<{
|
|
visible: boolean
|
|
dataset: DatasetInfo | null
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'update:visible', value: boolean): void
|
|
}>()
|
|
|
|
const dialogVisible = ref(false)
|
|
const loading = ref(false)
|
|
const dataInfo = ref<DataPreview | null>(null)
|
|
|
|
// 监听对话框显示状态
|
|
watch(() => props.visible, (val) => {
|
|
dialogVisible.value = val
|
|
if (val && props.dataset) {
|
|
loadData()
|
|
}
|
|
})
|
|
|
|
// 监听对话框关闭
|
|
watch(dialogVisible, (val) => {
|
|
emit('update:visible', val)
|
|
})
|
|
|
|
// 加载数据
|
|
const loadData = async () => {
|
|
if (!props.dataset) return
|
|
|
|
loading.value = true
|
|
try {
|
|
const { data } = await readCSV({
|
|
data_path: props.dataset.input_file,
|
|
head: 10,
|
|
tail: 5,
|
|
info: true,
|
|
describe: true
|
|
})
|
|
dataInfo.value = data
|
|
} catch (error) {
|
|
console.error(error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 获取表格列
|
|
const getColumns = (data: any[] = []) => {
|
|
return data.length > 0 ? Object.keys(data[0]) : []
|
|
}
|
|
|
|
// 获取统计数据列
|
|
const getDescribeColumns = (describe: any = {}) => {
|
|
return Object.keys(describe)
|
|
}
|
|
|
|
// 转换统计数据为表格格式
|
|
const getDescribeData = (describe: any = {}) => {
|
|
if (!describe) return []
|
|
|
|
const metrics = ['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']
|
|
return metrics.map(metric => ({
|
|
metric,
|
|
...Object.fromEntries(
|
|
Object.entries(describe).map(([col, stats]: [string, any]) => [
|
|
col,
|
|
typeof stats === 'object' ? stats[metric] : null
|
|
])
|
|
)
|
|
}))
|
|
}
|
|
|
|
// 转换缺失值数据为表格格式
|
|
const getMissingData = (missingValues: Record<string, number> = {}) => {
|
|
if (!dataInfo.value?.info?.rows) return []
|
|
|
|
return Object.entries(missingValues).map(([column, count]) => ({
|
|
column,
|
|
count,
|
|
percentage: ((count / dataInfo.value!.info.rows) * 100).toFixed(2)
|
|
}))
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.preview-section,
|
|
.statistics-section,
|
|
.missing-section {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
h4 {
|
|
margin-bottom: 10px;
|
|
}
|
|
</style> |