在ASP.NET核心Web应用程序Razor页面中使用C#函数不断更新x轴和y轴以更新Chart.js图表

e1xvtsh3  于 2023-01-17  发布在  Chart.js
关注(0)|答案(1)|浏览(159)

我尝试迭代两个列表,它们不断更新我的Chart.js图表。因为有几千个数据点,我不能使用静态图表。在尝试使用SignalR的缓冲队列并获得半成功后,我偶然发现这基本上是我试图完成的,但仅限于y轴。然而,我没有让它工作,因为我对 AJAX 处理程序很陌生,Chart.Js的更新插件也是我还不习惯的东西。
下面是我当前的.cshtml:

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

<html>

 <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");
    var chart = new myChart (ctx {
        type: 'line',
        data: {
            datasets: [{
                label: 'Chart Data',
                borderColor: 'rgb(54, 162, 235)',
                fill: false,
                tension: 0,
                data: []
            }]
        },
        options={
            scales: {
                xAxes: [{
                    type: 'realtime'
                }],
                yAxes: [{
                    scaleLabel: {
                        display: true,
                        labelString: 'Value'
                    }
                }]
            },
            plugins: {
                streaming: {
                    duration: 20000,
                    refresh: 1000,
                    delay: 2000,
                    onRefresh: onRefresh
                }
            }
        }
    });

    function onRefresh(chart) {
        function pushData(xData, yData) {
            chart.config.data.datasets.forEach(function (dataset) {
                dataset.data.push({ x: xData, y: yData });
            });
        }
        var xhr = new XMLHttpRequest();
        // you might want to custom the url
        var handlerUrl = '/Index?handler=Refresh';
        xhr.open('GET', handlerUrl, true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status == 200) {
                    pushData(xhr.responseText);
                    return;
                }
                console.log("error happens: receives a status code ", xhr.status)
            }
        }
        xhr.send();
    }
</script>

</html>

和.cshtml.cs:

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

namespace Proj.Pages.Visualization
{
    public class VisualizationMainModel : PageModel
    {
        public List<string> Time = new();

        public List<string> Value = new();

        public int i = 0;

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

            using (StreamReader sr = new(filepath))
            {
                sr.ReadLine();

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

                    Time.Add(values[0]);
                    Value.Add(values[1]);
                    }
            }
        }

        public IActionResult OnGetRefresh()
        {
            return new JsonResult(this.XValue(), this.YValue());
        }

        private string XValue()
        {
            string X = Time[i];
            return X;
        }

        private string YValue()
        {
            string Y = Value[i];
            i += 1;
            return Y;
        }
    }
}

可能有一个更直接的方法来获得.csv条目作为直接数据点,但现在只是让它显示并每隔几毫秒更新一次将是我的目标。

u91tlkcl

u91tlkcl1#

我想,快速浏览一下之后,如果C#代码是正确的,您只需要在pushData函数 link to the documentation 中添加一个对图表update函数的调用。

更新:****和至少修复下面列出的所有错误 (我没有检查C#代码,可能也有一些)

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

但我强烈建议检查浏览器控制台,因为您的javascript代码似乎有一些/很多错误,* 例如:*

  • chart = new myChart (...)应为chart = new Chart (...)
  • new Chart (ctx {...})ctx和配置对象之间缺少逗号,因此new Chart (ctx, {...})
  • 在配置对象options={中,等号应为冒号options:{
  • pushData(xhr.responseText);正在向pushData函数传递一个字符串,但在该函数中,您正在访问两个参数function pushData(xData, yData) { ... }. xDatayData,这将不起作用。xData将始终是返回的数据,yData将始终是undefined

这些是我浏览你的代码时发现的。

***顺便说一句:***如果将结果输出到控制台,您可以检查 AJAX 调用返回的内容。ANDxhr.responseText是字符串,而不是json对象(例如,使用JSON.parse(xhr.responseText)转换此对象)。

var xhr = new XMLHttpRequest();
    var handlerUrl = '/Index?handler=Refresh';
    xhr.open('GET', handlerUrl, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status == 200) {
                console.info(xhr.responseText);
                return;
            }
            console.log("error happens: receives a status code ", xhr.status)
        }
    }
    xhr.send();

奖金信息:

如果你不需要支持旧的浏览器,我推荐fetchlink to mdn documentation),这是“现代的方式”,而且更容易使用。
下面的代码与您的XMLHttpRequest代码段相当,更短,更容易阅读。

fetch('/Index?handler=Refresh')
    .then((response) => response.json())  
    // And data will be a json object and no convertion needed
    .then((data) => console.log(data));

相关问题