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
I didn't find a way to pass "dictCategory" dictionary to chart.js. so I converted it to two list:
Then I use them in chart.js:
It worked: [1]: https://phpout.com/wp-content/uploads/2023/09/9hVuO.png
You can try:
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
andcount
.Another way to do it is that: