Istanbul/Turkey

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: 330