2016-05-03 169 views
3

使用Asp.Net MVC,我試圖創建一個網頁,使用chart.js庫在一個頁面上顯示多個條形圖。每個圖表都有不同的數據,並在其自己的局部視圖中創建。儘管不是創建多個不同的圖表,但最後一個圖表數據會覆蓋頁面上的第一個圖表,而其餘所有圖表都顯示爲空白。正如您在下圖中看到的,「標題和細分」數據和圖例覆蓋了「生產者」數據,「標題和細分」圖表爲空。多個Chart.js部分視圖中的圖表互相覆蓋

enter image description here

在主視圖頁面,我使用foreach循環來呈現每個報表相同的局部視圖。

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

在我的部分視圖中,我基於模型中的值爲畫布對象創建了一個動態ID名稱。這是試圖解決Chart.js - Multiple Line Charts - Only Show Last Chart中提到的問題。

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

然後我使用動態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

當你說自執行函數時,你的意思是'$(function()};'而不是'$(document).ready'?並且這會如何幫助? –

+1

目標是在頁面上加載第二個分部視圖時不覆蓋保存數據的變量。 –

+1

在'$(document).ready'中放置'barChartData'確實有效!仍然需要'eval()'東西來讓窗口知道ctx對象是不同的。從我讀的[這裏](http://stackoverflow.com/a/3528526/4660897),'$(function {});'和'$(document).ready(function(){});'是完全一樣,所以改變,應該沒有什麼區別。謝謝您的幫助! –