PHP结合MySQL绘制多独立图表失败,求可行解决方案
问题描述
MySQL数据表
| lokasi | jan | feb |
|---|---|---|
| sukajaya | 652 | 427 |
| kenten laut | 123 | 532 |
| mariana | 126 | 439 |
我想在PHP中生成多个独立柱状图(不是多系列柱状图),每个图表对应一个月份(比如jan、feb),都用lokasi作为标签,但直接复制现有代码添加新图表的方式无法生效,请问该怎么调整代码?
当前使用的代码
<?php $con = new mysqli('localhost','root','','dinkes'); $query = $con->query("SELECT * FROM data2022"); foreach($query as $data) { $lokasi[] = $data['lokasi']; $januari[] = $data['jan']; ?> <div style="width: 500px;"> <canvas id="myChart1"></canvas> <script> const labels = <?php echo json_encode($lokasi) ?>; const data = { labels: labels, datasets: [{ label: 'Pengidap Penyakit ISPA Januari', data: <?php echo json_encode($januari) ?>, backgroundColor: [] }] }; const config = { type: 'bar', data: data, options: { scales: { y: { beginAtZero: true } } }, }; var myChart1 = new Chart( document.getElementById('myChart1'), config ); </script> </div> </body> </html>
解决方案
问题根源
你当前代码的核心问题有两个:
- 循环生成了多个ID相同的
canvas(都是myChart1),JavaScript获取元素时只会匹配第一个,后续图表无法渲染 - 代码结构混乱,循环内重复输出JS逻辑,且没有正确处理多月份的数据拆分
调整后的完整代码
<?php $con = new mysqli('localhost','root','','dinkes'); $query = $con->query("SELECT * FROM data2022"); // 先统一整理所有数据 $lokasi = []; // 定义需要生成图表的月份及对应标签 $monthData = [ 'jan' => ['label' => 'Pengidap Penyakit ISPA Januari', 'data' => []], 'feb' => ['label' => 'Pengidap Penyakit ISPA Februari', 'data' => []] ]; foreach($query as $data) { $lokasi[] = $data['lokasi']; $monthData['jan']['data'][] = $data['jan']; $monthData['feb']['data'][] = $data['feb']; } ?> <!DOCTYPE html> <html> <body> <?php // 循环生成每个月份的图表容器 $chartIndex = 1; foreach($monthData as $info) { ?> <div style="width: 500px; margin-bottom: 30px;"> <h3><?php echo $info['label'] ?></h3> <canvas id="myChart<?php echo $chartIndex ?>"></canvas> </div> <?php $chartIndex++; } ?> <!-- 统一加载Chart.js并初始化所有图表 --> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> const labels = <?php echo json_encode($lokasi) ?>; const chartConfigs = <?php echo json_encode($monthData) ?>; let chartIndex = 1; for(const key in chartConfigs) { const config = { type: 'bar', data: { labels: labels, datasets: [{ label: chartConfigs[key].label, data: chartConfigs[key].data, backgroundColor: ['rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)'] }] }, options: { scales: { y: { beginAtZero: true } } } }; new Chart(document.getElementById(`myChart${chartIndex}`), config); chartIndex++; } </script> </body> </html>
关键优化点
- 唯一ID标识:每个
canvas使用递增数字作为ID后缀,确保每个图表容器唯一 - 数据预整理:一次性从数据库取出所有数据并按月份拆分,避免循环内重复操作
- JS逻辑集中:把Chart.js引用和图表初始化代码放在页面底部,减少冗余,提升加载效率
- 模块化配置:将月份标签和数据封装成配置对象,通过循环批量生成图表,代码更易维护
内容的提问来源于stack exchange,提问作者Bale Ez
相关产品推荐
相关产品推荐

