如何使用AJAX数据和变量在同一页面上呈现多个Chart.JS图表

时间:2019-03-27 11:02:43

标签: jquery asp.net-core chart.js

我正在尝试创建一个可重用的折线图视图组件,该组件可以从模型中获取变量,以通过AJAX和操作结果提取其数据。当在页面上呈现单个图表时,这种方法可以很好地工作,但是当一个图表以上时,它可以中断。

我已经遍历了各种教程来在页面上创建多个图表,并且如果图表是用数据硬编码的,但是如果它依赖于AJAX调用(将所有线条呈现到同一画布上),则可以使此工作正常。

这是图表的JS:

var hiddens = document.getElementsByClassName("kpiclass");
for (hidden of hiddens) {
var kpidata = $(hidden).val();

$.ajax({

    type: "POST",
    url: "/Home/GetLineChartData",
    traditional: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: kpidata,
    success: function (iData) {
        var aData = iData;
        var aLabels = aData[0];
        var aDatasets1 = aData[1];
        var dataT = {
            labels: aLabels,
            datasets: [{

                data: aDatasets1,
                label: 'Value',
                backgroundColor: getStyle('--primary'),
                borderColor: 'rgba(255,255,255,.55)'
            }]
        };

        var charts = document.getElementsByName(kpidata);

        for (chart of charts) {


            var ctx = chart.getContext('2d');

            var myNewChart = new Chart(ctx, {
                type: 'line',
                data: dataT,
                options: {
                    responsive: true,
                    tooltipCaretSize: 0,
                    maintainAspectRatio: false,
                    legend: {
                        display: false
                    },
                    scales: {
                        xAxes: [{
                            gridLines: {
                                color: 'transparent',
                                zeroLineColor: 'transparent'
                            },
                            ticks: {
                                fontSize: 2,
                                fontColor: 'transparent'
                            }
                        }],
                        yAxes: [{
                            display: false,
                            ticks: {
                                display: false

                            }
                        }]
                    },
                    elements: {
                        line: {
                            borderWidth: 1
                        },
                        point: {
                            radius: 4,
                            hitRadius: 10,
                            hoverRadius: 4
                        }
                    }
                }


            });
        }
    }
});

这是视图组件的图表部分:

  <div>@Html.DisplayFor(model => model.Kpi.KpiMainName)</div>
  @Html.HiddenFor(model => model.Kpi.KpiId, new {  @class="kpiclass"})
</div>

<div class="chart-wrapper mt-3 mx-3" style="height:70px;">
  <div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;"><div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div></div>
  <canvas class="chart chartjs-render-monitor line" Name="@(Model.KpiId)" height="70" width="275" style="display: block; width: 275px; height: 70px;"></canvas>
  <div  class="chartjs-tooltip bottom top" style="opacity: 0; left: 22.5576px; top: 113.333px;" ><div class="tooltip-header"><div class="tooltip-header-item">January</div></div><div class="tooltip-body"><div class="tooltip-body-item"><span class="tooltip-body-item-color" style="background-color: rgb(0, 165, 224);"></span><span class="tooltip-body-item-label">My First dataset</span><span class="tooltip-body-item-value">65</span></div></div></div>
</div> 

我正在将变量从视图组件中的隐藏字段传递给AJAX调用,以从ActionResult中提取正确的数据。如果我使用getElementsByName收集页面上的图表,则AJAX调用会触发正确的次数,但会将所有行呈现到页面上的最后一个画布,如果我使用getElementsByClassName,则所有行将呈现到页面上的每个画布上,而不是每个,但只有将鼠标悬停在图表上才能看到。无论我尝试过什么,我似乎都无法将正确的数据与正确的图表匹配。

有人有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在将各种类似问题的答案拼凑在一起之后,我找到了一种使用.each函数的方法。每当页面上有带“线”类的画布时,就会为每个图表调用此JS。希望这会对其他人有所帮助。

$('.line').each(function (index, element) {

var kpidata = element.getAttribute('id');


$.ajax({

    type: "POST",
    url: "/Home/GetLineChartData",
    traditional: true,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    data: kpidata,
    success: function (iData) {
        var aData = iData;
        var aLabels = aData[0];
        var aDatasets1 = aData[1];
        var dataT = {
            labels: aLabels,
            datasets: [{

                data: aDatasets1,
                label: 'Value',
                backgroundColor: getStyle('--primary'),
                borderColor: 'rgba(255,255,255,.55)'
            }]
        };


        var ctx = element.getContext('2d');

        var myNewChart = new Chart(ctx, {
            type: 'line',
            data: dataT,
            options: {
                responsive: true,
                tooltipCaretSize: 0,
                maintainAspectRatio: false,
                legend: {
                    display: false
                },
                scales: {
                    xAxes: [{
                        gridLines: {
                            color: 'transparent',
                            zeroLineColor: 'transparent'
                        },
                        ticks: {
                            fontSize: 2,
                            fontColor: 'transparent'
                        }
                    }],
                    yAxes: [{
                        display: false,
                        ticks: {
                            display: false

                        }
                    }]
                },
                elements: {
                    line: {
                        borderWidth: 1
                    },
                    point: {
                        radius: 4,
                        hitRadius: 10,
                        hoverRadius: 4
                    }
                }
            }


        }
        );
    }
});


});