web-dev-qa-db-fra.com

Django et ChartJS

J'essaie de comprendre s'il est possible d'incorporer des données dynamiques dans une architecture Django Chart JS. J'ai parcouru quelques tutoriels et j'ai finalement obtenu Django de travailler avec ChartJS et c'est très bien quand je suis capable de coder en dur des valeurs puis d'afficher les graphiques associés. Ce que j'essaie finalement de faire est le même exercice avec des données dynamiques de ma base de données. J'ai trouvé cette question identique dans SO , https://stackoverflow.com/questions/47575896/dynamic-chart-using-Django-and-chart-js# = mais personne n'a répondu. C'est exactement ce que j'essaie de réaliser. J'ai un peu exploré les sérialiseurs, dois-je d'abord sérialiser les données? Merci d'avance pour vos réflexions et vos commentaires.

D'après les commentaires, j'ai ajouté du contexte au graphique en question, mais les données ne sont toujours pas transmises. Voici mon point de vue:

class ChartView(LoginRequiredMixin, TemplateView):

    model = Myobject 
    template_name = 'director/chart.html'

      def get_context_data(self, **kwargs):
          context = super(ChartView, self).get_context_data(**kwargs)  
          myobject = Myobject.objects.filter(field__in=self.request.user.userprofile.field.all())
          print(myobject)
          context['myobject'] = myobject
          return context

Je reçois juste un écran vide, pas de graphique du tout, ce qui suggère que quelque chose ne va manifestement pas. Dois-je apporter des modifications supplémentaires au Javascript afin de lui parler de l'objet? Mon hypothèse est non, que je transmets ces informations pour afficher les données context_data.

J'utilise également Ajax, donc je ne sais pas si c'est un facteur de complication. Voici mon javascript.

<script>
var endpoint = '{% url "myobject:chart_data" %}'
var defaultData = [];
var labels = [];
$.ajax({
    method: "GET",
    credentials: 'same-Origin',
    url: endpoint,
    success: function(data){
        labels = data.labels
        defaultData = data.default
        var ctx = document.getElementById("myChart");
        var myChart = new Chart(ctx, {
            type: 'pie',
            data: {
                labels: [{% for i in myobject %}{{ i.labels }},{% endfor %}],
                datasets: [{
                    data: [{% for i in myobject %}{{ i.data }},{% endfor %}]
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                    ],
                    borderColor: [
                        'rgba(255,99,132,1)',
                        'rgba(153, 102, 255, 1)',
                    ],
                    borderWidth: 1
                }]
            }
        })
    },
    error: function(error_data){
        console.log("error")
        console.log(error_data)
    }
})
</script>
6
Steve Smith

Vous n'avez pas nécessairement besoin d'utiliser des sérialiseurs pour restituer des données dynamiques dans Chart.js (bien que vous puissiez le faire si vous le souhaitez). Vous pouvez simplement parcourir vos variables de contexte Django comme d'habitude dans les emplacements appropriés. Ci-dessous est un exemple de graphique linéaire. Je jouerais avec cet exemple, mais cela devrait vous montrer comment rendre facilement le rendu dynamique données avec Django variables de contexte.

...
<canvas id="funchart" width="75" height="50"></canvas>                      

<script type="text/javascript">  
     var a = document.getElementById('funchart').getContext('2d');
     var myLineChart = new Chart(a, {
               type: 'line',
               data: {
                   labels:[{% for i in myobject %}{{ i.labels }},{% endfor %}],
                   datasets: [{
                        label:'My Dot',
                        data: [{% for i in myobject %}{{ i.data }},{% endfor %}]
                             }]
                      },
               options:{
                   scales: {
                       xAxes: [{
                           display:true
                              }],
                       yAxes: [{
                           ticks: {
                               beginAtZero:true
                                   }
                               }]
                            }
                        }
                      });
</script>
5
HoneyNutIchiros

donc j'ai travaillé la même chose ici, je pense que votre étiquette n'apparaît pas parce que l'étiquette sur chart.js ne veut qu'une chaîne, alors essayez ceci sur vos étiquettes:

labels: [{% for i in book %}"{{ i.id }}",{% endfor %}]
1
Ega Dharmawan

Mon code ci-dessous est ce qui a finalement résolu le problème de la façon d'obtenir des données utilisateur dynamiques. J'essaie toujours de comprendre comment faire fonctionner correctement les étiquettes. Cette solution permet aux étiquettes de s'afficher avec des numéros d'identification, ce qui n'est pas optimal, mais j'ai ouvert un SO pour le problème d'étiquette).

Mon HTML

   {% extends 'base5.html' %}

{% block body_block %}
<div class="box6">
          <h1 class="title">Number of Books By Author</h1>
<canvas id="myChart"></canvas>
<div>

  <script>
  var endpoint = '{% url "Books:chart_data" %}'
  var defaultData = [];
  var labels = [];
  array = {{ procedures3 }}
  $.ajax({
      method: "GET",
      credentials: 'same-Origin',
      url: endpoint,
      success: function(data){
          defaultData = data.default
          var ctx = document.getElementById("myChart");
          var myChart = new Chart(ctx, {
              type: 'bar',
              data: {
                  labels: [{% for i in book %}{{ i.id }},{% endfor %}],
                  datasets: [{
                      label: "# of Procedures",
                      data: [{% for j in book_count %}
                               {{ j }},
                             {% endfor %}],
                      backgroundColor: [
                          'rgba(255, 99, 132, 0.2)',
                          'rgba(255, 99, 132, 0.2)',
                          'rgba(54, 162, 235, 0.2)',
                          'rgba(255, 206, 86, 0.2)',
                          'rgba(75, 192, 192, 0.2)',
                          'rgba(153, 102, 255, 0.2)',
                          'rgba(255, 159, 64, 0.2)'
                      ],
                      borderColor: [
                          'rgba(255,99,132,1)',
                          'rgba(255,99,132,1)',
                          'rgba(54, 162, 235, 1)',
                          'rgba(255, 206, 86, 1)',
                          'rgba(75, 192, 192, 1)',
                          'rgba(153, 102, 255, 1)',
                          'rgba(255, 159, 64, 1)'
                      ],
                      borderWidth: 1
                  }]
              }
          })
      },
      error: function(error_data){
          console.log("error")
          console.log(error_data)
      },
  })
  </script>
  {% endblock %}

Views.py

ChartView

class ChartData(LoginRequiredMixin,APIView):
    model = Author
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        default_items = []
        labels = []
        data = {
            "labels": labels,
            "default": default_items,
        }
        return Response(data)

The ChartView

class ChartView(LoginRequiredMixin, TemplateView): template_name = 'Book/chart.html'

def get_context_data(self, **kwargs):
    context = super(ChartView, self).get_context_data(**kwargs)
    book = Author.objects.filter(id__in=self.request.user.userprofile.author.all()).order_by('id')
    books_count = [ Book.objects.filter(author=cls).count() for cls in book ]
    context['book'] = book
    context['book_count'] = books_count
    return context
0
Steve Smith