用户行为漏斗 - ECharts 场景化最佳实践
场景描述: 通过漏斗图分析用户在产品中的转化路径,识别流失节点,优化用户体验,提升转化率。广泛应用于电商、SaaS、内容平台等场景。
📋 目录
场景概述
典型应用场景
- 电商购物流程: 浏览→加购→下单→支付
- 注册转化: 访问注册页→填写信息→验证邮箱→完成注册
- 内容消费: 曝光→点击→阅读→点赞→分享
- SaaS激活: 注册→试用功能→邀请队友→付费升级
- 活动营销: 活动曝光→点击参与→完成任务→获得奖励
核心价值
核心概念
漏斗模型
标准漏斗
步骤 用户数 转化率 流失率
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
访问首页 10000 100% 0%
浏览商品 6000 60% 40%
加入购物车 2000 20% 66.7%
提交订单 800 8% 60%
完成支付 500 5% 37.5%1
2
3
4
5
6
7
2
3
4
5
6
7
关键指标:
- 整体转化率: 500/10000 = 5%
- 最大流失点: 浏览商品→加购物车(流失66.7%)
- 优化优先级: 重点优化"加入购物车"环节
转化率计算
typescript
// 单步转化率
function calculateStepConversion(currentStep: number, previousStep: number): number {
return (currentStep / previousStep) * 100;
}
// 整体转化率
function calculateOverallConversion(finalStep: number, firstStep: number): number {
return (finalStep / firstStep) * 100;
}
// 示例
const visitToBrowse = calculateStepConversion(6000, 10000); // 60%
const browseToCart = calculateStepConversion(2000, 6000); // 33.3%
const overallConversion = calculateOverallConversion(500, 10000); // 5%
console.log(`访问→浏览: ${visitToBrowse.toFixed(1)}%`);
console.log(`浏览→加购: ${browseToCart.toFixed(1)}%`);
console.log(`整体转化率: ${overallConversion.toFixed(1)}%`);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
技术实现
基础漏斗图
typescript
// 电商购物漏斗
const funnelData = [
{ name: '访问首页', value: 10000 },
{ name: '浏览商品', value: 6000 },
{ name: '加入购物车', value: 2000 },
{ name: '提交订单', value: 800 },
{ name: '完成支付', value: 500 }
];
chart.setOption({
title: {
text: '电商购物流程转化漏斗',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: (params) => {
const data = params.data;
const prevValue = params.dataIndex > 0
? funnelData[params.dataIndex - 1].value
: data.value;
const conversionRate = ((data.value / prevValue) * 100).toFixed(1);
return `
<b>${data.name}</b><br/>
用户数: ${data.value.toLocaleString()}<br/>
转化率: ${conversionRate}%<br/>
流失: ${prevValue - data.value}人
`;
}
},
series: [{
name: '转化漏斗',
type: 'funnel',
left: '10%',
top: 60,
bottom: 60,
width: '80%',
min: 0,
max: 10000,
minSize: '0%',
maxSize: '100%',
sort: 'descending', // 从上到下递减
gap: 2, // 区块间隔
label: {
show: true,
position: 'inside',
formatter: (params) => {
const rate = params.dataIndex > 0
? ((params.value / funnelData[params.dataIndex - 1].value) * 100).toFixed(1)
: '100.0';
return `${params.name}\n${params.value}人 (${rate}%)`;
}
},
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
emphasis: {
label: {
fontSize: 16
}
},
data: funnelData
}]
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
金字塔图(倒漏斗)
typescript
// 用户等级分布(金字塔结构)
const userLevelData = [
{ name: '普通用户', value: 50000 },
{ name: 'VIP用户', value: 10000 },
{ name: '超级VIP', value: 2000 },
{ name: '合作伙伴', value: 500 }
];
chart.setOption({
series: [{
name: '用户等级',
type: 'funnel',
sort: 'ascending', // ✅ 从小到大(金字塔)
data: userLevelData,
label: {
formatter: '{b}: {c}人'
},
itemStyle: {
color: (params) => {
const colors = ['#91cc75', '#fac858', '#ee6666', '#73c0de'];
return colors[params.dataIndex];
}
}
}]
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
多漏斗对比
typescript
// A/B测试对比
const groupA = [
{ name: '访问', value: 10000 },
{ name: '注册', value: 2000 },
{ name: '激活', value: 800 }
];
const groupB = [
{ name: '访问', value: 10000 },
{ name: '注册', value: 2500 },
{ name: '激活', value: 1200 }
];
chart.setOption({
title: {
text: 'A/B测试转化对比',
left: 'center'
},
legend: {
data: ['对照组A', '实验组B'],
top: 30
},
series: [
{
name: '对照组A',
type: 'funnel',
left: '5%',
width: '40%',
data: groupA,
label: {
formatter: '{b}\n{c}'
}
},
{
name: '实验组B',
type: 'funnel',
right: '5%',
width: '40%',
data: groupB,
label: {
formatter: '{b}\n{c}'
}
}
]
});
// 计算提升
const registrationLift = ((2500 - 2000) / 2000 * 100).toFixed(1); // 25.0%
const activationLift = ((1200 - 800) / 800 * 100).toFixed(1); // 50.0%
console.log(`注册转化提升: ${registrationLift}%`);
console.log(`激活转化提升: ${activationLift}%`);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
高级分析
维度拆解
按渠道拆解
typescript
// 不同渠道的转化漏斗
const channelFunnels = {
'自然搜索': [
{ name: '访问', value: 5000 },
{ name: '注册', value: 800 },
{ name: '付费', value: 200 }
],
'付费广告': [
{ name: '访问', value: 3000 },
{ name: '注册', value: 600 },
{ name: '付费', value: 150 }
],
'社交媒体': [
{ name: '访问', value: 2000 },
{ name: '注册', value: 400 },
{ name: '付费', value: 100 }
]
};
// 计算各渠道转化率
Object.entries(channelFunnels).forEach(([channel, steps]) => {
const registrationRate = (steps[1].value / steps[0].value * 100).toFixed(1);
const paymentRate = (steps[2].value / steps[1].value * 100).toFixed(1);
console.log(`${channel}:`);
console.log(` 注册转化率: ${registrationRate}%`);
console.log(` 付费转化率: ${paymentRate}%`);
});
// 输出:
// 自然搜索: 注册转化率: 16.0%, 付费转化率: 25.0%
// 付费广告: 注册转化率: 20.0%, 付费转化率: 25.0%
// 社交媒体: 注册转化率: 20.0%, 付费转化率: 25.0%1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
按设备类型拆解
typescript
// 移动端 vs PC端
const deviceComparison = {
'移动端': {
steps: [
{ name: '访问', value: 7000 },
{ name: '加购', value: 1400 },
{ name: '支付', value: 350 }
],
conversion: 5.0% // 350/7000
},
'PC端': {
steps: [
{ name: '访问', value: 3000 },
{ name: '加购', value: 600 },
{ name: '支付', value: 150 }
],
conversion: 5.0% // 150/3000
}
};
// 发现: 虽然最终转化率相同,但中间环节差异大
const mobileCartRate = 1400 / 7000 * 100; // 20%
const pcCartRate = 600 / 3000 * 100; // 20%
console.log('移动端加购率:', mobileCartRate + '%');
console.log('PC端加购率:', pcCartRate + '%');1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
趋势监控
typescript
// 每日转化率趋势
const dailyFunnelData = [
{ date: '2024-01-01', visits: 10000, registrations: 1500, payments: 500 },
{ date: '2024-01-02', visits: 11000, registrations: 1700, payments: 550 },
{ date: '2024-01-03', visits: 9500, registrations: 1400, payments: 480 },
// ... 更多日期
];
// 计算每日转化率
const conversionRates = dailyFunnelData.map(day => ({
date: day.date,
registrationRate: (day.registrations / day.visits * 100).toFixed(2),
paymentRate: (day.payments / day.registrations * 100).toFixed(2)
}));
// 绘制趋势图
trendChart.setOption({
title: { text: '转化率趋势' },
xAxis: {
type: 'category',
data: conversionRates.map(d => d.date)
},
yAxis: {
type: 'value',
axisLabel: { formatter: '{value}%' }
},
series: [
{
name: '注册转化率',
type: 'line',
data: conversionRates.map(d => parseFloat(d.registrationRate)),
smooth: true,
lineStyle: { color: '#5470c6' }
},
{
name: '付费转化率',
type: 'line',
data: conversionRates.map(d => parseFloat(d.paymentRate)),
smooth: true,
lineStyle: { color: '#91cc75' }
}
]
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
流失用户分析
typescript
class FunnelLossAnalyzer {
private funnelSteps: any[];
constructor(steps: any[]) {
this.funnelSteps = steps;
}
/**
* 计算每步流失用户数
*/
calculateLoss(): Array<{ step: string; lost: number; lossRate: number }> {
const result: any[] = [];
for (let i = 0; i < this.funnelSteps.length - 1; i++) {
const current = this.funnelSteps[i];
const next = this.funnelSteps[i + 1];
const lost = current.value - next.value;
const lossRate = (lost / current.value * 100).toFixed(1);
result.push({
step: `${current.name} → ${next.name}`,
lost,
lossRate: parseFloat(lossRate)
});
}
return result;
}
/**
* 识别关键流失点
*/
findCriticalDropoff(): { step: string; lossRate: number } {
const losses = this.calculateLoss();
// 找到流失率最高的步骤
const criticalStep = losses.reduce((max, current) =>
current.lossRate > max.lossRate ? current : max
);
return criticalStep;
}
/**
* 生成优化建议
*/
generateRecommendations(): string[] {
const losses = this.calculateLoss();
const recommendations: string[] = [];
losses.forEach(loss => {
if (loss.lossRate > 50) {
recommendations.push(
`⚠️ 高流失警告: ${loss.step} (流失${loss.lossRate}%)\n` +
` 建议: 深入分析该环节的用户体验问题`
);
}
});
const critical = this.findCriticalDropoff();
recommendations.push(
`🎯 优先优化: ${critical.step}\n` +
` 这是最大的流失点,优化效果最显著`
);
return recommendations;
}
}
// 使用示例
const analyzer = new FunnelLossAnalyzer([
{ name: '访问首页', value: 10000 },
{ name: '浏览商品', value: 6000 },
{ name: '加入购物车', value: 2000 },
{ name: '提交订单', value: 800 },
{ name: '完成支付', value: 500 }
]);
const losses = analyzer.calculateLoss();
console.table(losses);
const critical = analyzer.findCriticalDropoff();
console.log('关键流失点:', critical);
const recommendations = analyzer.generateRecommendations();
console.log(recommendations.join('\n\n'));1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
输出结果:
┌─────────────────────────────┬──────┬──────────┐
│ step │ lost │ lossRate │
├─────────────────────────────┼──────┼──────────┤
│ 访问首页 → 浏览商品 │ 4000 │ 40.0 │
│ 浏览商品 → 加入购物车 │ 4000 │ 66.7 │
│ 加入购物车 → 提交订单 │ 1200 │ 60.0 │
│ 提交订单 → 完成支付 │ 300 │ 37.5 │
└─────────────────────────────┴──────┴──────────┘
关键流失点: { step: '浏览商品 → 加入购物车', lossRate: 66.7 }
优化建议:
⚠️ 高流失警告: 浏览商品 → 加入购物车 (流失66.7%)
建议: 深入分析该环节的用户体验问题
⚠️ 高流失警告: 加入购物车 → 提交订单 (流失60.0%)
建议: 深入分析该环节的用户体验问题
🎯 优先优化: 浏览商品 → 加入购物车
这是最大的流失点,优化效果最显著1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
完整案例
电商转化漏斗分析系统
typescript
class EcommerceFunnelDashboard {
private funnelChart: echarts.ECharts;
private trendChart: echarts.ECharts;
private breakdownChart: echarts.ECharts;
constructor() {
this.funnelChart = echarts.init(document.getElementById('funnel-chart'));
this.trendChart = echarts.init(document.getElementById('trend-chart'));
this.breakdownChart = echarts.init(document.getElementById('breakdown-chart'));
}
async init() {
// 加载数据
const funnelData = await this.loadFunnelData();
const trendData = await this.loadTrendData();
const channelData = await this.loadChannelData();
// 渲染图表
this.renderFunnel(funnelData);
this.renderTrend(trendData);
this.renderBreakdown(channelData);
// 绑定交互
this.bindInteractions();
}
private renderFunnel(data: any[]) {
// 计算转化率
const calculateRate = (index: number) => {
if (index === 0) return 100;
return ((data[index].value / data[index - 1].value) * 100).toFixed(1);
};
this.funnelChart.setOption({
title: {
text: '购物流程转化漏斗',
subtext: `整体转化率: ${(data[data.length - 1].value / data[0].value * 100).toFixed(2)}%`,
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: (params) => {
const rate = calculateRate(params.dataIndex);
const prevValue = params.dataIndex > 0
? data[params.dataIndex - 1].value
: params.value;
const lost = prevValue - params.value;
return `
<div style="padding: 8px;">
<b style="font-size: 14px;">${params.name}</b><br/>
<span style="color: #999;">用户数:</span> ${params.value.toLocaleString()}<br/>
<span style="color: #52c41a;">转化率:</span> ${rate}%<br/>
<span style="color: #ff4d4f;">流失:</span> ${lost.toLocaleString()}人
</div>
`;
}
},
series: [{
name: '转化漏斗',
type: 'funnel',
left: '10%',
top: 80,
bottom: 60,
width: '80%',
sort: 'descending',
gap: 2,
label: {
show: true,
position: 'inside',
formatter: (params) => {
const rate = calculateRate(params.dataIndex);
return `{name|${params.name}}\n{value|${params.value}人} {rate|${rate}%}`;
},
rich: {
name: {
fontSize: 13,
fontWeight: 'bold',
color: '#fff',
lineHeight: 20
},
value: {
fontSize: 12,
color: '#fff',
padding: [4, 0, 0, 0]
},
rate: {
fontSize: 11,
color: '#ffd700',
padding: [4, 0, 0, 4]
}
}
},
itemStyle: {
borderColor: '#fff',
borderWidth: 2,
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.3)'
},
emphasis: {
label: {
fontSize: 15
},
itemStyle: {
shadowBlur: 20
}
},
data: data
}]
});
}
private renderTrend(trendData: any[]) {
this.trendChart.setOption({
title: {
text: '转化率趋势(近30天)',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['注册转化率', '付费转化率'],
top: 30
},
xAxis: {
type: 'category',
data: trendData.map(d => d.date.substring(5)) // MM-DD
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '注册转化率',
type: 'line',
data: trendData.map(d => d.registrationRate),
smooth: true,
symbol: 'circle',
symbolSize: 6,
lineStyle: {
width: 2,
color: '#5470c6'
},
areaStyle: {
opacity: 0.1,
color: '#5470c6'
}
},
{
name: '付费转化率',
type: 'line',
data: trendData.map(d => d.paymentRate),
smooth: true,
symbol: 'circle',
symbolSize: 6,
lineStyle: {
width: 2,
color: '#91cc75'
},
areaStyle: {
opacity: 0.1,
color: '#91cc75'
}
}
]
});
}
private renderBreakdown(channelData: any) {
const channels = Object.keys(channelData);
const registrationRates = channels.map(ch =>
(channelData[ch].registrations / channelData[ch].visits * 100).toFixed(1)
);
const paymentRates = channels.map(ch =>
(channelData[ch].payments / channelData[ch].registrations * 100).toFixed(1)
);
this.breakdownChart.setOption({
title: {
text: '各渠道转化对比',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['注册转化率', '付费转化率'],
top: 30
},
xAxis: {
type: 'category',
data: channels
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
series: [
{
name: '注册转化率',
type: 'bar',
data: registrationRates,
itemStyle: {
color: '#5470c6'
},
label: {
show: true,
formatter: '{c}%'
}
},
{
name: '付费转化率',
type: 'bar',
data: paymentRates,
itemStyle: {
color: '#91cc75'
},
label: {
show: true,
formatter: '{c}%'
}
}
]
});
}
private bindInteractions() {
// 点击漏斗图,显示该环节详细信息
this.funnelChart.on('click', (params) => {
console.log('点击环节:', params.name);
this.showStepDetail(params.name, params.value);
});
}
private showStepDetail(stepName: string, userCount: number) {
// 弹出详情面板
const modal = document.getElementById('detail-modal');
if (modal) {
document.getElementById('step-name').textContent = stepName;
document.getElementById('user-count').textContent = userCount.toLocaleString();
modal.style.display = 'block';
}
}
private async loadFunnelData(): Promise<any[]> {
const response = await fetch('/api/analytics/funnel');
return response.json();
}
private async loadTrendData(): Promise<any[]> {
const response = await fetch('/api/analytics/funnel/trend?days=30');
return response.json();
}
private async loadChannelData(): Promise<any> {
const response = await fetch('/api/analytics/funnel/channels');
return response.json();
}
}
// 启动仪表盘
const dashboard = new EcommerceFunnelDashboard();
dashboard.init();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
最佳实践总结
🎯 设计原则
- 突出关键指标: 转化率、流失率要醒目显示
- 提供上下文: 与历史数据、行业基准对比
- 支持多维拆解: 按渠道、设备、地区等维度分析
- ** actionable**: 明确指出优化方向和优先级
- 实时监控: 建立预警机制,及时发现异常
📊 技术要点
| 功能 | 配置 | 说明 |
|---|---|---|
| 排序 | sort: 'descending' | 从上到下递减 |
| 标签 | label.position: 'inside' | 内部显示 |
| 富文本 | rich样式对象 | 自定义格式 |
| 对比 | 双漏斗并排 | A/B测试 |
| 交互 | chart.on('click') | 查看详情 |
⚡ 分析框架
typescript
// 1. 计算整体转化率
overallConversion = finalStep / firstStep;
// 2. 计算每步转化率
stepConversion = currentStep / previousStep;
// 3. 识别最大流失点
maxDropoff = max(previousStep - currentStep);
// 4. 多维度拆解
byChannel, byDevice, byRegion...
// 5. 趋势监控
daily/weekly/monthly trends...
// 6. 生成优化建议
recommendations = analyze(dropoffs, trends, benchmarks);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
🔧 常见问题
Q1: 如何判断转化率是否正常?
A: 与以下基准对比:
- 历史同期数据
- 行业平均水平
- 相似产品表现
Q2: 流失率高怎么办?
A:
- 定位具体环节
- 收集用户反馈
- 分析技术日志
- A/B测试优化方案
Q3: 如何提高漏斗图可读性?
A:
- 限制步骤数量(5-7步为宜)
- 使用颜色区分不同阶段
- 添加清晰的标签和数值
- 提供tooltip详细说明
延伸阅读
- ECharts 漏斗图API
- 数据分析方法论
- A/B测试实战
- 用户增长黑客
总结: 漏斗分析的核心价值不是展示数据,而是指导行动。通过精准识别流失点、多维度拆解、趋势监控,可以为产品优化提供明确的方向。记住:每一个流失点背后,都隐藏着产品改进的机会。
