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

ASP.NET Core Razor Pages中Chart.js图表XY轴实时更新实现问题

解决Chart.js实时更新CSV数据的问题

原代码核心问题

  1. 前端语法与配置错误:

    • Chart实例化拼写错误(myChart → Chart),且参数间缺少逗号
    • Chart.js v3版本轴配置结构变更,xAxes/yAxes数组需改为scales.x/scales.y对象
    • 未解析后端返回的JSON数据,且pushData调用参数不匹配
    • 请求URL路径错误,未指向正确的Razor Page处理器
  2. 后端逻辑错误:

    • JsonResult构造参数错误,无法正确返回x/y数据对
    • 实例变量i存在多用户访问冲突风险
    • 未处理索引越界问题,超出CSV数据长度后会报错

修正后的前端代码(.cshtml)

@page
@model Proj.Pages.Visualization.VisualizationMainModel
@{    
    ViewData["Title"] = "CSV Data Visualization";
}

<div>
    <canvas id="myChart" width="1200" height="700"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.3.2"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon@1.27.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@2.0.0"></script>

<script>
    var ctx = document.getElementById("myChart").getContext("2d");
    // 修正Chart实例化语法与配置结构
    var chart = new Chart(ctx, {
        type: 'line',
        data: {
            datasets: [{
                label: 'Chart Data',
                borderColor: 'rgb(54, 162, 235)',
                fill: false,
                tension: 0,
                data: []
            }]
        },
        options: {
            scales: {
                x: {
                    type: 'realtime',
                    realtime: {
                        delay: 2000
                    }
                },
                y: {
                    scaleLabel: {
                        display: true,
                        labelString: 'Value'
                    }
                }
            },
            plugins: {
                streaming: {
                    duration: 20000,
                    refresh: 100, // 设置为100毫秒实现高频更新
                    onRefresh: onRefresh
                }
            }
        }
    });

    function onRefresh(chart) {
        function pushData(xData, yData) {
            chart.config.data.datasets.forEach(function (dataset) {
                dataset.data.push({ x: xData, y: parseFloat(yData) });
            });
        }

        var xhr = new XMLHttpRequest();
        // 修正请求URL,指向当前Razor Page的Refresh处理器
        var handlerUrl = '/Visualization/VisualizationMain?handler=Refresh';
        xhr.open('GET', handlerUrl, true);
        xhr.responseType = 'json'; // 设置响应类型为JSON

        xhr.onreadystatechange = function () {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status === 200) {
                    if (xhr.response) {
                        // 解析后端返回的x/y数据
                        pushData(xhr.response.X, xhr.response.Y);
                    }
                    return;
                }
                console.error("请求错误,状态码:", xhr.status);
            }
        };
        xhr.send();
    }
</script>

修正后的后端代码(.cshtml.cs)

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Proj.Pages.Visualization
{
    public class VisualizationMainModel : PageModel
    {
        // 使用Session存储用户当前索引,避免多用户冲突
        private int CurrentIndex
        {
            get => HttpContext.Session.GetInt32("DataIndex") ?? 0;
            set => HttpContext.Session.SetInt32("DataIndex", value);
        }

        public List<string> Time { get; set; } = new();
        public List<string> Value { get; set; } = new();

        public void OnGet()
        {
            var filepath = Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\Content\rawData.csv");

            using (StreamReader sr = new(filepath))
            {
                sr.ReadLine(); // 跳过表头

                while (!sr.EndOfStream)
                {
                    var line = sr.ReadLine();
                    var values = line.Split(";");

                    if (values.Length >= 2) // 防止CSV行格式错误
                    {
                        Time.Add(values[0]);
                        Value.Add(values[1]);
                    }
                }
                // 初始化Session索引
                CurrentIndex = 0;
            }
        }

        public IActionResult OnGetRefresh()
        {
            // 防止索引越界
            if (CurrentIndex >= Time.Count || CurrentIndex >= Value.Count)
            {
                // 可以选择重置索引或返回空数据
                CurrentIndex = 0;
                return new JsonResult(new { X = "", Y = "" });
            }

            var result = new { X = Time[CurrentIndex], Y = Value[CurrentIndex] };
            CurrentIndex++;
            return new JsonResult(result);
        }
    }
}

关键优化说明

  1. 毫秒级更新:将streaming.refresh设置为100ms(可根据硬件性能调整),实现高频数据刷新
  2. 多用户兼容:使用Session存储每个用户的当前数据索引,避免实例变量冲突
  3. 错误处理:添加CSV行格式校验、索引越界处理,提升鲁棒性
  4. 数据解析:前端设置responseType: 'json',直接解析后端返回的JSON对象,避免手动解析错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:15:27