非常好的选择!让我们来实现这些改进,进一步增强我们的实时分析功能和用户分群分析。

第三十三部分:改进实时分析可视化和用户分群分析

  1. 改进实时分析可视化

首先,我们需要在服务器端收集更多实时数据。更新 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>
  1. 用户分群分析

首先,我们需要在数据库中存储更多的用户行为数据。更新 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>

这些改进实现了以下功能:

  1. 改进实时分析可视化:

    • 显示当前活跃用户数量
    • 展示最活跃的页面及其访问量
    • 使用 WebSocket 实时更新数据
  2. 用户分群分析:

    • 基于设备类型(桌面、移动、平板)进行分群
    • 基于浏览器类型进行分群
    • 基于用户参与度(低、中、高)进行分群
    • 使用饼图可视化展示各个分群的比例

主要改进包括:

  • 提供了更直观的实时数据展示,让管理员能够即时了解网站的活跃状况
  • 实现了基于用户行为数据的分群分析,帮助管理员更好地理解用户群体的构成
  • 使用 Plotly. Js 创建交互式图表,提升了数据可视化效果

接下来的步骤可以包括:

  1. 优化数据收集和存储方式,以处理更大规模的用户行为数据
  2. 实现更复杂的用户分群算法,如基于用户行为模式的聚类分析
  3. 添加更多的实时指标,如实时转化率、实时收入等
  4. 实现用户行为预测功能,如预测用户流失风险
  5. 添加 A/B 测试功能,以优化网站内容和用户体验

你希望继续深入哪个方向,或者有其他想法吗?