Tutorial: Processing, Javascript, and Data Visualization

[The above graphic is an interactive 3D bar graph. If you can’t see it, it’s probably because your browser sucks can’t render WebGL content. Maybe try Chrome or Firefox?]

Ben Fry and Casey Reas, the initiators of the Processing project, announced at the Eyeo Festival that a new version of Processing, Processing 2.0, will be released in the fall (VIDEO). This 2.0 release brings a lot of really exciting changes, including vastly improved 3D performance, and a brand-new high-performance video library. Perhaps most interesting is the addition of publishing modes – Processing sketches can now be published to other formats other than the standard Java applet. The mode that is going to cause the most buzz around the interweb is Javascript mode: yes, Processing sketches can now be published, with one click, to render in pretty much any web browser. This is very exciting news for those of us who use Processing for data visualization – it means that our sketches can reach a much broader audience, and that the visual power of Processing can be combined with the interactive power of Javascript.

While preview releases of Processing 2.0 will be available for download very soon, you don’t have to wait to experiment with Processing and Javascript. The upcoming JS mode comes thanks to the team behind Processing.js, and we can use it to build sketches for the browser right now.

To get started, you can download this sample file. When you unzip the file, you’ll see a directory with three files – the index.html page, processing.js, and our sketch file, called tutorial.pde. If you open the sketch file in a text editor, you’ll see something like this:

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
}

void draw() {
  //instructions in here happen over and over again
}

If you’re a Processing user, you’ll be familiar with the setup and draw enclosures. If you’re not, the notes inside of each one explain what’s going on: when we run the sketch, the size is set to 500px by 500px, and the background is set to black. Nothing is happening (yet) in the draw enclosure.

You can see this incredibly boring sketch run if you open the index.html file in your browser (this will work in Firefox and Safari, but not in Chrome due to security settings).

Processing.js is a fully-featured port of Processing – all of the things that you’d expect to be able to do in Processing without importing extra libraries can be done in Processing.js. Which, quite frankly, is amazing! This means that many of your existing sketches will run, with no changes, in the browser.

Since this is a data visualization tutorial, let’s look at a simple representation of numbers. To keep it simple, we’ll start with a set of numbers: 13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9 35.1, 34.3. (These numbers are obesity percentages in the U.S. population, between the 1960s and the present – but we’re really going to use them without context).

Typically, if we were to put these numbers into a Processing sketch, we’d construct an array of floating point numbers (numbers with a decimal place), which would look like this:

float[] myNumbers = {13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3};

However, we’re not in Java-land anymore, so we can make use of Javascript’s easier syntax (one of the truly awesome things about Processing.js is that we can include JS in our sketches, inline):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

Our .pde file, then, looks like this:


var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
}

void draw() {
  //instructions in here happen over and over again
}

Now that we have our helpful list of numbers (called, cleverly, ‘numbers’), we can access any of the numbers using its index. Indexes in Processing (and Javascript) are zero-based, so to get the first number out of the list, we’d use numbers[0]. To get the fourth one, we’d use numbers[3]. Let’s use those two numbers to start doing some very (very) simple visualization. Indeed, the first thing we’ll do is to draw a couple of lines:

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  //Draw two lines
  stroke(255);
  line(0, 50, numbers[0], 50);
  line(0, 100, numbers[4], 100);
}

void draw() {
  //instructions in here happen over and over again
}

OK. I’ll admit. That’s a pretty crappy sketch. But, we can build on it. Let’s start by making those lines into rectangles:

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  //Draw two lines
  stroke(255);
  rect(0, 50, numbers[0], 20);
  rect(0, 100, numbers[4], 20);
}

void draw() {
  //instructions in here happen over and over again
}

At this point, I’m going to introduce my very best Processing friend, the map() function. What the map() function allows us to do is to adjust a number that exists in a certain range so that it fits into a new range. A good real-world example of this would be converting a number (0.5) that exists in a range between 0 and 1 into a percentage:

50 = map(0.5, 0, 1, 0, 100);

We can take any number inside any range, and map it to a new range. Here are a few more easy examples:

500 = map(5, 0, 10, 0, 1000);
0.25 = map(4, 0, 16, 0, 1);
PI = map(180, 0, 360, 0, 2 * PI);

In our sketch, the list of numbers that we’re using ranges from 13.4 to 34.3. This means that our rectangles are pretty short, sitting in the 500 pixel-wide sketch. So, let’s map those numbers to fit onto the width of our screen (minus 50 pixels as for a buffer):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  //Draw two rectangles
  rect(0, 50, map(numbers[0], 0, 34.3, 0, width - 50), 20);
  rect(0, 100, map(numbers[4], 0, 34.3, 0, width - 50),  20);
}

void draw() {
  //instructions in here happen over and over again
}

Two bars! Wee-hoo! Now, let’s use a simple loop to get all of our numbers on the screen (this time we’ll use the max() function to find the biggest number in our list):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  for (var i = 0; i < numbers.length; i++) {
    //calculate the width of the bar by mapping the number to the width of the screen minus 50 pixels
    var w = map(numbers[i], 0, max(numbers), 0, width - 50);
    rect(0, i * 25, w, 20);
  }
}

void draw() {
  //instructions in here happen over and over again
}

We’re still firmly in Microsoft Excel territory, but we can use some of Processing’s excellent visual programming features to make this graph more interesting. For starters, let’s change the colours of the bars. Using the map() function again, we’ll colour the bars from red (for the smallest number) to yellow (for the biggest number):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  for (var i = 0; i < numbers.length; i++) {
    //calculate the amount of green in the colour by mapping the number to 255 (255 red &amp; 255 green = yellow)
    var c = map(numbers[i], min(numbers), max(numbers), 0, 255);
    fill(255, c, 0);
    //calculate the width of the bar by mapping the number to the width of the screen minus 50 pixels
    var w = map(numbers[i], 0, max(numbers), 0, width - 50);
  	rect(0, i * 25, w, 20);
  }
}

void draw() {
  //instructions in here happen over and over again
}

This process of mapping a number to be represented by a certain dimension (in this case, the width of the bars along with the colour) is the basic premise behind data visualization in Processing. Using this simple framework, we can map to a whole variety of dimensions, including size, position, rotation, and transparency.

As an example, here is the same system we saw above, rendered as a radial graph (note here that I’ve added a line before the loop that moves the drawing point to the centre of the screen; I’ve also changed the width of the bars to fit in the screen):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500);
  background(0);
  
  //move to the center of the sketch before we draw our graph
  translate(width/2, height/2);
  for (var i = 0; i < numbers.length; i++) {
    //calculate the amount of green in the colour by mapping the number to 255 (255 red &amp; 255 green = yellow)
    var c = map(numbers[i], min(numbers), max(numbers), 0, 255);
    fill(255, c, 0);
    //calculate the width of the bar by mapping the number to the half the width of the screen minus 50 pixels
    var w = map(numbers[i], 0, max(numbers), 0, width/2 - 50);
  	rect(0, 0, w, 20);
  	//after we draw each bar, turn the sketch a bit
  	rotate(TWO_PI/numbers.length);
  }
}

void draw() {
  //instructions in here happen over and over again
}

So far we’ve been keeping things very simple. But the possibilities using Processing and Javascript are really exciting. It’s very easy to add interactivity, and it’s even possible to take advantage of Processing’s 3D functionality in the browser.

Here’s our numbers again, rendered in 3D (note the change to the size() function), with the rotation controlled by the mouse (via our new friend the map() function):

var numbers = [13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3];

void setup() {
  //instructions in here happen once when the sketch is run
  size(500,500,P3D);
  background(0);
  
}

void draw() {
  //instructions in here happen over and over again
  background(0);
  //turn on the lights so that we see shading on the 3D objects
  lights();
  //move to the center of the sketch before we draw our graph
  translate(width/2, height/2);
  //Tilt about 70 degrees on the X axis - like tilting a frame on the wall so that it's on a table
  rotateX(1.2);
  //Now, spin around the Z axis as the mouse moves. Like spinning that frame on the table around its center
  rotateZ(map(mouseX, 0, width, 0, TWO_PI));
  for (var i = 0; i < numbers.length; i++) {
    //calculate the amount of green in the colour by mapping the number to 255 (255 red &amp; 255 green = yellow)
    var c = map(numbers[i], min(numbers), max(numbers), 0, 255);
    fill(255, c, 0);
    //calculate the height of the bar by mapping the number to the half the width of the screen minus 50 pixels
    var w = map(numbers[i], 0, max(numbers), 0, width/2 - 50);
    //move out 200 pixels from the center
  	pushMatrix();
  		translate(200, 0);
  		box(20,20,w);
  	popMatrix();
  	//after we draw each bar, turn the sketch a bit
  	rotate(TWO_PI/numbers.length);
  }
}

Thirty lines of code, and we have an interactive, 3D data visualization (you can see this sketch running inline in the header). Now, I understand that this isn’t the best use of 3D, and that we’re only visualizing a basic dataset, but the point here is to start to imagine the possibilities of using Processing with Javascript in the browser.

For starters, Javascript lets us very easily import data from any JSON source with no parsing whatsoever – this means we can create interactive graphics that load dynamic data on the fly (more on this in the next tutorial). On top of that, because we can write Javascript inline with our Processing code, and we can integrate external Javascript functions and libraries (lie JQuery) to our sketches, we can incorporate all kinds of advanced interactivity.

I suspect that the release of Processing 2.0 will lead to a burst of Javascript-based visualization projects being released on the web. In the meantime, we can use the basic template from this tutorial to work with Processing.js – have fun!

31 thoughts on “Tutorial: Processing, Javascript, and Data Visualization”

  1. The page begins with this quote: "The above graphic is an interactive 3D bar graph. If you can't see it, it's probably because your browser sucks…"

    Well, I could not see the graphic. Shame on me I guess for using a browser that comes installed in many new computers. I use it regularly for some pretty complex, interactive web-based applications. There are other possible explanations for why this particular web page does not work in a major browser, of course. For example, the page depends heavily on javascript and uses Flash, two technologies that are not guaranteed to be present in every situation. There might be other explanations. Probably just a matter of settings. It would be nicer to help the user be successful with his software than to spit in his face.

    That kind of hateful language has a bullying tone, like sophomores hazing freshmen. It does not build goodwill in an introductory tutorial. It is a smack in the face to a newcomer who showed up in good faith looking for help. It creates risk for an instant turn-off to a software that a lot of good people have worked very hard to build. Why would the community be willing to p*ss away all that effort just so someone can indulge in a snarky laugh line?

    If the Processing.org community want people outside the inner circle to use this stuff, they would benefit from a sober look at the attitude on display to the public.

    1. I don't usually comment anywhere, but seriously David – Get a life.

      Thanks Jer, out of a bunch of tutorials I did this week, only this one made me laugh.

  2. Dave,

    Bullying? Hateful? Really?

    If you are so attached to your choice of web browser that a tongue-in-cheek comment about its inadequacies feels like a 'smack in the face', I think you need to start taking software a little less seriously.

    I suppose I could have written the line like this:

    [The above graphic is an interactive 3D bar graph. If you can't see it, it's probably because your browser doesn't have the ability to render WebGL content. Maybe try Chrome or Firefox?]

    But frankly, if I'm going to put hours of my own time into writing a tutorial (one of dozens that I've written on this site), I think I'm allowed to indulge in a 'snarky laugh line' or two.

    ** edit – in order to keep everyone happy and to keep the focus on the red hot learning action, I've redacted the original caption.

    -Jer

  3. @blprnt don't waste you time responding to it. As for @David please, if you'e newcomer buy yourself a "Learning Processing: A Beginner's Guide to Programming…" by Daniel Shiffman if you can't handle this tutorial.

  4. WebGL is a choice. Not the only one. HTML5 offers another way though, granted, not the only way. WebGL is controversial from a security standpoint as it is reported to open a known avenue of attack into Chrome and Firefox. Hopefully the Processing.org community will implement alternative methods for 3D rendering to give developers and users more choices. If they already have, then maybe a version of this tutorial on HTML5 or some other standards-based method?

    Hopefully the security issues have been addressed. Maybe somebody can update that information for us here.

    See http://www.geek.com/articles/chips/webgl-flaws-pu

    See also http://www.pcworld.com/businesscenter/article/230

    David

    1. Hi David,

      First, I apologize for any offense that you took from my 'your browser sucks' line (which has been changed), or my terse reply. I certainly didn't mean to be hateful or bullying.

      As for WebGL, you are right, it is a choice. However, this tutorial uses Processing.js, which uses WebGL to render 3D content, so in order to see it you'll need to have a WebGL enabled browser. If you don't want to download one, then you won't see the finished content.

      I'm not on the Processing.js team, so I can't really speak for them – but I for one am very excited about the prospect of hardware-accelerated graphics in the browser. I'm not a GL expert, so I can't speak about the WebGL security concerns – maybe someone from the Processing.js team will be able to give some insight.

      -Jer

      1. Nice tutorial.
        I'm not with processing or any other standards body but I spent the last 2 years learning OpenGL and programming GPUs, and as far as I know there is no alternative to WebGL for 3D content on the web. This is because WebGL allows you to use the graphics card in the computer. Without that any javascript based code can not do 'real' 3D (HTML5 uses WebGL to do 3D)

        The security issues are real but temporary, and no worse than any of the crap thats happened in IE. I think you have a legitimate reason to say IE sucks (you should have called it out by name though, because it's possible that people have webgl turned off or an older version of FF/Chrome). What needs to happen is improved security from the GPU vendors (NVIDIA and AMD) who have notoriously crappy code because up until recently they didn't have to worry about security.

        As someone who has been developing content for the web for almost a decade, IE has stood in the way of technology in so many ways that I will openly degrade it. We are finally at a point where IE support is not necessary for a successful website or web application because enough people have made the switch to modern standards based browsers.

        Anyway, keep up the good work! You are a gentleman and a scholar!
        Ian

  5. Jer – Freedom of speech certainly gives you the right to indulge in as many snarky laughs as you want. Being encouraging to first-time users trying to learn something, though, would be better for the Processing community and the world in general. I tried FireFox Mac 3.6.2 and got this error:

    Unable to execute pjs sketch: TypeError: Processing.debug is not a function

    I tried Safari Mac 5.1 and it said there were 6 errors opening the page. I didn't dig through the Activity window very far, but it shouldn't be necessary.

    As an early programmer in personal computing in the late 70s and early 80s, we all worked together to try to help each other as best we could to welcome and encourage newbies interested in learning because in the end, we're all newbies as soon as any new technology arrives, and many times within a particular yet-unexplored corner of an existing technology.

    It seems there are injured feelings now for both parties, when in the end, it could have all been avoided in the first place with, "If your browser doesn't display the graphic, click <here> for some possible solutions." (See the Arduino ARDX tutorials from :Oomlout: for examples of a really good approach to tutorials for newcomers). The 2nd thought rephrasing with FireFox as a solution actually wouldn't have helped. The other lost opportunity was in brushing off the time that one of your readers took to write with an honest commentary on his first-time experience here.

    In the end, yes, you can indulge in as many snarks as you want; it's your own blog after all. But once you are indeed putting in all those hours into writing with the presumed objective of helping others and growing a community, why kick over the bucket?

    1. Roger,

      Thanks for your reply. I am a fan of your work with Hyperstudio (I'm not sure if you've read my previous posts about Hypercard), and I appreciate your taking the time to comment.

      Actually, I appreciate and respect all of the comments that I receive. Dave's initial one caught me off guard because I honestly didn't think (and still don't think) that my language was anywhere near hateful or bullying. It seemed like a gross overreaction. I'll admit that my own reply was terse, but I take an accusation of bullying quite personally, having been a victim of severe bullying in my school years.

      I've been teaching programming to 'newbies' since 1993. While I don't have the depth of experience that you have, I'm sure that we share a similar dedication to learning and belief in the transformative power of programming.

      I've apologized to Dave for any offense he may have taken and have changed the initial line of the tutorial. Which, for posterity's sake, read:

      [The above graphic is an interactive 3D bar graph. If you can't see it, it's probably because your browser sucks. Maybe try Chrome or Firefox?]

      -J

  6. (Different Dave here)

    More to the point, I think there are some errors that are preventing me from running the last two versions of the sketch in any browser. There's an &lt in the loop functions in the last 4 examples that it's choking on if I copy and paste. Change that to < (less than, if this crunches the symbol in comments also) and the next to the last example (no WebGL) runs in Safari but not Chrome. OK, that's as expected. I guess Safari gets slammed for no WebGL but it is the only one of the two that will run the non-WebGL versions as formatted due to security, right?

    Then how does one run the last one?

    Change tutorial.pde to match the last example, with the less than correction.

    If I try running the index.html in Chrome (which can handle WebGL) I get:

    Unable to load pjs sketch files:
    tutorial.pde ==> No content

    And if I try it in Safari, I get

    Unable to execute pjs sketch: WebGL context is not supported on this browser.

    As expected.

    What's the right way to do this?

    Thanks, Jer!

    1. Dave,

      Chrome doesn't allow you to load local Javascript content. It's a security thing. Strange, but as far as I can see, there's nothing that can be done about it. If you load the files to a web server, you'll see everything running beautifully.

      The upcoming Processing 2.0 release actually loads web content in a little local web server to get around this issue.

      -J

  7. Update: It works in Firefox but does not look as great as it does in Chrome on your site. How do I get this to work for me in Chrome? Beyond that, what are the security or other issues to resolve so that I can embed Processing.js in my website and have Chrome and Firefox users both able to see it? Is this just a local issue?

    Good night!

  8. As always an excellent tutorial!

    Just thought I'd indicate an error in the code that might throw some beginners.

    for (var i = 0; i &lt; numbers.length; i++) {

    <

    Keep up the great work!

  9. a really, really useful tutorial. thanks for posting it. if it wasn't for stuff like this, a lot of people like me would never dip their toes in this stuff at all. i think that if anyone thinks that someone saying their browser choice sucks is bullying, they've probably never really been bullied (worked for me out of the box in FF4 and chrome btw).

    thanks again.

  10. "var numbers" didn't work out for me (processing says "unexpected token"), so I used :

    float[] numbers = {13.4, 14.5, 15.0, 23.2, 30.9, 31.3, 32.9, 35.1, 34.3};

    Thanks for the tutorial.

  11. can you say about, how to increase Frame rate in android and IOS devices.

    I am a html5 game developer, i am using processing js to develope games in PC browser the game had too fast in mobile devices had too slow.

    How to increase frame rate

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>