Несколько Диаграмм.диаграммы js в частичных представлениях перезаписывают друг друга


Использование Asp.Net MVC, я пытаюсь создать веб-страницу, которая отображает несколько гистограмм на одной странице, используя диаграмму .библиотека js. Каждая диаграмма содержит различные данные и создается в своем собственном частичном представлении. Однако вместо того, чтобы создавать несколько различных диаграмм, последние данные диаграммы перезаписывают первую диаграмму на странице, и все остальные диаграммы выглядят пустыми. Как вы можете видеть на рисунке ниже, данные "название и сегменты" и легенда переписывают данные "производители", а Диаграмма "заголовок и сегменты" пуста.

Введите описание изображения здесь

На главной странице представления я использую цикл foreach для отображения одного и того же частичного представления для каждого отчета.

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

В моем частичном представлении я создаю динамическое имя ID для объекта canvas на основе значения в модели. Это была попытка преодолеть проблему, упомянутую в диаграмме .js-Multiple Line Charts-показывать только последний график .

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

Затем я создаю объект canvas, используя динамический ИДЕНТИФИКАТОР.

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

На диаграмме.сценарий js, который также находится в моем частичном представлении, я использовал eval () для создания динамических переменных ctx и myBar. (Источник идеи: как объявить и использовать динамические переменные в 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>

Я видел и другие подобные вопросы, но ни один из них, казалось, не имел решения для моей проблемы.:
несколько chartjs на одной странице
отображение диаграмм HTML5 в частичных представлениях показывает только пустые данные

1   3   2016-05-03 19:00:33

1 ответ:

Я думаю, проблема в том, что 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>