refactor: overhaul UI for streamlined user experience
Redesign navigation, home overview, user portrait, and valuation pages with improved functionality and responsive design. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
950
components/data-integration/data-correlation-analysis.tsx
Normal file
950
components/data-integration/data-correlation-analysis.tsx
Normal file
@@ -0,0 +1,950 @@
|
||||
"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">高度显著 (p≤0.001)</Badge>
|
||||
}
|
||||
if (significance <= 0.01) {
|
||||
return <Badge className="bg-green-100 text-green-800">显著 (p≤0.01)</Badge>
|
||||
}
|
||||
if (significance <= 0.05) {
|
||||
return <Badge className="bg-yellow-100 text-yellow-800">边际显著 (p≤0.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>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user