非常好的选择!让我们来实现这些改进,进一步增强我们的实时分析功能和用户分群分析。
第三十三部分:改进实时分析可视化和用户分群分析
- 改进实时分析可视化
首先,我们需要在服务器端收集更多实时数据。更新 src/routes/analytics.ts:
import { Elysia } from "elysia";
import { websocket } from "@elysiajs/websocket";
import { db } from "../db";
import { users, posts, postViews } from "../db/schema";
let activeUsers = new Set();
export const analyticsRoutes = new Elysia()
.use(websocket())
.ws("/ws", {
open(ws) {
activeUsers.add(ws.id);
broadcastActiveUsers();
},
close(ws) {
activeUsers.delete(ws.id);
broadcastActiveUsers();
},
message(ws, message) {
// 处理接收到的消息
},
})
.get("/api/real-time-stats", async () => {
const activePagesResult = await db
.select({
path: postViews.path,
count: sql`count(*)`.as("count"),
})
.from(postViews)
.where(sql`${postViews.lastViewed} > datetime('now', '-5 minutes')`)
.groupBy(postViews.path)
.orderBy(sql`count(*)`, "desc")
.limit(5)
.all();
return {
activeUsers: activeUsers.size,
activePages: activePagesResult,
};
})
.post("/api/log-behavior", async ({ body, server }) => {
// ... 保存行为数据的代码
// 发送实时更新
broadcastUpdate(server, {
type: 'behavior-update',
data: body
});
return { success: true };
});
function broadcastActiveUsers() {
broadcastUpdate(server, {
type: 'active-users-update',
data: { activeUsers: activeUsers.size }
});
}
function broadcastUpdate(server, data) {
server.websocket.clients.forEach(client => {
client.send(JSON.stringify(data));
});
}然后,更新 src/views/analytics.eta 以显示这些实时数据:
<% layout('./layouts/main.eta', { title: 'Analytics' }) %>
<h1>Real-time Analytics Dashboard</h1>
<div class="real-time-stats">
<div class="stat-box">
<h2>Active Users</h2>
<p id="active-users-count">0</p>
</div>
<div class="stat-box">
<h2>Top Active Pages</h2>
<ul id="active-pages-list"></ul>
</div>
</div>
<!-- 保留之前的图表和表格 -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script>
const socket = new WebSocket('ws://localhost:3000/ws');
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === 'active-users-update') {
document.getElementById('active-users-count').textContent = data.data.activeUsers;
} else if (data.type === 'behavior-update') {
updateCharts(data.data);
}
};
function updateCharts(data) {
// 更新图表的逻辑
}
// 定期获取实时统计数据
setInterval(async function() {
const response = await fetch('/api/real-time-stats');
const stats = await response.json();
document.getElementById('active-users-count').textContent = stats.activeUsers;
const activePagesList = document.getElementById('active-pages-list');
activePagesList.innerHTML = '';
stats.activePages.forEach(page => {
const li = document.createElement('li');
li.textContent = `${page.path}: ${page.count} views`;
activePagesList.appendChild(li);
});
}, 5000); // 每5秒更新一次
</script>
<style>
.real-time-stats {
display: flex;
justify-content: space-around;
margin-bottom: 2em;
}
.stat-box {
background-color: #f0f0f0;
border-radius: 8px;
padding: 1em;
text-align: center;
}
</style>- 用户分群分析
首先,我们需要在数据库中存储更多的用户行为数据。更新 src/db/schema.ts:
export const userBehaviors = sqliteTable("user_behaviors", {
id: integer("id").primaryKey(),
userId: integer("user_id").references(() => users.id),
pageViews: text("page_views"),
clickPath: text("click_path"),
totalTimeSpent: real("total_time_spent"),
deviceType: text("device_type"),
browserType: text("browser_type"),
timestamp: integer("timestamp", { mode: "timestamp" })
});创建相应的迁移文件并运行迁移。
更新 public/js/analytics.js 以收集设备和浏览器信息:
// ... 保留之前的代码
// 获取设备和浏览器信息
function getDeviceInfo() {
const ua = navigator.userAgent;
let deviceType = "desktop";
if (/mobile/i.test(ua)) deviceType = "mobile";
else if (/tablet/i.test(ua)) deviceType = "tablet";
let browserType = "unknown";
if (/firefox/i.test(ua)) browserType = "firefox";
else if (/chrome/i.test(ua)) browserType = "chrome";
else if (/safari/i.test(ua)) browserType = "safari";
else if (/edge/i.test(ua)) browserType = "edge";
return { deviceType, browserType };
}
// 更新发送数据的部分
setInterval(function() {
const { deviceType, browserType } = getDeviceInfo();
fetch('/api/log-behavior', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...behaviorData,
deviceType,
browserType
})
});
// 重置数据
behaviorData = {
pageViews: {},
clickPath: [],
totalTimeSpent: 0
};
}, 60000);现在,让我们在 src/routes/analytics.ts 中添加用户分群分析功能:
import { Elysia } from "elysia";
import { db } from "../db";
import { userBehaviors, users } from "../db/schema";
export const analyticsRoutes = new Elysia()
// ... 保留之前的路由
.get("/user-segments", async () => {
const deviceSegments = await db
.select({
deviceType: userBehaviors.deviceType,
count: sql`count(distinct ${userBehaviors.userId})`.as("count"),
})
.from(userBehaviors)
.groupBy(userBehaviors.deviceType)
.all();
const browserSegments = await db
.select({
browserType: userBehaviors.browserType,
count: sql`count(distinct ${userBehaviors.userId})`.as("count"),
})
.from(userBehaviors)
.groupBy(userBehaviors.browserType)
.all();
const engagementSegments = await db
.select({
segment: sql`
CASE
WHEN avg(${userBehaviors.totalTimeSpent}) < 60 THEN 'Low Engagement'
WHEN avg(${userBehaviors.totalTimeSpent}) < 300 THEN 'Medium Engagement'
ELSE 'High Engagement'
END
`.as("segment"),
count: sql`count(distinct ${userBehaviors.userId})`.as("count"),
})
.from(userBehaviors)
.groupBy(sql`segment`)
.all();
return {
deviceSegments,
browserSegments,
engagementSegments,
};
});最后,在 src/views/analytics.eta 中添加用户分群分析的可视化:
<h2>User Segments</h2>
<div id="device-segments-chart"></div>
<div id="browser-segments-chart"></div>
<div id="engagement-segments-chart"></div>
<script>
// ... 保留之前的代码
async function loadUserSegments() {
const response = await fetch('/user-segments');
const segments = await response.json();
Plotly.newPlot('device-segments-chart', [{
values: segments.deviceSegments.map(s => s.count),
labels: segments.deviceSegments.map(s => s.deviceType),
type: 'pie'
}], {
title: 'User Segments by Device Type'
});
Plotly.newPlot('browser-segments-chart', [{
values: segments.browserSegments.map(s => s.count),
labels: segments.browserSegments.map(s => s.browserType),
type: 'pie'
}], {
title: 'User Segments by Browser Type'
});
Plotly.newPlot('engagement-segments-chart', [{
values: segments.engagementSegments.map(s => s.count),
labels: segments.engagementSegments.map(s => s.segment),
type: 'pie'
}], {
title: 'User Segments by Engagement Level'
});
}
loadUserSegments();
</script>这些改进实现了以下功能:
-
改进实时分析可视化:
- 显示当前活跃用户数量
- 展示最活跃的页面及其访问量
- 使用 WebSocket 实时更新数据
-
用户分群分析:
- 基于设备类型(桌面、移动、平板)进行分群
- 基于浏览器类型进行分群
- 基于用户参与度(低、中、高)进行分群
- 使用饼图可视化展示各个分群的比例
主要改进包括:
- 提供了更直观的实时数据展示,让管理员能够即时了解网站的活跃状况
- 实现了基于用户行为数据的分群分析,帮助管理员更好地理解用户群体的构成
- 使用 Plotly. Js 创建交互式图表,提升了数据可视化效果
接下来的步骤可以包括:
- 优化数据收集和存储方式,以处理更大规模的用户行为数据
- 实现更复杂的用户分群算法,如基于用户行为模式的聚类分析
- 添加更多的实时指标,如实时转化率、实时收入等
- 实现用户行为预测功能,如预测用户流失风险
- 添加 A/B 测试功能,以优化网站内容和用户体验
你希望继续深入哪个方向,或者有其他想法吗?