Create Interactive Data Visualisations with Django & Chart.js

How to visualise your data with interactive graphs + BONUS: asynchronous vanilla JS!

Louis de Bruijn
Mar 26 · 5 min read

In this story I am going to show you how to visualise your data in the beautiful graphs provided by the chart.js library. These charts are far more beautiful than any charts you’ve previously created with matplotlib, and besides that they can be manipulated by your users!

Also, I wanted to take this opportunity to give another crack at the asynchronous javascript execution (AJAX), this time using Vanilla JS XMLHttpRequest.

What we’ll cover today:

  • Send and catch asynchronous responses with XMLHttpRequest, Django’s JsonResponse and the FormData object.
  • Set up the labels, values and colours for the charts.
  • Create doughnut, bar and line charts.
  • Provide user feedback.

Let’s start with the HTML form > work our way to the backend with JS > return a response > catch the response and display results and feedback. For this project we’ll be using two abusive language datasets for Twitter, that I am also using for my Master’s thesis.

Asynchronous requests

In order to send an asynchronous Javascript request to our backend, we’re going to create a normal HTML form and prevent the default response of submitting & reloading the webpage. We’ll then create a FormData object and send this via Javascript to our Django backend.

There is no submit button in this form, so we’ll have to add a addEventListener that registers when a specified event click is delivered to the target input. We’re then going to gather the form fields in a FormData key-value object that we’ll send to our Django backend through an XMLHttpRequest. All of this is done in vanilla (=pure) Javascript.

In somewhat pseudocode:

  • line 2-3 We’re waiting for a click on a HTML element with class="form-check-input dataset"
  • line 4–5 We’re grabbing the HTML form element and creating a key-value object.
  • line 7-9 We’re opening a new request with the form method POST and action or url and sending our key-value object to the Django backend.

Django backend

This is where we’re going to prepare and convert our data and set everything up for returning a response filled with data. We’re also going to provide some user feedback with a message.

When we access this route with a GET method, we simply display the template demographics.html that includes the HTML form, but when we access this view with a POST, we’re going to prepare our data and send a JsonResponse. line 15-19 is where we’re preparing our data for the charts. line 19-20 is where we’re using Django’s render_to_string that enables us to load a jinja2 template with variables to a string. The third argument is the context dictionary from which we can use the keys in the template as such {{ tags }}. The template includes/message.html for instance, looks like this:

<li>
<div class="alert alert-{{ tags }} msg fade show" role="alert">{{ message }}</div>
</li>

It also important to note that we’re sending a dictionary response with all of our data, that we’re going to extract in Javascript two sections down. We’re converting this dictionary to a JSON object and then unpacking it with the JSON.parse method in Javascript.

Data prepping

To show how we’re prepping the data I’ve selected three functions hashtag_demographics, creation_date_demographics and text_demographics.

The most interesting take-outs and code bites are:

  • Chart.js expects three lists for its charts: a list of labels, a list of values, and a list of colours (in hex-codes). We’re using the zip function with * to iterate through lists of tuples [(label, value), (label value)].
  • For the colour schemes we’re using the seabornpackage, which comes with sets of beautiful colour palettes.
  • For the time series we need to convert Python’s datetime objects to Javascript Date objects and we do so in line 44.
  • line 62-69 vectorises the tweet content to tf-idf counts, which is a common practice other than counts to vectorise.

JSON response

The JsonResponse that we’re sending from our Django backend in demographics.py, line 33 should be another addEventListener that we’re appending to our send_request.js.

  • line 15 shows how we catch the response object and convert its JSON to an object, this makes the keys and values in our response objects coming from the Django object accessible!
  • line 18-20 is how we add the message to our messages-list element in our HTML page. I am using a custom function fade_alerts() that fades out the message after a while.
  • line 23-26 is how we add the textual information to our webpage.
  • line 29-36 shows how we extract the values, labels and colours for our chart.js visuals in returnCharts() and showCharts() functions as explained in the next section.

Chart.js visualisations

For brevity I’ve decided to only include the script for the time-series line chart (as always, full code can be found at the bottom). get_time_config() defines the configurations for the chart, convertDates() converts the list of dates into Javascript Date objects while returnChart() and showChart() define and display the chart.

line 67 is important, as it grabs the element with id="time" and uses it in line 70 to append the chart to that element. This element is defined in the template includes/demographics.html in demographics.py, line 20 as <canvas id="time"></canvas>.

The end

At last we’re going to add a bit of Javascript in the request.js that get’s loaded when the view is rendered that simulates a click event so that the demographics get loaded via the same route as shown above.

var hatEvalData = document.getElementById("hateval_dataset");
hatEvalData.click();

Full code and scripts can be found here. Also, you can interact with a live demo of these charts here.

JavaScript in Plain English

Learn the web's most important programming language.

Louis de Bruijn

Written by

Master Information Science student, University of Groningen. Python enthusiast and Data Scientist at Ortec Finance.

JavaScript in Plain English

Learn the web's most important programming language.

More From Medium

More from JavaScript in Plain English

More from JavaScript in Plain English

More from JavaScript in Plain English

32 funny Code Comments that people actually wrote

10.3K

More from JavaScript in Plain English

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade