You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Chart.js折线图中动态展示截至今日的近两年SQL数据

解决方案:动态生成近24个月的支出数据与图表

我来帮你搞定这个动态时间范围的需求,核心思路是用日期类自动计算近24个月的区间,彻底摆脱固定自然年的限制,同时简化代码结构:

一、重构PHP数据获取逻辑

我们可以利用PHP的DateTime类动态生成近24个月的时间节点,统一查询每个月的数据,不用再分开处理去年和今年:

<?php 
$conn = new mysqli(blah blah blah); 
if ($conn->connect_error) { 
    die("Connection failed: " . $conn->connect_error); 
} 

// 初始化当前日期,计算起始时间(往前推24个月)
$currentDate = new DateTime();
$startDate = (clone $currentDate)->sub(new DateInterval('P24M'));

$monthlyData = [];
$chartLabels = [];

// 遍历近24个月
for ($i = 0; $i < 24; $i++) {
    // 计算当前循环对应的月份
    $targetMonth = (clone $startDate)->add(new DateInterval("P{$i}M"));
    $year = $targetMonth->format('Y');
    $month = $targetMonth->format('n'); // 数字格式的月份(1-12)
    
    // 生成图表标签(例如:Feb 2023)
    $chartLabels[] = $targetMonth->format('M Y');
    
    // 用预处理语句查询当月支出,更安全防注入
    $sql = "SELECT SUM(Contracts.Sum_Approved) AS total 
            FROM Contracts 
            JOIN Budgets ON Contracts.Budget = Budgets.BudgetID 
            WHERE MONTH(Contracts.Decision_Date) = ? 
              AND YEAR(Contracts.Decision_Date) = ? 
              AND Contracts.owner = ? 
              AND Contracts.Archived = 0 
              AND Contracts.Budget = ?";
    
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("iiii", $month, $year, $userid, $budget);
    $stmt->execute();
    $result = $stmt->get_result();
    $row = $result->fetch_array();
    
    // 处理空数据,避免null导致图表异常
    $monthlyData[] = $row['total'] ?? 0;
}

// 清理资源
$stmt->close();
$conn->close();
?>

优化亮点:

  • 用DateTime自动计算时间区间,完全不用手动判断年份月份,适配任意当前日期
  • 预处理语句替代字符串拼接,提升代码安全性
  • 把标签和数据统一存入数组,后续直接传递给Chart.js,砍掉了一堆冗余的单个月份变量

二、简化Chart.js配置

现在直接把PHP生成的数组传入Chart.js,不用再手动拼接24个数据项:

var ctx = document.getElementById("myAreaChart"); 
var myLineChart = new Chart(ctx, { 
    type: 'line', 
    data: { 
        labels: <?php echo json_encode($chartLabels); ?>,
        datasets: [{ 
            label: "Agreed Funding", 
            lineTension: 0.3, 
            backgroundColor: "rgba(78, 115, 223, 0.05)", 
            borderColor: "rgba(78, 115, 223, 1)", 
            pointRadius: 3, 
            pointBackgroundColor: "rgba(78, 115, 223, 1)", 
            pointBorderColor: "rgba(78, 115, 223, 1)", 
            pointHoverRadius: 3, 
            pointHoverBackgroundColor: "rgba(78, 115, 223, 1)", 
            pointHoverBorderColor: "rgba(78, 115, 223, 1)", 
            pointHitRadius: 10, 
            pointBorderWidth: 2, 
            data : <?php echo json_encode($monthlyData); ?>,
        }], 
    }, 
    options: { 
        maintainAspectRatio: false, 
        layout: { 
            padding: { left: 10, right: 25, top: 25, bottom: 0 } 
        }, 
        scales: { 
            xAxes: [{ 
                time: { unit: 'month' }, // 改为month更贴合我们的按月统计维度
                gridLines: { display: true, drawBorder: false }, 
                ticks: { maxTicksLimit: 7 } 
            }], 
            yAxes: [{ 
                ticks: { 
                    maxTicksLimit: 5, 
                    padding: 10, 
                    callback: function(value, index, values) { 
                        return '£' + number_format(value); 
                    } 
                }, 
                gridLines: { 
                    color: "rgb(234, 236, 244)", 
                    zeroLineColor: "rgb(234, 236, 244)", 
                    drawBorder: false, 
                    borderDash: [2], 
                    zeroLineBorderDash: [2] 
                } 
            }], 
        }, 
        legend: { display: false }, 
        tooltips: { 
            backgroundColor: "rgb(255,255,255)", 
            bodyFontColor: "#858796", 
            titleMarginBottom: 10, 
            titleFontColor: '#6e707e', 
            titleFontSize: 14, 
            borderColor: '#dddfeb', 
            borderWidth: 1, 
            xPadding: 15, 
            yPadding: 15, 
            displayColors: false, 
            intersect: false, 
            mode: 'index', 
            caretPadding: 10, 
            callbacks: { 
                label: function(tooltipItem, chart) { 
                    var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || ''; 
                    return datasetLabel + ': £' + number_format(tooltipItem.yLabel); 
                } 
            } 
        } 
    } 
});

配置调整说明:

  • 用json_encode直接把PHP数组转成JS数组,代码简洁不易出错
  • 调整xAxes.time.unit为month,让图表的时间轴渲染更准确
  • 自动适配动态生成的时间范围,不管今天是几月,都会展示最近24个月的完整数据

这样调整后,你的图表就会自动展示从当前日期往前推24个月到当前月的所有支出数据,完全实现动态的近两年范围,而且代码结构更清晰、安全,没有繁琐的条件判断。

内容的提问来源于stack exchange,提问作者user5838014

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:12:35