27- Django with ChartJS
Chart.js is an free JavaScript library for making HTML-based charts. In this article, I will create an admin dashboard and create charts by using chartJS.
Create a path in urls.py
path('dashboard', views.dashboard, name='dashboard'),
Create a view in views.py
I created several queries for the dashboard. You can find detailed explanations in the following article (28- Django Annotate and Aggregate Queryset Methods) if you want to get more information about the queries I used. Import Count function.
from django.db.models import Q, Count
def dashboard(request):
#Query For Top5 Most Watched Movies. Query counts the db records, put them in order and returns first 5
topFiveMovie = Movie.objects.annotate(myCounter=Count('Watched_Movie')).order_by('-myCounter')[:5]
topFiveWatched = Watched.objects.values('movie__id').annotate(myCounter=Count('id')).order_by('-myCounter')[:5]
#Query gets the highest floating point values in MoviesApp_Scores, then returns the objects to be able to get the movie titles
#Flat=True is used in values_list to have QuerySet of single values instead of tuples (for example <QuerySet [1, 2]> )
#Null values are excluded
AppScoreValues= Movie.objects.order_by('-movieapp_score').values_list('movieapp_score', flat=True).exclude(movieapp_score__isnull=True)
MovieAppScore= Movie.objects.order_by('-movieapp_score').filter(movieapp_score__in=AppScoreValues[:5])
#Same as the above query for different field (like numbers)
numberOfLikesValues = Movie.objects.order_by('-numberOfLikes').values_list('numberOfLikes', flat=True).exclude(numberOfLikes__isnull=True)
likes = (Movie.objects.order_by('-numberOfLikes').filter(numberOfLikes__in=numberOfLikesValues[:3]))
#Same as the above query for different field (like numbers)
numberOfDislikesValues = Movie.objects.order_by('-numberOfDislikes').values_list('numberOfDislikes', flat=True).exclude(numberOfDislikes__isnull=True)
dislikes = Movie.objects.order_by('-numberOfDislikes').filter(numberOfDislikes__in=numberOfDislikesValues[:3])
watchByDate= Watched.objects.values('date_watched__month', 'date_watched__year').annotate(myCounter=Count('id'))
return render (request, 'dashboard.html', {'topFiveMovie': topFiveMovie, 'topFiveWatched': topFiveWatched, 'MovieAppScore':MovieAppScore, 'likes':likes, 'dislikes':dislikes, 'watchByDate':watchByDate})
Visit https://www.chartjs.org/ . In the Installation section you can find CDN link. Create a new template, name it dashboard.html. Copy and Paste the CDN link to your template dashboard.html.
{% extends 'base.html' %}
{% block title %}
<title>Dashboard</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
{% endblock title%}
1.PIE CHART FOR NUMBER OF LIKES
First Chart Type is pie, you can resize it by changing its canvas width and height.
<!-- PieChart NUmberOFlikes Start-->
<h5>Number Of Likes</h5>
<canvas id="PieChart" width="50" height="50"></canvas>
<script>
const ctxPieChart = document.getElementById('PieChart');
const PieChart = new Chart(ctxPieChart, {
type: 'pie',
data: {
labels: [ {% for m in likes %} "{{m.title}}", {% endfor %} ],
datasets: [{
data: [ {% for m in likes %} {{m.numberOfLikes}}, {% endfor %} ],
backgroundColor: [
'rgba(166, 40, 145, 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(166, 40, 145, 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>
<!-- PieChart NUmberOFlikes Ends -->
Pie Chart for Number of Likes is ready.
2. DoughnutChart For MovieApp Ratings
<!-- Doughnut MovieAppScore Starts Here -->
<h5>MovieApp Scores</h5>
<canvas id="DoughnutChart" width="50" height="50"></canvas>
<script>
const ctxDoughnut = document.getElementById('DoughnutChart');
const DoughnutChart = new Chart(ctxDoughnut, {
type: 'doughnut',
data: {
labels: [ {% for m in MovieAppScore %} "{{m.title}}", {% endfor %} ],
datasets: [{
data: [ {% for m in MovieAppScore %} {{m.movieapp_score}}, {% endfor %} ],
backgroundColor: [
'rgba(166, 40, 145, 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(166, 40, 145, 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>
<!-- Doughnut MovieAppScore Ends -->
3. TOP5 WATCHED MOVIES
<!--ChartJS Top5 Bar Starts Here -->
<h5>Most Watched Movies</h5>
<canvas id="barChart" width="50" height="50"></canvas>
<script>
const ctxbarChart = document.getElementById('barChart');
const barChart = new Chart(ctxbarChart, {
type: 'bar',
data: {
labels: [ {% for t in topFiveMovie %} "{{t.title}}", {% endfor %} ],
datasets: [{
label: 'Most Watched Movies',
data: [ {% for n in topFiveWatched %} {{n.myCounter}}, {% 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>
<!--ChartJS Top5 Bar Ends -->
4. PIE CHART NUMBER OF DISLIKES
<!-- PieChart Dislikes Starts Here -->
<h5>Number Of Dislikes</h5>
<canvas id="DislikeChart" width="50" height="50"></canvas>
<script>
const ctxDislikeChart = document.getElementById('DislikeChart');
const DislikeChart = new Chart(ctxDislikeChart, {
type: 'pie',
data: {
labels: [ {% for m in dislikes %} "{{m.title}}", {% endfor %} ],
datasets: [{
data: [ {% for m in dislikes %} {{m.numberOfDislikes}}, {% endfor %} ],
backgroundColor: [
'rgba(166, 40, 145, 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(166, 40, 145, 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>
<!-- PieChart Dislikes Ends -->
5. Total Number of Movies Watched on Monthly and Yearly
<!-- LineChart Watch Date Starts Here -->
<h5>Movies Viewed Dates:</h5>
<canvas id="LineChart" width="50" height="50"></canvas>
<script>
const ctxLineChart = document.getElementById('LineChart');
const LineChart = new Chart(ctxLineChart, {
type: 'line',
data: {
labels: [ {% for label in watchByDate %} {{label.date_watched__month}} +"-"+ {{label.date_watched__year}}, {% endfor %}],
datasets: [{
label: 'Movies Displayed',
data: [ {% for data in watchByDate %} {{data.myCounter}}, {% endfor %}],
backgroundColor: [
'rgba(166, 40, 145, 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(166, 40, 145, 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>
<!-- Linehart WatchDate Ends -->
My DB has data only for 2 monts, that's why it looks like this (for now).
We just created a nicelooking dashboard by using ChartJS. I really like its simplicity and cool looking animations.
That's it, thanks for reading.
- Hits: 491