Files
users/components/data-integration/data-correlation-analysis.tsx

951 lines
42 KiB
TypeScript
Raw Normal View History

"use client"
import { useState } from "react"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Checkbox } from "@/components/ui/checkbox"
import { Badge } from "@/components/ui/badge"
import { Separator } from "@/components/ui/separator"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Search, Filter, Download, RefreshCw, Play, ArrowRight, Settings } from 'lucide-react'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
// 模拟图表组件
const NetworkGraph = ({ data, title }: { data: any; title: string }) => (
<div className="w-full h-96 bg-muted/30 rounded-md flex items-center justify-center">
<div className="text-center">
<p className="text-muted-foreground">{title}</p>
<p className="text-sm text-muted-foreground"></p>
</div>
</div>
)
const ScatterPlot = ({ data, title }: { data: any; title: string }) => (
<div className="w-full h-64 bg-muted/30 rounded-md flex items-center justify-center">
<div className="text-center">
<p className="text-muted-foreground">{title}</p>
<p className="text-sm text-muted-foreground"></p>
</div>
</div>
)
const HeatMap = ({ data, title }: { data: any; title: string }) => (
<div className="w-full h-64 bg-muted/30 rounded-md flex items-center justify-center">
<div className="text-center">
<p className="text-muted-foreground">{title}</p>
<p className="text-sm text-muted-foreground"></p>
</div>
</div>
)
interface CorrelationResult {
id: string
field1: string
field2: string
correlationCoefficient: number
significance: number
sampleSize: number
createdAt: string
dataSource: string
}
interface UserSegmentCorrelation {
id: string
segment1: string
segment2: string
overlapPercentage: number
uniqueUsers1: number
uniqueUsers2: number
commonUsers: number
}
export function DataCorrelationAnalysis() {
const [activeTab, setActiveTab] = useState("field-correlation")
const [isCreatingAnalysis, setIsCreatingAnalysis] = useState(false)
const [selectedFields, setSelectedFields] = useState<string[]>([])
const [selectedDataSources, setSelectedDataSources] = useState<string[]>([])
// 模拟字段列表
const fields = [
{ id: "userId", name: "用户ID", type: "string", dataSource: "所有数据源" },
{ id: "phoneNumber", name: "手机号", type: "string", dataSource: "所有数据源" },
{ id: "identityNumber", name: "身份证号", type: "string", dataSource: "所有数据源" },
{ id: "deviceImei", name: "IMEI设备号", type: "string", dataSource: "所有数据源" },
{ id: "registrationDate", name: "注册时间", type: "datetime", dataSource: "用户数据库" },
{ id: "lastActiveTime", name: "最后活跃时间", type: "datetime", dataSource: "行为分析平台" },
{ id: "age", name: "年龄", type: "number", dataSource: "用户数据库" },
{ id: "gender", name: "性别", type: "string", dataSource: "用户数据库" },
{ id: "location", name: "地区", type: "string", dataSource: "用户数据库" },
{ id: "totalSpent", name: "消费总额", type: "number", dataSource: "交易系统" },
{ id: "purchaseFrequency", name: "购买频率", type: "number", dataSource: "交易系统" },
{ id: "averageOrderValue", name: "平均订单金额", type: "number", dataSource: "交易系统" },
{ id: "preferredCategory", name: "偏好类别", type: "string", dataSource: "交易系统" },
{ id: "loginFrequency", name: "登录频率", type: "number", dataSource: "行为分析平台" },
{ id: "timeSpentPerSession", name: "单次会话时长", type: "number", dataSource: "行为分析平台" },
{ id: "clickThroughRate", name: "点击率", type: "number", dataSource: "行为分析平台" },
{ id: "conversionRate", name: "转化率", type: "number", dataSource: "行为分析平台" },
{ id: "rfmScore", name: "RFM评分", type: "number", dataSource: "用户价值模型" },
{ id: "lifetimeValue", name: "生命周期价值", type: "number", dataSource: "用户价值模型" },
{ id: "churnRisk", name: "流失风险", type: "number", dataSource: "用户价值模型" },
]
// 模拟数据源
const dataSources = [
{ id: "all", name: "所有数据源" },
{ id: "user-db", name: "用户数据库" },
{ id: "transaction", name: "交易系统" },
{ id: "behavior", name: "行为分析平台" },
{ id: "user-value", name: "用户价值模型" },
]
// 模拟用户分群
const userSegments = [
{ id: "high-value", name: "高价值用户", count: 12500 },
{ id: "new-users", name: "新注册用户", count: 45600 },
{ id: "inactive", name: "非活跃用户", count: 28900 },
{ id: "potential", name: "潜在高转化用户", count: 18700 },
{ id: "loyal", name: "忠诚用户", count: 9800 },
{ id: "risk", name: "流失风险用户", count: 15400 },
]
// 模拟相关性分析结果
const correlationResults: CorrelationResult[] = [
{
id: "corr-1",
field1: "年龄",
field2: "消费总额",
correlationCoefficient: 0.72,
significance: 0.001,
sampleSize: 45678,
createdAt: "2023-07-20 15:30",
dataSource: "用户数据库 & 交易系统",
},
{
id: "corr-2",
field1: "登录频率",
field2: "购买频率",
correlationCoefficient: 0.85,
significance: 0.001,
sampleSize: 38945,
createdAt: "2023-07-20 15:30",
dataSource: "行为分析平台 & 交易系统",
},
{
id: "corr-3",
field1: "单次会话时长",
field2: "转化率",
correlationCoefficient: 0.65,
significance: 0.01,
sampleSize: 42156,
createdAt: "2023-07-20 15:30",
dataSource: "行为分析平台",
},
{
id: "corr-4",
field1: "地区",
field2: "偏好类别",
correlationCoefficient: 0.58,
significance: 0.05,
sampleSize: 45678,
createdAt: "2023-07-20 15:30",
dataSource: "用户数据库 & 交易系统",
},
{
id: "corr-5",
field1: "RFM评分",
field2: "生命周期价值",
correlationCoefficient: 0.92,
significance: 0.001,
sampleSize: 45678,
createdAt: "2023-07-20 15:30",
dataSource: "用户价值模型",
},
]
// 模拟用户分群相关性
const segmentCorrelations: UserSegmentCorrelation[] = [
{
id: "seg-corr-1",
segment1: "高价值用户",
segment2: "忠诚用户",
overlapPercentage: 68.5,
uniqueUsers1: 12500,
uniqueUsers2: 9800,
commonUsers: 6713,
},
{
id: "seg-corr-2",
segment1: "新注册用户",
segment2: "潜在高转化用户",
overlapPercentage: 12.3,
uniqueUsers1: 45600,
uniqueUsers2: 18700,
commonUsers: 5609,
},
{
id: "seg-corr-3",
segment1: "非活跃用户",
segment2: "流失风险用户",
overlapPercentage: 75.2,
uniqueUsers1: 28900,
uniqueUsers2: 15400,
commonUsers: 11581,
},
{
id: "seg-corr-4",
segment1: "高价值用户",
segment2: "潜在高转化用户",
overlapPercentage: 8.7,
uniqueUsers1: 12500,
uniqueUsers2: 18700,
commonUsers: 1088,
},
{
id: "seg-corr-5",
segment1: "忠诚用户",
segment2: "流失风险用户",
overlapPercentage: 2.1,
uniqueUsers1: 9800,
uniqueUsers2: 15400,
commonUsers: 206,
},
]
const getCorrelationStrength = (coefficient: number) => {
const absCoefficient = Math.abs(coefficient)
if (absCoefficient >= 0.8) return "强"
if (absCoefficient >= 0.5) return "中"
return "弱"
}
const getCorrelationBadge = (coefficient: number) => {
const absCoefficient = Math.abs(coefficient)
if (absCoefficient >= 0.8) {
return <Badge className="bg-green-100 text-green-800"></Badge>
}
if (absCoefficient >= 0.5) {
return <Badge className="bg-yellow-100 text-yellow-800"></Badge>
}
return <Badge className="bg-gray-100 text-gray-800"></Badge>
}
const getSignificanceBadge = (significance: number) => {
if (significance <= 0.001) {
return <Badge className="bg-green-100 text-green-800"> (p0.001)</Badge>
}
if (significance <= 0.01) {
return <Badge className="bg-green-100 text-green-800"> (p0.01)</Badge>
}
if (significance <= 0.05) {
return <Badge className="bg-yellow-100 text-yellow-800"> (p0.05)</Badge>
}
return <Badge className="bg-red-100 text-red-800">{'不显著 (p>0.05)'}</Badge>
}
const toggleFieldSelection = (fieldId: string) => {
if (selectedFields.includes(fieldId)) {
setSelectedFields(selectedFields.filter((id) => id !== fieldId))
} else {
setSelectedFields([...selectedFields, fieldId])
}
}
const toggleDataSourceSelection = (sourceId: string) => {
if (selectedDataSources.includes(sourceId)) {
setSelectedDataSources(selectedDataSources.filter((id) => id !== sourceId))
} else {
setSelectedDataSources([...selectedDataSources, sourceId])
}
}
return (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h2 className="text-2xl font-bold"></h2>
<div className="flex items-center gap-2">
<Button variant="outline">
<Download className="mr-2 h-4 w-4" />
</Button>
<Button onClick={() => setIsCreatingAnalysis(true)}>
<Play className="mr-2 h-4 w-4" />
</Button>
</div>
</div>
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-4">
<TabsList>
<TabsTrigger value="field-correlation"></TabsTrigger>
<TabsTrigger value="segment-correlation"></TabsTrigger>
<TabsTrigger value="user-network"></TabsTrigger>
<TabsTrigger value="path-analysis"></TabsTrigger>
</TabsList>
<TabsContent value="field-correlation" className="space-y-4">
<Card>
<CardHeader>
<div className="flex justify-between items-center">
<CardTitle></CardTitle>
<div className="flex items-center gap-2">
<div className="relative">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input type="text" placeholder="搜索字段..." className="pl-8 w-[200px]" />
</div>
<Select defaultValue="all">
<SelectTrigger className="w-[150px]">
<Filter className="mr-2 h-4 w-4" />
<SelectValue placeholder="相关性强度" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="strong"></SelectItem>
<SelectItem value="medium"></SelectItem>
<SelectItem value="weak"></SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardHeader>
<CardContent>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>1</TableHead>
<TableHead>2</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{correlationResults.map((result) => (
<TableRow key={result.id}>
<TableCell className="font-medium">{result.field1}</TableCell>
<TableCell className="font-medium">{result.field2}</TableCell>
<TableCell>{result.correlationCoefficient.toFixed(2)}</TableCell>
<TableCell>{getCorrelationBadge(result.correlationCoefficient)}</TableCell>
<TableCell>{getSignificanceBadge(result.significance)}</TableCell>
<TableCell>{result.sampleSize.toLocaleString()}</TableCell>
<TableCell>{result.dataSource}</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<HeatMap data={{}} title="字段相关性热力图" />
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex gap-4">
<div className="flex-1">
<Label>X轴字段</Label>
<Select defaultValue="age">
<SelectTrigger>
<SelectValue placeholder="选择字段" />
</SelectTrigger>
<SelectContent>
{fields
.filter((field) => field.type === "number")
.map((field) => (
<SelectItem key={field.id} value={field.id}>
{field.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex-1">
<Label>Y轴字段</Label>
<Select defaultValue="totalSpent">
<SelectTrigger>
<SelectValue placeholder="选择字段" />
</SelectTrigger>
<SelectContent>
{fields
.filter((field) => field.type === "number")
.map((field) => (
<SelectItem key={field.id} value={field.id}>
{field.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<ScatterPlot data={{}} title="年龄 vs 消费总额" />
</div>
</CardContent>
</Card>
</div>
</TabsContent>
<TabsContent value="segment-correlation" className="space-y-4">
<Card>
<CardHeader>
<div className="flex justify-between items-center">
<CardTitle></CardTitle>
<Button></Button>
</div>
</CardHeader>
<CardContent>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>1</TableHead>
<TableHead>2</TableHead>
<TableHead></TableHead>
<TableHead>1</TableHead>
<TableHead>2</TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{segmentCorrelations.map((correlation) => (
<TableRow key={correlation.id}>
<TableCell className="font-medium">{correlation.segment1}</TableCell>
<TableCell className="font-medium">{correlation.segment2}</TableCell>
<TableCell>
<div className="flex items-center gap-2">
<span>{correlation.overlapPercentage.toFixed(1)}%</span>
{correlation.overlapPercentage > 50 ? (
<Badge className="bg-green-100 text-green-800"></Badge>
) : correlation.overlapPercentage > 20 ? (
<Badge className="bg-yellow-100 text-yellow-800"></Badge>
) : (
<Badge className="bg-gray-100 text-gray-800"></Badge>
)}
</div>
</TableCell>
<TableCell>{correlation.uniqueUsers1.toLocaleString()}</TableCell>
<TableCell>{correlation.uniqueUsers2.toLocaleString()}</TableCell>
<TableCell>{correlation.commonUsers.toLocaleString()}</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex gap-4">
<div className="flex-1">
<Label>1</Label>
<Select defaultValue="high-value">
<SelectTrigger>
<SelectValue placeholder="选择分群" />
</SelectTrigger>
<SelectContent>
{userSegments.map((segment) => (
<SelectItem key={segment.id} value={segment.id}>
{segment.name} ({segment.count.toLocaleString()})
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex-1">
<Label>2</Label>
<Select defaultValue="loyal">
<SelectTrigger>
<SelectValue placeholder="选择分群" />
</SelectTrigger>
<SelectContent>
{userSegments.map((segment) => (
<SelectItem key={segment.id} value={segment.id}>
{segment.name} ({segment.count.toLocaleString()})
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<div className="p-6 border rounded-md">
<div className="flex justify-center items-center">
<div className="w-32 h-32 rounded-full bg-blue-100 flex items-center justify-center text-blue-800 font-bold text-lg">
</div>
<div className="w-24 h-24 bg-blue-200 mx-4 flex items-center justify-center text-blue-800 font-bold">
<br />
68.5%
</div>
<div className="w-32 h-32 rounded-full bg-green-100 flex items-center justify-center text-green-800 font-bold text-lg">
</div>
</div>
<div className="mt-4 text-center">
<p className="text-sm text-muted-foreground">
共同用户: 6,713 | 高价值用户: 12,500 | 忠诚用户: 9,800
</p>
</div>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="user-network" className="space-y-4">
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex justify-between items-center">
<div className="flex gap-2">
<Select defaultValue="all">
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="关联维度" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="id">ID</SelectItem>
<SelectItem value="phone"></SelectItem>
<SelectItem value="identity"></SelectItem>
<SelectItem value="imei">IMEI设备号</SelectItem>
</SelectContent>
</Select>
<Select defaultValue="high-value">
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="用户分群" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
{userSegments.map((segment) => (
<SelectItem key={segment.id} value={segment.id}>
{segment.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex gap-2">
<Button variant="outline" size="sm">
<Settings className="mr-2 h-4 w-4" />
</Button>
<Button variant="outline" size="sm">
<RefreshCw className="mr-2 h-4 w-4" />
</Button>
</div>
</div>
<NetworkGraph data={{}} title="用户关联网络图" />
<div className="flex justify-between items-center">
<div>
<h3 className="text-sm font-medium"></h3>
<p className="text-xs text-muted-foreground">节点: 1,245 | 连接: 3,567 | 平均连接度: 2.87</p>
</div>
<div className="flex gap-2">
<Badge className="bg-blue-100 text-blue-800">ID</Badge>
<Badge className="bg-green-100 text-green-800"></Badge>
<Badge className="bg-purple-100 text-purple-800"></Badge>
<Badge className="bg-orange-100 text-orange-800">IMEI设备号</Badge>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>ID</TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-medium">-001</TableCell>
<TableCell>125</TableCell>
<TableCell>
<Badge className="bg-green-100 text-green-800"></Badge>
</TableCell>
<TableCell>, IMEI设备号</TableCell>
<TableCell>2023-07-20 15:30</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">-002</TableCell>
<TableCell>87</TableCell>
<TableCell>
<Badge className="bg-green-100 text-green-800"></Badge>
</TableCell>
<TableCell>, ID</TableCell>
<TableCell>2023-07-20 15:30</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">-003</TableCell>
<TableCell>215</TableCell>
<TableCell>
<Badge className="bg-yellow-100 text-yellow-800"></Badge>
</TableCell>
<TableCell>, ID</TableCell>
<TableCell>2023-07-20 15:30</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">-004</TableCell>
<TableCell>56</TableCell>
<TableCell>
<Badge className="bg-gray-100 text-gray-800"></Badge>
</TableCell>
<TableCell>IMEI设备号</TableCell>
<TableCell>2023-07-20 15:30</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="sm">
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="path-analysis" className="space-y-4">
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex justify-between items-center">
<div className="flex gap-2">
<Select defaultValue="registration-to-purchase">
<SelectTrigger className="w-[200px]">
<SelectValue placeholder="选择路径类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="registration-to-purchase"></SelectItem>
<SelectItem value="browse-to-purchase"></SelectItem>
<SelectItem value="multi-purchase"></SelectItem>
<SelectItem value="churn-path"></SelectItem>
</SelectContent>
</Select>
<Select defaultValue="all">
<SelectTrigger className="w-[150px]">
<SelectValue placeholder="用户分群" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
{userSegments.map((segment) => (
<SelectItem key={segment.id} value={segment.id}>
{segment.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<Button variant="outline">
<RefreshCw className="mr-2 h-4 w-4" />
</Button>
</div>
<div className="p-4 border rounded-md">
<div className="flex justify-center items-center">
<div className="flex flex-col items-center">
<div className="w-32 h-12 bg-blue-100 rounded-md flex items-center justify-center text-blue-800 font-medium">
</div>
<div className="text-xs text-muted-foreground mt-1">100%</div>
</div>
<div className="flex flex-col items-center mx-2">
<ArrowRight className="h-6 w-6 text-muted-foreground" />
<div className="text-xs text-muted-foreground">85%</div>
</div>
<div className="flex flex-col items-center">
<div className="w-32 h-12 bg-blue-100 rounded-md flex items-center justify-center text-blue-800 font-medium">
</div>
<div className="text-xs text-muted-foreground mt-1">85%</div>
</div>
<div className="flex flex-col items-center mx-2">
<ArrowRight className="h-6 w-6 text-muted-foreground" />
<div className="text-xs text-muted-foreground">65%</div>
</div>
<div className="flex flex-col items-center">
<div className="w-32 h-12 bg-blue-100 rounded-md flex items-center justify-center text-blue-800 font-medium">
</div>
<div className="text-xs text-muted-foreground mt-1">55%</div>
</div>
<div className="flex flex-col items-center mx-2">
<ArrowRight className="h-6 w-6 text-muted-foreground" />
<div className="text-xs text-muted-foreground">40%</div>
</div>
<div className="flex flex-col items-center">
<div className="w-32 h-12 bg-green-100 rounded-md flex items-center justify-center text-green-800 font-medium">
</div>
<div className="text-xs text-muted-foreground mt-1">22%</div>
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<h3 className="text-sm font-medium mb-2"></h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">85%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-green-600 h-1.5 rounded-full" style={{ width: "85%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">65%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-green-600 h-1.5 rounded-full" style={{ width: "65%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">40%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-yellow-600 h-1.5 rounded-full" style={{ width: "40%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">22%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-yellow-600 h-1.5 rounded-full" style={{ width: "22%" }}></div>
</div>
</div>
</div>
<div>
<h3 className="text-sm font-medium mb-2"></h3>
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">15%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-red-600 h-1.5 rounded-full" style={{ width: "15%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">35%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-red-600 h-1.5 rounded-full" style={{ width: "35%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">60%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-red-600 h-1.5 rounded-full" style={{ width: "60%" }}></div>
</div>
<div className="flex justify-between items-center">
<span className="text-sm"></span>
<span className="text-sm">78%</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-1.5">
<div className="bg-red-600 h-1.5 rounded-full" style={{ width: "78%" }}></div>
</div>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
{/* 创建分析对话框 */}
<Dialog open={isCreatingAnalysis} onOpenChange={setIsCreatingAnalysis}>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label></Label>
<div className="grid grid-cols-2 gap-2">
{dataSources.map((source) => (
<div key={source.id} className="flex items-center space-x-2">
<Checkbox
id={`source-${source.id}`}
checked={selectedDataSources.includes(source.id)}
onCheckedChange={() => toggleDataSourceSelection(source.id)}
/>
<Label htmlFor={`source-${source.id}`}>{source.name}</Label>
</div>
))}
</div>
</div>
<Separator />
<div className="space-y-2">
<Label></Label>
<div className="relative">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input type="text" placeholder="搜索字段..." className="pl-8" />
</div>
<div className="h-60 overflow-y-auto border rounded-md p-2">
{fields.map((field) => (
<div key={field.id} className="flex items-center space-x-2 py-1">
<Checkbox
id={`field-${field.id}`}
checked={selectedFields.includes(field.id)}
onCheckedChange={() => toggleFieldSelection(field.id)}
/>
<Label htmlFor={`field-${field.id}`} className="flex-1">
{field.name}
</Label>
<span className="text-xs text-muted-foreground">{field.type}</span>
<Badge variant="outline">{field.dataSource}</Badge>
</div>
))}
</div>
</div>
<div className="space-y-2">
<Label></Label>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="correlation-method"></Label>
<Select defaultValue="pearson">
<SelectTrigger id="correlation-method">
<SelectValue placeholder="选择方法" />
</SelectTrigger>
<SelectContent>
<SelectItem value="pearson">Pearson相关系数</SelectItem>
<SelectItem value="spearman">Spearman等级相关</SelectItem>
<SelectItem value="kendall">Kendall's Tau</SelectItem>
<SelectItem value="chi-square"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="sample-size"></Label>
<Select defaultValue="all">
<SelectTrigger id="sample-size">
<SelectValue placeholder="选择样本大小" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all"></SelectItem>
<SelectItem value="10000">10,000</SelectItem>
<SelectItem value="50000">50,000</SelectItem>
<SelectItem value="100000">100,000</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<Checkbox id="save-result" defaultChecked />
<Label htmlFor="save-result"></Label>
</div>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsCreatingAnalysis(false)}>
</Button>
<Button onClick={() => setIsCreatingAnalysis(false)}>
<Play className="mr-2 h-4 w-4" />
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
)
}