调整趋势图功能,加入了查询数据库,分析群聊聊天数量的功能

This commit is contained in:
liuwei
2025-03-26 14:17:11 +08:00
parent 9c7a8e80f4
commit 82ab98c787
2 changed files with 74 additions and 91 deletions

View File

@@ -14,6 +14,8 @@
<script src="https://unpkg.com/element-ui/lib/index.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- Axios --> <!-- Axios -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- ECharts -->
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style> <style>
body { body {
margin: 0; margin: 0;

View File

@@ -151,8 +151,8 @@
<div v-else> <div v-else>
<div class="chart-container"> <div class="chart-container">
<h3>消息数量趋势</h3> <h3>消息数量趋势</h3>
<!-- 使用固定ID --> <!-- 直接在Vue模板中创建图表容器 -->
<div id="message-trend-chart-container" style="width: 100%; height: 300px;"></div> <div ref="trendChartContainer" style="width: 100%; height: 300px;"></div>
</div> </div>
<div style="margin-top: 20px; text-align: center;"> <div style="margin-top: 20px; text-align: center;">
<el-radio-group v-model="trendDays" @change="loadMessageTrend"> <el-radio-group v-model="trendDays" @change="loadMessageTrend">
@@ -426,10 +426,8 @@
// 对话框打开后的回调 // 对话框打开后的回调
onTrendDialogOpened() { onTrendDialogOpened() {
console.log('对话框已打开'); console.log('对话框已打开');
// 延迟加载确保DOM已渲染 // 直接加载数据,不使用延迟
setTimeout(() => { this.loadMessageTrend();
this.loadMessageTrend();
}, 100);
}, },
loadMessageTrend() { loadMessageTrend() {
@@ -438,11 +436,9 @@
axios.get(`/api/robot/group/${this.currentGroupId}/message_trend?days=${this.trendDays}`) axios.get(`/api/robot/group/${this.currentGroupId}/message_trend?days=${this.trendDays}`)
.then(response => { .then(response => {
if (response.data.success) { if (response.data.success) {
// 增加延迟时间 // 直接渲染表格显示数据
setTimeout(() => { this.renderTrendTable(response.data.data);
this.renderTrendChart(response.data.data); this.trendLoading = false;
this.trendLoading = false;
}, 500); // 增加到500毫秒
} else { } else {
this.$message.error('加载消息趋势失败'); this.$message.error('加载消息趋势失败');
this.trendLoading = false; this.trendLoading = false;
@@ -455,105 +451,90 @@
}); });
}, },
renderTrendChart(data) { renderTrendTable(data) {
try { try {
console.log('开始渲染图表'); console.log('开始渲染趋势数据');
// 使用固定ID获取容器元素 // 获取容器元素
const container = document.getElementById('message-trend-chart-container'); const container = this.$refs.trendChartContainer;
if (!container) { if (!container) {
console.error('找不到图表容器ID: message-trend-chart-container'); console.error('找不到图表容器');
this.$message.error('无法找到图表容器,请尝试重新打开对话框'); this.$message.error('无法找到图表容器,请尝试重新打开对话框');
return; return;
} }
console.log('找到图表容器:', container);
// 清空容器 // 清空容器
container.innerHTML = ''; container.innerHTML = '';
// 动态创建Canvas元素
const canvas = document.createElement('canvas');
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
container.appendChild(canvas);
console.log('已创建Canvas元素');
const ctx = canvas.getContext('2d');
// 销毁旧图表
if (this.charts.trendChart) {
this.charts.trendChart.destroy();
}
// 确保charts对象存在
if (!this.charts) {
this.charts = {};
}
// 准备数据 // 准备数据
const labels = data.dates || []; const labels = data.dates || [];
const messageData = (data.counts || []).map(count => parseInt(count) || 0); const messageData = (data.counts || []).map(count => parseInt(count) || 0);
// 检查Chart是否存在 if (labels.length === 0) {
if (typeof Chart === 'undefined') { container.innerHTML = '<div style="text-align: center; padding: 20px;">暂无数据</div>';
console.error('Chart.js未加载');
this.$message.error('图表库未加载,请检查网络连接');
return; return;
} }
// 创建新图 // 创建表格显示数据
this.charts.trendChart = new Chart(ctx, { let tableHtml = `
type: 'line', <table class="el-table" style="width: 100%;">
data: { <thead>
labels: labels, <tr>
datasets: [{ <th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">日期</th>
label: '消息数量', <th style="padding: 12px 0; text-align: center; background-color: #f5f7fa; color: #606266; font-weight: bold; border-bottom: 1px solid #ebeef5;">消息数量</th>
data: messageData, </tr>
backgroundColor: 'rgba(75, 192, 192, 0.2)', </thead>
borderColor: 'rgba(75, 192, 192, 1)', <tbody>
borderWidth: 2, `;
tension: 0.3,
fill: true for (let i = 0; i < labels.length; i++) {
}] tableHtml += `
}, <tr>
options: { <td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">${labels[i]}</td>
responsive: true, <td style="padding: 12px 0; text-align: center; border-bottom: 1px solid #ebeef5;">${messageData[i]}</td>
maintainAspectRatio: false, </tr>
plugins: { `;
title: { }
display: false
}, tableHtml += `
tooltip: { </tbody>
mode: 'index', </table>
intersect: false `;
},
legend: { container.innerHTML = tableHtml;
position: 'top',
} // 添加简单的可视化条形图
}, const maxValue = Math.max(...messageData);
scales: { let chartHtml = `
y: { <div style="margin-top: 20px;">
beginAtZero: true, <h4 style="margin: 10px 0;">消息数量可视化</h4>
title: { <div style="display: flex; flex-direction: column; gap: 5px;">
display: true, `;
text: '消息数量'
} for (let i = 0; i < labels.length; i++) {
}, const percentage = (messageData[i] / maxValue) * 100;
x: { chartHtml += `
ticks: { <div style="display: flex; align-items: center; margin-bottom: 5px;">
maxRotation: 45, <span style="width: 80px; text-align: right; margin-right: 10px;">${labels[i]}</span>
minRotation: 45 <div style="flex-grow: 1; display: flex; align-items: center;">
} <div style="background-color: rgba(75, 192, 192, 0.7); height: 20px; width: ${percentage}%; min-width: 2px; border-radius: 2px;"></div>
} <span style="margin-left: 10px;">${messageData[i]}</span>
} </div>
} </div>
}); `;
}
chartHtml += `
</div>
</div>
`;
container.innerHTML += chartHtml;
} catch (error) { } catch (error) {
console.error('渲染图表出错:', error); console.error('渲染趋势数据出错:', error);
this.$message.error('渲染图表出错: ' + error.message); this.$message.error('渲染趋势数据出错: ' + error.message);
this.trendLoading = false;
} }
} }
} }