Create a COVID-19 Dashboard with JavaScript
By: Varun Joshi
Tags: JavaScript, Software Development, Covid 19, Coronavirus, Programming

Now that we have decided what we want to build, let’s start writing some HTML & CSS!

The HTML

First, let’s take a look at all the libraries & scripts we need to import to create our beautiful dashboard.

We’re going to use Bootstrap 4 to manage our views and make our web app look great on mobile devices. Then, we need to select a font. One of my recent favourites is Work Sans, its sans-serif & is perfectly readable across all screens. You may want to check out other fonts on Google Fonts.

We’ll be importing scripts to all the libraries we are going to use here. Your <head> tag should be looking like this:

A note about the meta tag on line-3:

<meta content="width=device-width, initial-scale=1" name="viewport" />

This means that the browser will render the width of the page at the width of its screen. So if that screen is 320px wide, the browser window will be 320px wide, rather than way zoomed out and showing 960px. This helps for responsive design and should be used only if you intend your website to be responsive.

Our HTML is divided into the following parts:

The top header which consists of a title, a dropdown to select the country & a button which opens a modal displaying important information regarding the dashboard. (The modal is optional). The left container which consists of our graphs and statistics. This container data is fetched from the internet using the Axios library. The right container which shows a couple of resources from WHO. This is static and not fetched from an API.

The header div is pretty simple with a standard <select> tag & a button.

For the left & right containers, we’ll be using the bootstrap grid. Divide the grid into two parts ( col-lg-8 & col-lg-4 ).

Let’s create the left container first. Take a look at the design. We want to add the flag & name of the country selected, a div that shows active cases & a collapsible view which contains 3 divs for Confirmed, Recovered & Deaths.

To get the flag of each country, check out CountryFlags.io, an awesome but simple API that helps you get the flag of any country!

The collapsible divs each contain a chart, a dropdown to select the days for which stats are shown & the total count of cases in that day range.

This collapsible view is called an accordion because it works just like one.

An Accordion. It expands and collapses to create music.

In our case, the accordion div will contain all cards, these cards will expand and collapse on clicks & display our charts!

In the end, after you’ve added the country name, Active status div & the three cards to the accordion, your final code for the left container should be:

Phew, now let’s quickly finish off the static resources-container. It contains bootstrap cards, you can find a super handy resource which gives you a cheat sheet for all the bootstrap classes, with all the code!

The CSS

The CSS is fairly simple, and we will not be covering all the classes & properties used in this project until we discuss media-queries.

Hence, use the below CSS to give your dashboard the final look and feel.

Good job sticking around till here! We’re on track to create our final product! The next step is to work with JavaScript, which will be the longest part of this tutorial.

It is true what they say for the 80/20 rule:

80% of work takes 20% of the time while 20% of the work takes 80% of the time!

The JavaScript

Before we dive into the actual code, let’s familiarise ourselves with IIFEs & Promises.

Immediately Invoked Function Expressions

IIFEs are functions in JavaScript which run as soon as they are defined. They are “immediately invoked” when your script file is run. Hence, they do not need another function to call them.

Pre ES6:

(function(){

console.log('Welcome, this is an IIFE!');

})();

ES6:

(() => {

console.log('Welcome, this is an IIFE!')

})();

Promises

To understand promises, consider an example. Say you’re baking a cake for the first time & the recipe says it takes 45 minutes to bake a cake. Now once you start baking a cake, you don’t know if you’re going to bake it right until the 45 minutes are up.

There are two outcomes, if the cake is baked right, then you can eat your cake 🍰, or else if you’re like me, you burn your kitchen down & decide to just buy a cake the next time. 🤷🏼‍♂️

So there are three states:

Pending: You don’t know if the cake is going be baked right. Fulfilled: Your cake is baked right, so you can eat it. Rejected: Your burn your kitchen down, so you can’t have it.

The above scenario in a JavaScript promise would look like this:

let isCakeBakedRight = true; const bakeCake = new Promise(

(resolve, reject) => {

if ( isCakeBakedRight ) {

// Eat the cake! 🍰

resolve("Eat");

} else {

const reason = new Error("Oven's on fire");

reject(reason);

}

}

);

Axios is a promise-based HTTP client for the browser & node js.

Now that you know about IIFEs & Promises, let’s start creating our JS Controllers.

Let’s start by creating the UI Controller first. The UI controller, true to its name, will handle all operations related to the UI such as getting the data from the API, creating charts & updating the values for the number of cases.

Let’s take a look at each of the code-blocks & functions in the UI Controller.

HTMLStrings

This variable stores all the strings we use in the HTML to identify classes or ids. This makes sure you don’t spend hours debugging typos & allows for quick & error-free referencing.

setTotalCasesForStatus(status)

The API which we use in this project returns total country data in two ways:

For the entire country For each province in the country

Due to this, we will be creating 4 variables and looping through the summary data returned by the API. This will work for both the ways listed above.

This function will also set the values to the UI.

setCasesForStatus(count, status)

This function will set the number of cases for the last 30, 60, 90 & 120 days for the selected status.

getChartColors(status, type)

This function is used to set the chart colours, for the background & the border of the chart.

setChartForStatus(data, status)

This is an important function. This function collects the data received from the API & creates a chart for the selected status.

Our line chart requires an array of labels for the X-Axis, which we insert as an interval of 5 days (due to a large number of dates, 30 or above). We also insert the current date to make sure it is not missed out.

We pass the labels & dataset to the chart, along with the background colour & border colour. We also provide some custom options for the Y-axis such as the step size for the axis & if it should begin from 0.

Documentation on more options and chart types can be found here.

let ctx = document.querySelector(chartName);

let statusChart = new Chart(ctx, {

type: 'line',

data: {

labels: labels,

datasets: [{

label: status+ ' Cases',

data: chartData,

backgroundColor: getChartColors(status, 'background'),

borderColor: getChartColors(status, 'border'),

borderWidth: 2

}]

},

options: {

scales: {

yAxes: [{

ticks: {

beginAtZero: false,

stepSize: 10000,

}

}]

}

}

});

getCountryFlag(country)

This function uses a simple switch-case to return the flag ID for the CountryFlags API.

The next list of functions is exposed from the controller so that they can be called outside the U IController.

numberFormat

This function returns the number formatted as per the required locale. If you’re looking for numbers to be returned as 1,00,000 use the en-IN locale option. More details here.

getSummaryCount

This function fetches the summary count from the API for the full day.

MomentJS is a simple and handy library which lets you manipulate the date and time in JavaScript.

For example, if you want yesterday’s date and time, all you need to do is,

let yesterday = moment().subtract(1, 'days');

// 2020-06-05T22:06:42+05:30

Remember our discussion regarding promises? Let’s use it. In the code-block below, the Axios object fires a GET request to the API. The method returns a Promise so that we can use the then and catch methods to handle the result.

The then method is called when the promise is fulfilled. The catch method handles rejections & other errors.

axios.get('https://api.covid19api.com/country/' + selectedCountry + '?from=' + yesterday + 'T00:00:00Z&to=' + today + 'T00:00:00Z')

.then( response => {

let res = response['data'];

setTotalCasesForStatus(res);

}).catch( error => {

console.log(error);

});

getCasesForStatus(status, delta)

This method gets the total cases for the status and the delta specified by the user. The default delta is set to 30 days. So you will see the data for the last 30 days from the current date by default.

This is where momentJS makes our job easier by providing the subtract method which gives the delta date.

On fulfilment of the promise, this method sets the count for the status & creates the charts.

That’s is for the UI Controller. Next, we will create the IIFE that will set up eventListeners and create a default environment.

Additional Task: Writing a Media Query for mobile devices.

Media Queries were introduced with CSS3. It uses the @media rule to include a block of CSS properties only if a certain condition is true.

The media query below will set some different properties if the screen-size is below 600px.

@media screen and (max-width: 600px) {

.left-container {

height: auto !important;

}

.right-container {

height: auto !important;

} .details-container {

margin: 0;

} .resources-container {

margin: 0;

} .col-lg-5 {

margin-top: 15px;

} .country-select {

margin-top: 14px;

} .active-cases {

width: 60%;

}

}

More on Media-Queries in this awesome freecodecamp.org post.