如何用PHP+MySQL结合Chart.js渲染X轴为近24小时的图表
解决Chart.js X轴重复显示01:00并展示最近24小时的问题
问题根源
当前X轴重复显示01:00,是因为查询数据时未限定最近24小时的连续时间范围,导致不同日期的同一小时(如昨天和今天的01:00)被重复统计,或者部分小时数据缺失后标签未补全。
解决方案
1. 修正PHP端数据查询逻辑
确保生成最近24小时的完整小时序列(即使某小时无报告也补0),再合并数据库查询结果:
// 生成最近24小时的连续小时标签(从23小时前到当前小时) $hourlyLabels = []; for ($i = 23; $i >= 0; $i--) { $currentHour = date('H:00', strtotime("-{$i} hours")); $hourlyLabels[$currentHour] = 0; } // 查询数据库中最近24小时的每小时报告数 $dbQuery = "SELECT DATE_FORMAT(date_creation, '%H:00') AS hour, COUNT(*) AS reportCount FROM signalements WHERE date_creation >= DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY hour ORDER BY hour"; $result = mysqli_query($yourDbConnection, $dbQuery); // 将查询结果填充到预设的小时序列中 while ($row = mysqli_fetch_assoc($result)) { if (isset($hourlyLabels[$row['hour']])) { $hourlyLabels[$row['hour']] = $row['reportCount']; } } // 提取最终的标签和数据,转为JSON供前端使用 $chartData = json_encode([ 'labels' => array_keys($hourlyLabels), 'data' => array_values($hourlyLabels) ]);
2. 优化Chart.js前端配置
使用分类轴或时间轴确保X轴标签正确展示:
方案一:使用分类轴(简单直接)
const chartCtx = document.getElementById('reportChart').getContext('2d'); const chartData = <?php echo $chartData; ?>; new Chart(chartCtx, { type: 'bar', // 可根据需求更换为line等类型 data: { labels: chartData.labels, datasets: [{ label: '每小时报告数', data: chartData.data, backgroundColor: 'rgba(54, 162, 235, 0.5)', borderColor: 'rgba(54, 162, 235, 1)', borderWidth: 1 }] }, options: { scales: { x: { ticks: { autoSkip: true, maxRotation: 45, minRotation: 45 } }, y: { beginAtZero: true, title: { display: true, text: '报告数' } } } } });
方案二:使用时间轴(更精准的时间序列控制)
需先引入Chart.js的时间适配器(如chartjs-adapter-date-fns),再配置时间轴:
new Chart(chartCtx, { type: 'bar', data: { datasets: [{ label: '每小时报告数', // 将标签转为时间对象,适配时间轴 data: chartData.labels.map((label, index) => ({ x: new Date(Date.now() - (23 - index) * 60 * 60 * 1000), y: chartData.data[index] })), backgroundColor: 'rgba(54, 162, 235, 0.5)', borderColor: 'rgba(54, 162, 235, 1)', borderWidth: 1 }] }, options: { scales: { x: { type: 'time', time: { unit: 'hour', displayFormats: { hour: 'HH:00' }, // 限定时间范围为最近24小时 min: new Date(Date.now() - 24 * 60 * 60 * 1000), max: new Date() }, ticks: { maxRotation: 45, minRotation: 45 } }, y: { beginAtZero: true, title: { display: true, text: '报告数' } } } } });
效果说明
修改后X轴将展示从23小时前到当前时间的连续小时标签(如00:00、01:00...23:00),不会出现重复的小时值,且完整覆盖最近24小时的报告数据。
内容的提问来源于stack exchange,提问作者aMoN
相关产品推荐
相关产品推荐

