skip to Main Content

I want to get a report by chart from my model but I can’t figured out how to pass data from a dictionary to chart using chart.js?

here is my model:

class Book(models.Model):

    number = models.CharField(_("number"), max_length=255)
    title = models.CharField(_("title"), max_length=255)
    subtitle = models.CharField(_("subtitle"), max_length=255, null=True,)
    authors = models.TextField(_("authors"), null=True,)
    publisher = models.CharField(_("publisher"), max_length=255, null=True,)
    published_date = models.DateField(_("published date"), null=True,)
    category = models.CharField(_("category"), max_length=255, null=True,)
    distrubution_expense = models.FloatField(_("distribution expense"))

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('book_detail', args=[str(self.id)])

and this is my view that I use queryset to count the number of categories repetition:

class CategoryChartListView(generic.ListView):
    model = Book
    template_name= 'pages/chart_category.html'

    def get_context_data(self, **kwargs):
        context = super(CategoryChartListView, self).get_context_data(**kwargs)
        context["dictCategory"] =    Book.objects.values('category').annotate(count=Count('category'))
        return context

also this is the dictionary that I get from above queryset in view:

{'category': 'Business Analytics', 'count': 336}
{'category': 'Data ethics', 'count': 389}
{'category': 'visualization', 'count': 314}
{'category': 'statistics', 'count': 428}
{'category': 'NLP', 'count': 368}
{'category': 'Language', 'count': 1}
{'category': 'python', 'count': 373}
{'category': 'maths', 'count': 379}
{'category': 'deep learning', 'count': 364}
{'category': 'SQL', 'count': 403}
{'category': 'Python', 'count': 80}
{'category': 'R Studio', 'count': 246}
{'category': 'data science', 'count': 395}
{'category': None, 'count': 0}

and template:

{%block content%}
        <!-- displaying the chart -->
        <!-- you can also play around with the width and height to increase or decrease the chart size -->
        <canvas id="myChart" width="400" height="100"></canvas>  
    {%endblock content%}

    {%block scripts%}
        <script>
            // jquery function
            $(document).ready(function(){
                    var ctx = document.getElementById('myChart').getContext('2d');
                    var myChart = new Chart(ctx, {
                        type: 'doughnut',
                        data: {
                            labels: [{%for data in dictCategory%} {{ data.keys }}, {%endfor%}] //loop through queryset, 
                            datasets: [{
                                label: '# of users',
                                data: [{%for data in dictCategory%}{{ data.values }},{%endfor%}],
                                backgroundColor: [
                                    '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(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
                            }]
                        },
                        options: {
                            scales: {
                                y: {
                                    beginAtZero: true
                                }
                            }
                        }
                });
            });
        </script>
    {%endblock scripts%}

I use these code but I got nothing.

2

Answers


  1. Chosen as BEST ANSWER

    I didn't find a way to pass "dictCategory" dictionary to chart.js. so I converted it to two list:

    category_list = ['Business Analytics', 'Data ethics', 
                           'visualization', 'statistics', 'NLP', 
                           'Language', 'python', 'maths', 'deep 
                           learning', 'SQL', 'Python', 'R 
                           Studio', 'data science']
    count_list = [336, 389, 314, 428, 368, 1, 373, 379, 364, 403, 
                    80, 246, 395]
    

    Then I use them in chart.js:

    <script>
        // jquery function
        $(document).ready(function(){
            var ctx = document.getElementById('myChart').getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: [{% for data in category_list %} '{{data}}', {% endfor %}],
                    datasets: [{
                        label: '# of categories',
                        data: [{% for data in count_list %}{{data}},{% endfor %}],
                        backgroundColor: [
                            '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)',
                            'rgba(54, 162, 64, 0.2)',
                            'rgba(255, 148, 64, 0.2)',
                            'rgba(75, 175, 192, 0.2)',
                            'rgba(255, 130, 64, 0.2)',
                            'rgba(54, 158, 64, 0.2)',
                            'rgba(255, 125, 64, 0.2)',
                            'rgba(75, 165, 192, 0.2)'
                        ],
                        borderWidth: 1
                    }]
                },
            });
        });
        </script>
    

    It worked: [1]: https://phpout.com/wp-content/uploads/2023/09/9hVuO.png


  2. You can try:

    ...
    data: {
                                labels: [{%for data in dictCategory%} {{ data.category }}, {%endfor%}] //loop through queryset, 
                                datasets: [{
                                    label: '# of users',
                                    data: [{%for data in dictCategory%}{{ data.count }},{%endfor%}],
    ...
    

    the problem is that keys here are category and count, and values are their values. so when you try to get keys, you get category and count.

    Another way to do it is that:

    ...
    $(document).ready(function(){
                        dictCategory = {{dictCategory}}
                        labels = []
                        data = []
                        for (i = 0; i < dictCategory.length; i++){
                            labels.append(item.category);
                            data.append(item.count);
                        }
                        var ctx = document.getElementById('myChart').getContext('2d');
                        var myChart = new Chart(ctx, {
                            type: 'doughnut',
                            data: {
                                labels: labels, 
                                datasets: [{
                                    label: '# of users',
                                    data: data
    ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search