Javascript

JavaScript is the scripting language for the Web. Its biggest strength is that it allows us to change and manipulate the contents of a web page after it has already loaded into the browser. Let's get the basic simple stuff out of the way by looking at basic programming constructs in JavaScript, enough to get us started off in D3. One nice thing to remember when encountering a programming language for the first time is that while each language has its own character, "way of thinking", pros and cons, there are some basic, universal structures they share. These structures are so common because they represent something deeper: they reflect the way we "think", how we logically "break down and chunk" problems when we are creatively solving a larger problem. So, if you have learnt an if-then-else structure before, if you've learnt a for loop before, even though they "look" different in each language, you've basically learnt them forever.

A complete digression here, but later (not in class) have a read of Peter Norvig's article on Teach yourself programming in 10 years. We could replace the word "programming" with design, with UX, with anything we want master. The point is that it takes years of careful, deliberative, patient learning. So, even if all this appears a little bit hard in the beginning and too much to take in, don't worry. We'll get there! Ok, back to work!


The Console: our inspection and debugging friend

Carrying on from the previous tutorial, go to the page http://localhost:8888 that is your index.html. Click on the link Empty D3 template to move to the 01_EmptyD3Template.html page that we created earlier.


Mathematical and Logical Operators

All Javascript standard mathematical operators are here. (By this is meant stuff like addition, subtraction, multiplication, division and other fancier cousins).

All Javascript standard logical operators are here. By this is meant stuff like AND, OR and NOT, and other fancier cousins, very handy for when we start writing if-then conditions).

All Javascript standard comparison operators are here. (By this is meant stuff like GREATER THAN, LESS THAN, EQUALS, and other fancier cousins, also very handy for when we start writing if-then conditions).

Skim through them, but don't try and remember all of them. These are go-to reference resources when we are writing our code.


Variables

Like all languages, in JavaScript too, variables contain data. A simple variable can hold just a single value:

var totalWidth = 960;
var totalHeight = 500;

Here, we are not saying that totalWidth equals 960, as we would in math. What we are really saying is that totalWidth is assigned a value of 960. It could change sometime later, or somewhere else. The container can be emptied and filled in with a new value. For example, if you're trying this in the console, and now type var totalWidth = totalWidth + 10;, its new value would be 970.

We can also assign float, character or boolean (true or false) values to variables:

var proportion = 0.95;
var name = "DECO3100";
var ThisYearsInfoVisWorkIsAwesome = true;


Arrays

Think of an array as a single variable that stores a list or sequence of data values. JavaScript permits a single array to contain differently typed data values; (i.e., technically, I could store the number 100 and the word apple in the same array. But, the general recommendation is to have arrays with all values of the same type to prevent confusion and chaos. Here are a few examples:

var data = [1, 1, 2, 3, 5, 8, 13, 21];
var names = ["f1", "f2", "f3", "f4", "f5, "f6", "f7"];
var values = [0.1, 0.2, 0.3];

Then, we can query the elements one by one, by using an index: data[0], data[1], etc. Note that in JavaScript we count from 0.


Objects

An object is way of building up a customised data structure. Often, in D3, we will need to define objects that are used recurringly in the same way for every project. Thus, we will be using "chunks" of code to define these objects. An object is defined with curly brackets that enclose a set of properties and their values, connected by a colon. Let's consider one very useful object we will need to define, the margin object, like so:

var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};

Thus, we have now defined a margin object which we can use later to specify the top, right, bottom, and left margins for our page. If you interactively type the above into your Console, you will see the following. Note that then asking for the value of margin.top returns the correct value.


JSON: JavaScript Object Notation

We have already seen csv as a data format. The other type of data format very commonly used is JSON or Javascript Object Notation. JSON is a format in which data is organised as a JavaScript Object (duh, of course!). Many web application programming interfaces (e.g. Twitter API) return data as a JSON variable, so it's a useful format to know. We can write simple Python scripts to easily convert JSON data into csv, but we will do this later if needed.

JSON data looks very similar to an object, with the only exception that the property names are now surrounded by quotation marks (i.e., they are string values):

var margin = {
"top": 20,
"right": 20,
"bottom": 30,
"left": 50
};

If you have property values that are text, these will also have strings:

var Rents = {
"Suburb": "Pyrmont",
"State": "NSW",
"SUA": "Sydney",
"MedianRent": 800
};

To store geographic data the format is called GeoJSON. We will delve more deeply into GeoJSON when we do geodata tutorials.


Functions

Understanding the idea of a "function" is fundamental to programming. A function can be imagined like a machine that is consuming something as an input, doing something to it, changing or transforming it in some way, and putting something out as an output. So, what it eats, or the inputs, are called arguments or parameters. What it spits out, or the outputs, are called, boringly, outputs.

Functions are rather like our brains. They take ideas in, through our sensors (eyes, ears, etc.), some transformations happen, and then we produce an output, in the form of other ideas. In fact, the human brain could be one of the most complex functions ever known to date, and it is a "black box" because we just use it, and don't really understand all that well how the "function" computes!

Thankfully, the functions we write in code are much simpler, and we always understand them in and out: we know they have to do exactly what we want them to do! To do something as a defined block of actions, we make a function, and then call the function whenever we want to perform that particular set of tasks. For example, we might want to take in a number, and return a colour based on the number.

In JavaScript, calling functions look like this:

function_name(inputs);

In the Console window, type:

console.log("How would the world ever do Info Vis if numbers didn't logically map to colours?");

This is an example of a function that simply takes in the input parameters and prints them to the console.

Ok, now let's make a function. In JavaScript, you can actually save a function in a variable name. So, lets define a simple function in which we take in a number, and return an rgb colour. This is something you can use, for example to generate a monochromatic set of colours for a vis (of course, only after you have transformed your data to lie in the range of 0 and 255. Right now, we just assume we already have, we will see the idea of "scales" in a later tutorial).

var calculateRGB = function (number){
  return "rgb(" + number + ",0,0)";
}

Try this in the Console. You can see that now when we call the function with an input of 100, it returns rgb(100,0,0).

The word return is used to output the values from a function. So, the basic idea is that now having defined the function, you can take an entire array of data, a set of numbers, and call the function again and again to get back a full set of colours, mapped to your data.

A last note on anonymous functions, i.e., functions with no names, embedded inside our D3 calls. We will use these a lot, but let's wait till we get to the point where we need them.


Control structures: if() and else

An if() statement is conditional test: When the test is satisfied, or returns true, or the condition being tested holds, then the code within the chunk is run. If it returns false, or does not hold, nothing happens.

if (test) {
  //If true, then do this.
}

Let's discuss a particularly useful situation in which an if() will be used. Suppose you have a dataset in which you want to show all the elements that are below the average in one colour and above the average in another colour. You will use a structure like:

var average = 10;
var returnColour = function(data) {
  if (data > average) {
    return "green";
  } else {
    return "red";
  }
}

This is what happens when we use it. Try a few examples.

This is a chunk of code that can be embedded in our code as an anonymous function later when we write full-fledged D3 code to produce visualisations (that is, without the need to put it in a variable with a function name as we have done here). As of now, we simply think of it as a logical and reusable code block.

You can also have multiple sets of if ... else statements. You can also combine more than one condition using operators && (meaning AND), or || (meaning OR). For example, you may want to return four letters (or colours), depending on grades "Pass", "Credit", "Distinction" and "High Distinction". In the code below, we use the AND operator as in "&&" and equal operator as in "==":

var returnGrade = function(marks) {
  if (marks > 49 && marks <= 64) {
    return "P";
  } else if (marks >= 65 && marks <= 74) {
    return "C";
  } else if (marks >= 75 && marks <= 85) {
    return "D";
  } else if (marks >= 85) {
    return "HD";
  }
}

What happens is shown below. Again, try typing this into the console and try a few numbers to check whether this is working. Try inserting another condition at the end where a mark above 100 returns a "Super awesome" or an "SA" (You will also have to change the HD condition).


Control Structures: for() loops

For loops are easy: you just use them when you want to perform an action a number of times. Say you want to iterate over each element in your data set one by one, and do something to them. That's where you use a for loop. From Scott Murray's book, here is the format:

for (initialization; test; update) {
  //Code to run each time through the loop
}

Let's understand what this means by an example. Suppose we wish to add all the numbers in a data set. Here is what we do:

var data = [8, 10, 12, 1, 6];
var sum = 0;
for (var i = 0; i < data.length; i++) {
  sum = sum + data[i];
  console.log(sum);
}

Of course, we could just use an inbuilt sum function, but it is good to understand sometimes how to do things from the bottom up, just in case we need to do something for which there is no in-built function. Here is what we get when we do this in the console:

Let's understand this part by part:

  1. Define a data set in the data variable as an array.
  2. Define a variable called sum and set it to 0.
  3. Three parts of the for loop:
    • initialization:Set a counter variable i to 0
    • test: We are iterating through every element of the data till we reach the final element. How do we know we are at the final element? Because the loop runs as long as the value of i is less than the total length of our data array, and stops when it becomes equal. The total length is 5, so data.length is 5. Here data.length is a property of arrays: every array has a length which can be measured using arrayName.length. We iterate from 0 to 4, thus iterating over every element of the data array.
    • update: Each time we iterate over one value, we increase i by 1. As long as the test condition holds, this keeps increasing every loop.
  4. Finally, the code chunk inside the for loop does exactly what we want, add each element of the data array, store the result in sum variable, and we have console.log within the loop to print the value of sum variable each time to show that there is indeed this cumulative sum building up as i goes from 0 to 4.

Ok, we have all the tools and tricks we need to get started on D3 properly. There is tons of other stuff to learn in JavaScript, of course, but we now know enough to start off D3. If we need to learn more, we will do it as we go.


Sarkar, S. and Hussein, D.A., 2017, D3 Tutorials for Information Visualisation Design Studio, University of Sydney.
Email: somwrita.sarkar@sydney.edu.au, dhus4848@uni.sydney.edu.au