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

Chart.js结合ASP.NET MVC5从SQL Server取数渲染图表求助

解决ASP.NET MVC5为Chart.js填充真实数据的问题

我帮你梳理下当前代码里的问题,然后给出具体的修正方案,这样就能让Chart.js正常渲染真实数据了。

一、后端Controller的核心问题与修正

你的后端代码里有几个关键错误,导致数据无法正确传递给前端:

  1. 错误使用服务器端Chart控件:你实例化的System.Web.UI.DataVisualization.Charting.Chart是ASP.NET自带的服务器端图表控件,和前端的Chart.js完全无关,完全不需要它,直接返回整理好的数据即可。
  2. 变量未定义+关联逻辑错误:MonthlyExpenseSummary里用了FromDate和ToDate但没定义,而且LINQ的join条件a.ItemName equals at.Amount明显不符合数据库关联逻辑(应该关联外键,比如a.AmountId equals at.Id,需要根据你的实际表结构调整)。
  3. 重复序列化:Json(JsonConvert.SerializeObject(...), ...)是重复操作,ASP.NET的JsonResult会自动序列化对象,这么做会让前端拿到的是字符串而非JSON对象,导致无法解析。

修正后的Controller代码:

public class ChartController : Controller
{
    // 替换为你的实际DbContext
    private readonly YourDbContext _dbContext = new YourDbContext();

    public JsonResult WeeklyExpenseSummary()
    {
        DateTime today = DateTime.Today;
        // 计算本周一的日期
        int offset = (int)today.DayOfWeek - (int)DayOfWeek.Monday;
        offset = offset < 0 ? offset + 7 : offset;
        DateTime fromDate = today.AddDays(-offset);
        DateTime toDate = fromDate.AddDays(7);

        // 修正关联条件,这里请替换为你实际的外键关联逻辑
        var data = (from expense in _dbContext.ExpenseReport
                    join amount in _dbContext.Amount on expense.AmountId equals amount.Id
                    where expense.Date >= fromDate && expense.Date < toDate
                    group amount by amount.ItemName into grouped
                    select new 
                    { 
                        label = grouped.Key, 
                        value = grouped.Count() 
                    }).ToList();

        // 直接返回数据,JsonResult会自动完成序列化
        return Json(data, JsonRequestBehavior.AllowGet);
    }

    public JsonResult MonthlyExpenseSummary()
    {
        DateTime today = DateTime.Today;
        DateTime startDate = new DateTime(today.Year, today.Month, 1);
        DateTime endDate = startDate.AddMonths(1).AddDays(-1);

        // 同样修正关联条件
        var data = (from expense in _dbContext.ExpenseReport
                    join amount in _dbContext.Amount on expense.AmountId equals amount.Id
                    where expense.Date >= startDate && expense.Date <= endDate
                    group amount by amount.ItemName into grouped
                    select new 
                    { 
                        label = grouped.Key, 
                        value = grouped.Count() 
                    }).ToList();

        return Json(data, JsonRequestBehavior.AllowGet);
    }
}

二、前端View的问题与修正

前端的主要问题是没有主动请求后端数据,还有一些拼写错误导致Chart.js无法正常初始化:

  1. Canvas属性拼写错误:heigh应该改为height。
  2. 配置项大小写错误:PointHitRadius要改成小写开头的pointHitRadius(Chart.js用驼峰命名)。
  3. 未发起AJAX请求:你直接写了data变量但没有赋值,需要先通过AJAX获取后端的周/月数据,再初始化图表。

修正后的Index.cshtml代码(需要引入jQuery,如果你项目里还没加的话):

<div style="width: 80%;">
    <canvas id="barChart" height="400" width="400"></canvas>
</div>

<!-- 先引入jQuery和Chart.js -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
$(document).ready(function() {
    // 同时请求周和月的支出数据
    $.when(
        $.get("/Chart/WeeklyExpenseSummary"),
        $.get("/Chart/MonthlyExpenseSummary")
    ).done(function(weeklyResponse, monthlyResponse) {
        // 把后端返回的数据转换为Chart.js需要的格式
        const weeklyData = weeklyResponse[0];
        const monthlyData = monthlyResponse[0];
        
        const labels = weeklyData.map(item => item.label);
        const weeklyValues = weeklyData.map(item => item.value);
        const monthlyValues = monthlyData.map(item => item.value);

        // 初始化Chart.js
        const chartCtx = document.getElementById("barChart").getContext('2d');
        Chart.defaults.global.animation.duration = 2000;
        
        new Chart(chartCtx, {
            type: 'bar',
            data: {
                labels: labels,
                datasets: [{
                    label: 'Weekly Expenses',
                    fill: true,
                    barTension: 0.1,
                    borderColor: '#2C3E50',
                    borderWidth: 2,
                    borderCapStyle: 'butt',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'miter',
                    pointBorderColor: "#2C3E50",
                    pointBackgroundColor: "#fff",
                    pointBorderWidth: 2,
                    pointHoverRadius: 8,
                    pointHoverBackgroundColor: "#2C3E50",
                    pointHoverBorderColor: "#2C3E50",
                    pointHoverBorderWidth: 5,
                    pointRadius: 10,
                    pointHitRadius: 10,
                    data: weeklyValues
                }, {
                    label: 'Monthly Expenses',
                    fill: true,
                    barTension: 0.8,
                    backgroundColor: '#2C3E50',
                    borderColor: '#f0c419',
                    borderWidth: 2,
                    borderCapStyle: 'butt',
                    borderDash: [],
                    borderDashOffset: 0.0,
                    borderJoinStyle: 'miter',
                    pointBorderColor: "#f0c419",
                    pointBackgroundColor: "#fff",
                    pointBorderWidth: 1,
                    pointHoverRadius: 5,
                    pointHoverBackgroundColor: "#f0c419",
                    pointHoverBorderColor: "#f0c419",
                    pointHoverBorderWidth: 2,
                    pointRadius: 1,
                    pointHitRadius: 1,
                    data: monthlyValues
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true,
                        },
                    }]
                }
            }
        });
    }).fail(function() {
        alert("获取支出数据失败,请检查后端接口是否正常运行");
    });
});
</script>

三、额外注意事项

  • 数据库关联逻辑:一定要确保LINQ中的join条件是正确的外键关联,否则会查询到错误的数据或者出现笛卡尔积。
  • 数据格式对齐:如果周和月数据的label(比如商品名称)不一致,Chart.js会无法正常渲染,你可能需要调整后端的分组逻辑(比如按日期分组,每周7天/每月30天)来保证标签统一。
  • 调试技巧:打开浏览器开发者工具(F12),查看Network标签页确认AJAX请求是否成功,Console标签页查看是否有JavaScript错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:55:54