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

无法通过AJAX更新折线图数据 技术求助(附代码)

折线图AJAX更新故障排查与修复

问题原因分析

  • 前端事件绑定错误:下拉选择框ID为selectMonth,但JS代码监听的是不存在的#monthDropdown元素,导致选择月份后无法触发AJAX请求。
  • 表单提交默认行为未阻止:按钮为type="submit",点击后会触发表单提交刷新页面,打断AJAX流程。
  • 变量大小写与拼写错误:
    • AJAX成功回调中,将参数data误写为大写Data,且后端返回字段为Dates,代码中写成date;
    • 定义变量Dates_Values后,使用时误写为Dates_Value,拼写不一致。
  • 后端数据逻辑错误:当前后端返回的是该月份所有日期的列表和总交互数,而非按日期分组的每日交互数,无法生成折线图所需的对应数据。
  • 日期格式与排序问题:后端直接返回DateTime对象,前端解析可能出现格式问题,且未对日期排序,导致x轴顺序混乱。
  • 图表重复实例化:每次AJAX请求成功后都新建Chart实例,未销毁旧实例,可能导致图表渲染异常。

修复方案

前端代码修正

@page
@model Task_CRM.Pages.TrendChartModel
@{
    ViewData["Title"] = "Monthly Line Chart";
}
<div class="card">
    <div class="card-header center">
        <center><strong><h5>Trend Interaksi</h5></strong></center>
    </div>
    <div class="card-body">
        <form>
            <label for="selectMonth">Pilih Bulan:  </label>
            <select id="selectMonth" asp-for="SelectedMonth" asp-items="Model.month"></select>
            <!-- 修改按钮类型为button,避免表单提交 -->
            <button type="button" class="btn btn-primary" id="updateChartMonth">Update Chart</button>
        </form>
        <div>
            <canvas id="Trend" width="400" height="200"></canvas>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>

<script>
    // 全局存储图表实例,用于更新前销毁旧实例
    let trendChartInstance = null;

    $(document).ready(function () {
        // 绑定正确的按钮点击事件
        $('#updateChartMonth').click(function () {
            var selectedMonth = $('#selectMonth').val();
            if (!selectedMonth) {
                alert('请选择月份');
                return;
            }
            
            $.ajax({
                url: '/TrendChart?handler=GetMonthlyData',
                type: 'GET',
                data: { SelectedMonth: selectedMonth },
                success: function(data){
                    // 修正变量引用,匹配后端返回字段
                    const dates = data.Dates;
                    const counts = data.DailyCounts;

                    // 销毁旧图表实例,避免重复渲染
                    if (trendChartInstance) {
                        trendChartInstance.destroy();
                    }

                    // 创建新的折线图
                    trendChartInstance = new Chart(document.getElementById('Trend'), {
                        type: 'line',
                        data: {
                            labels: dates,
                            datasets: [{
                                label: 'Total Interactions',
                                data: counts,
                                fill: false,
                                borderColor: 'rgba(75, 192, 192, 1)',
                                borderWidth: 2,
                                pointRadius: 5,
                                pointHoverRadius: 8,
                                pointBackgroundColor: 'rgba(75, 192, 192, 1)',
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            aspectRatio: 1,
                            title: {
                                display: true,
                                text: 'Total Interactions Over Time'
                            },
                            scales: {
                                x: {
                                    position: 'bottom',
                                    title: {
                                        display: true,
                                        text: 'Tanggal'
                                    }
                                },
                                y: {
                                    beginAtZero: true,
                                    title: {
                                        display: true,
                                        text: 'Total Interactions'
                                    }
                                }
                            }
                        }
                    });
                },
                error: function(xhr, status, error) {
                    console.error('Error Fetching Updated Data:', error);
                }
            });
        });
    });
</script>

@{
    await Html.RenderPartialAsync("_ValidationScriptsPartial");
}

后端代码修正

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Task_CRM.Data;
using Task_CRM.Models;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;

namespace Task_CRM.Pages
{
    public class TrendChartModel : PageModel
    {
        private readonly Task_CRMContext _context;

        public TrendChartModel(Task_CRMContext context)
        {
            _context = context;
        }

        [BindProperty]
        public List<Interaction> Interaction { get; set; }
        [BindProperty]
        public SelectList month { get; set; }
        // 添加BindProperty确保GET参数正确绑定
        [BindProperty]
        public int SelectedMonth { get; set; }


        public void OnGet()
        {
            var currentUser = HttpContext.Session.GetString("Username");

            if (currentUser != null)
            {
                ViewData["Navbar"] = currentUser;
            }

            // 获取唯一月份并排序
            var uniqueMonth = _context.Interaction
                .Select(m => m.Tanggal.Month)
                .Distinct()
                .OrderBy(m => m)
                .ToList();

            month = new SelectList(uniqueMonth);
        }

        public IActionResult OnGetGetMonthlyData(int SelectedMonth)
        {
            // 按日期分组统计每日交互数,并按日期升序排序
            var dailyData = _context.Interaction
                .Where(d => d.Tanggal.Month == SelectedMonth)
                .GroupBy(d => d.Tanggal.Date)
                .Select(g => new 
                { 
                    Date = g.Key.ToString("yyyy-MM-dd"), // 转换为前端易处理的字符串格式
                    Count = g.Count() 
                })
                .OrderBy(item => item.Date)
                .ToList();

            // 提取日期和对应数量的列表
            var Dates = dailyData.Select(item => item.Date).ToList();
            var DailyCounts = dailyData.Select(item => item.Count).ToList();

            var responseData = new { Dates, DailyCounts };

            return new JsonResult(responseData);
        }
    }
}

关键修复点说明

  1. 事件与表单修正:将按钮类型改为button避免表单提交,绑定正确的按钮点击事件。
  2. 变量一致性修正:统一变量大小写和拼写,确保前后端字段匹配。
  3. 后端数据逻辑重构:改为按日期分组统计每日交互数,同时对结果排序并转换日期格式。
  4. 图表实例管理:全局存储图表实例,更新前销毁旧实例,避免重复渲染问题。
  5. 参数绑定优化:给SelectedMonth添加[BindProperty],确保GET请求参数正确绑定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 01:42:25