2016-05-03 11 views
3

Mit Asp.Net MVC versuche ich eine Webseite zu erstellen, die mehrere Balkendiagramme auf einer einzigen Seite unter Verwendung der chart.js-Bibliothek anzeigt. Jedes Diagramm hat andere Daten und wird in einer eigenen Teilansicht erstellt. Anstatt jedoch mehrere verschiedene Diagramme zu erstellen, überschreiben die letzten Diagrammdaten das erste Diagramm auf der Seite und alle übrigen Diagramme sind leer. Wie Sie in der folgenden Abbildung sehen können, überschreiben die Daten und die Legende "Titel und Segmente" die Daten von "Produzenten" und das Diagramm "Titel und Segmente" ist leer.Mehrere Chart.js-Diagramme in Teilansichten Überschreiben einander

enter image description here

Auf der Hauptansichtsseite, verwende ich eine foreach-Schleife die gleiche Teilansicht für jeden Bericht zu machen.

In meiner Teilansicht erstelle ich einen dynamischen ID-Namen für das Canvas-Objekt basierend auf einem Wert im Modell. Dies war ein Versuch, das in Chart.js - Multiple Line Charts - Only Show Last Chart erwähnte Problem zu überwinden.

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

Ich dann ein Canvas-Objekt mit der dynamischen ID erstellen.

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

Im chart.js Skript, das auch in meiner Teilansicht ist, habe ich eval() dynamische ctx und mybar Variablen zu erstellen. (Quelle der Idee: 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> 

ich ähnliche Fragen gesehen haben, doch keiner schien eine Lösung für mein Problem zu haben:
multiple chartjs in the same page
Rendering HTML5 Charts in partial views show only blank data

+0

Sind Sie eval die CTX-Variablen-Namen unterscheiden zu machen? Ich denke, dass Sie dieses Problem mit der Funktion Dokument bereit gelöst haben. –

+1

@AlexanderLindsay Das war mein Ziel, aber es hat nichts geändert. Ich bekomme die gleichen verwirrten Ergebnisse, wenn ich nur 'ctx' für alle Diagramme verwende oder wenn ich' eval() 'wie meinen aktuellen Versuch verwende. –

Antwort

2

denke ich, das Problem ist, dass die barChartData von jeder der Teilansichten überschrieben wird. Versuchen Sie, diese Variable in die Funktion Dokument bereit zu stellen.

Verwenden Sie alternativ eine selbstausführende Funktion, um alle Diagrammdaten zu verarbeiten.

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

Grundsätzlich ist das Problem, dass jede der Teilansichten ist eine Kopie von barChartData auf der Seite hinzufügen. Jeder davon ist im Fensterbereich definiert. So ist die Seite wird so etwas wie folgt aussehen:

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

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

Das barChartData mit dem Modell zwei Werte verlassen wird.

Sie sollten in der Lage sein, die generierte Seite zu sehen und die verschiedenen Skript-Tags zu sehen. Die Konsole in den Tools für Browser-Entwickler sollte ebenfalls überprüft werden.

Hier ist, wie man es beheben:

<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

Wenn Sie sagen, Selbstausführungsfunktion, meinst du '$ (function()};' anstelle von '$ (document) .ready'? Und wie würde das helfen? –

+1

Das Ziel besteht darin, die Variablen, die die Daten enthalten, nicht zu überschreiben, wenn die zweite Teilansicht auf der Seite geladen wird. –

+1

Platzieren von 'barChartData' innerhalb des' $ (document) .ready's hat den Trick gemacht! Trotzdem brauchte ich das 'eval()' Zeug, um das Fenster wissen zu lassen, dass die ctx-Objekte verschieden sind. Nach dem, was ich [hier] (http://stackoverflow.com/a/3528526/4660897) gelesen habe, sind '$ (function {});' und '$ (document) .ready (function() {});' sind genau das gleiche, so dass sich das nicht ändern sollte. Danke für die Hilfe! –