2016-05-03 5 views
3

Использование Asp.Net MVC, я пытаюсь создать веб-страницу, которая отображает несколько гистограмм на одной странице, используя библиотеку chart.js. Каждый график имеет разные данные и создается в его собственном частичном представлении. Вместо того, чтобы создавать несколько разных диаграмм, последние данные диаграммы переписывают первый график на странице, а все остальные диаграммы выглядят пустыми. Как вы можете видеть на рисунке ниже, данные «Название и сегменты» и легенда переписывают данные «Продюсеры», а диаграмма «Название и сегменты» пуста.Несколько диаграмм Chart.js в частичных представлениях Перезаписывание друг друга

enter image description here

На главной странице просмотра, я использовать цикл Еогеасп, чтобы сделать то же частичный вид для каждого отчета.

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

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

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

Затем я создаю объект холста с использованием динамического идентификатора.

<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

+0

Вы используете Eval, чтобы имена переменных CTX разные? Я думаю, вы решили эту проблему с помощью функции готовности документа. –

+1

@AlexanderLindsay Это была моя цель, но ничего не изменило. Я получаю те же самые испорченные результаты, если я использую только 'ctx' для всех диаграмм, или если я использую' eval() ', как моя текущая попытка. –

ответ

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 [email protected] 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> 
+1

Когда вы произносите функцию self execute, вы имеете в виду '$ (function()};' вместо '$ (document) .ready'? И как это поможет? –

+1

Целью является не переопределять переменные, которые хранят данные, когда второй частичный вид загружается на страницу. –

+1

Размещение 'barChartData' внутри' $ (document) .ready' сделал трюк! Все еще нуждался в 'eval()', хотя чтобы окно стало известно, что объекты ctx отличаются. Из того, что я читал [здесь] (http://stackoverflow.com/a/3528526/4660897), '$ (function {});' и '$ (document) .ready (function() {});' are точно так же, поэтому изменение этого не должно иметь никакого значения. Спасибо за помощь! –

Смежные вопросы