Monday 26 January 2015

Functional Programming, d3.js a good example

If you have ever tried to use d3.js to visualize your data, you already have used some of the features of functional programming. I never forget the difficulty of the first time I tried to understand the d3.js sample codes. In fact, it was d3.js and JavaScript which encouraged me to try to understand the Lambda Calculus itself. Let us take a look at a simple graph, and see how functional programming works here well.

First take a look at the page and its source we are going to talk about.  Here is the d3.js sample graph ...  Just note that the included strange script is nothing but uploaded "d3.v3.min.js" path in google drive.

JavaScript is one of the strangest programming languages you can find, you may have heard of good and bad parts of JavaScript! It lets you use many features of procedural languages as well as some features of event-driven programming, object-oriented and functional programming. d3.js is a single JavaScript function that gives all the visualization support we want to have almost all in functional form.

For example, look at the following line of code which simply creates a scale to assign any number between 0 and 2000 to an already defined color array.

var colorScale = d3.scale.quantile().domain([ 0, 2000 ]).range(colors);

Or see how we define a graph layout:

var force = d3.layout.force()
.charge(-80)
.gravity(0)
.size([width, height)
.on("tick", tick);

Since these are parameters passed to layout, you can change their order however you want, and it works like the previous one, and this proves it is not ordinary method calls we have in OOP.

var force = d3.layout.force()
.size([width, height)
.charge(-80)
.on("tick", tick)
.gravity(0);

Another good example is the following piece of code, which draws the top legend colored rectangles. The key to understanding it is that the legend variable somehow contains all the legend color placeholders, but not the rectangles themselves and like stream() we had in Java, it loops through the legend placeholder elements and as you call append("rect") and ... it appends SVG rectangle for each at certain place with certain colors.

legend.append("rect")
.attr("x", function(d, i) { return 10 + legendElementWidth * i; })
.attr("y", 10)
.attr("width", legendElementWidth)
.attr("height", gridSize / 2)
.style("fill", function(d, i) { return colors[i]; });

The fact is if you wanted to draw this graph in some procedural or OOP method I would assure you that it was much more difficult than doing it in this way. Although understanding the functional programming (or the way d3.js works) takes time and both have long learning curve, but as you get familiar with the concept of the functional programming, programming life gets easier.

Sample d3.js visualization ...