首页 文章

部分视图中的多个Chart.js图表互相覆盖

提问于
浏览 73
3

使用Asp.Net MVC,我正在尝试使用chart.js库创建一个在单个页面上显示多个条形图的网页 . 每个图表都有不同的数据,并在其自己的局部视图中创建 . 但是,最后的图表数据不是创建多个不同的图表,而是覆盖页面上的第一个图表,所有剩余的图表显示为空白 . 如下图所示,"Title and Segments"数据和图例覆盖"Producers"数据,"Title and Segments"图表为空 .

enter image description here

在主视图页面上,我使用foreach循环为每个报表呈现相同的局部视图 .

@foreach (Report report in Model.Reports)
{
    @Html.Partial("BarChartPartialView", report);
}

在我的局部视图中,我基于Model中的值为canvas对象创建动态ID名称 . 这是为了克服Chart.js - Multiple Line Charts - Only Show Last Chart中提到的问题 .

@{
    string name = "canvas" + Model.CurrentReport.ID;
}

然后,我使用动态ID创建一个canvas对象 .

<canvas id="@name"></canvas>

在我的局部视图中的chart.js脚本中,我使用eval()创建动态ctx和myBar变量 . (想法来源:How do i declare and use dynamic variables in javascript?

<script>
    var barChartData = {
        labels: [@Html.Raw(Model.Labels)],
        datasets: [@Html.Raw(Model.Data)]
    };

    $(document).ready(function () {      
        eval("var ctx" + "@name" + "=document.getElementById('@name').getContext('2d');");

        var temp = new Chart(eval('ctx' + '@name'), {
            type: 'bar',
            data: barChartData,
            options: {
                elements: {
                    rectangle: {
                        borderWidth: 2,
                        borderColor: 'rgb(0, 255, 0)'
                    }
                },
                legend: {
                    position: 'bottom'
                },
                title: {
                    display: true,
                    text: '@Model.CurrentReport.Name'
                }
            }
        });

        eval('window.myBar' + '@name' + "= temp;");
    });
</script>

我见过其他类似的问题,但似乎没有一个解决我的问题:
multiple chartjs in the same page
Rendering HTML5 Charts in partial views show only blank data

1 回答

  • 2

    我认为问题是每个部分视图都会覆盖 barChartData . 尝试将该变量放在文档就绪函数中 .

    或者,使用自执行功能来完成所有图表内容 .

    (function(){
        var data = {};
    })();
    

    基本上,问题是每个部分视图都在向页面添加 barChartData 的副本 . 每个都在窗口范围中定义 . 所以页面看起来像这样:

    <script>
        var barChartData = {
            labels: ModelOneLabels,
            datasets: ModelOneData
        };
        ...
    </script>
    
    <script>
        var barChartData = {
            labels: ModelTwoLabels,
            datasets: ModelTwoData
        };
        ...
    </script>
    

    这将留下 barChartData 与模型二值 .

    您应该能够查看生成的页面并查看多个脚本标记 . 浏览器开发人员工具中的控制台也应该验证 .

    以下是如何解决它:

    <script>
        $(document).ready(function () {
            var barChartData = {
                labels: [@Html.Raw(Model.Labels)],
                datasets: [@Html.Raw(Model.Data)]
            };
    
            var ctx = document.getElementById('@name').getContext('2d');
    
            // I am not sure how you are using the window.myBar@name var
            // if you are referencing it later than you may need to adjust this part
            var myBar = new Chart(ctx, {
              type: 'bar',
              data: barChartData,
              options: {
                  elements: {
                      rectangle: {
                          borderWidth: 2,
                          borderColor: 'rgb(0, 255, 0)',
                          borderSkipped: 'bottom'
                      }
                  },
                  legend: { 
                      position: 'bottom' 
                  }, 
                  title: {
                      display: true, 
                      text: '@Model.CurrentReport.Name'
                  }
            })
    
    });
    </script>
    

相关问题