This is an older version of Design Intellection. Access the new one: http://designintellection.com/.

Design Intellection is a small web design company committed to making the web a better place.

Contact

August 28, 2009

Creating Bar Charts with Processing.js

How to create simple and flexible bar charts that can be implemented anywhere.

The second part of this tutorial series will move from creating a single bar graphic to creating a full, multi-colored, aesthetically-pleasing bar graph. Also, since this is the first in the series that references the Processing.js syntax, a few extra pains will be taken to detail the basics of the syntax and structure.

A SPECIAL NOTE TO RSS READERS:

Due to the complex nature of this tutorial (mainly the examples) you have to go to the post to see the rest.

Also, it should be noted that a small bit of CSS was used to style the <canvas> element used in all the examples to give it a gray border and some margin.

Note: As mentioned in the introduction of this series (though included as an addendum), IE support is currently not included with these tutorials.

A Little Setup

Before starting with examples, let's take a moment to look at the initial setup. In Figure 2.1 a basic Processing.js "shell" has been setup with no rendering code.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. }
  18. // Draw elements
  19. void draw()
  20. {
  21. }
  22. </script>
  23. <canvas width="372" height="180"></canvas>
  24. </div> <!-- example -->
  25. </body>
  26. </html>
Figure 2.1

The Processing.js "shell."

Download Source processing-f2.1.txt

First, notice the <script> tag on line 18 with the application/processing attribute instead of the normal text/javascript. All Processing.js code will be contained within here.

There are two main functions that will be used in each example – the setup() and draw() function. Both of these functions are fairly self-descriptive: setup() contains the properties that prepare the drawing canvas, and draw() contains the display commands to draw the bar graph.

An important feature of the draw() function is that it loops continuously unless the exit() command is present. Therefore, it has the capability to animate elements, as well as capture mouse and keyboard actions to initiate events.

However, if you do not plan to utilize either of these, the exit() command should be used to keep Processing.js from unnecessarily using your computer's resources.

Now that we know the basic setup, let's start building things.

A Simple Bar

The first example will be quite basic – a single bar. The main function that will be used is the rect() function. The code to accomplish this and resulting display is shown in Figure 2.2.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. // Size of the drawing board
  18. size(372,180);
  19. // Set background to white
  20. background(255);
  21. }
  22. // Draw elements
  23. void draw()
  24. {
  25. // Remove the border (on by default)
  26. noStroke();
  27. // Create the bar
  28. fill(#99cc33); // Set the fill color
  29. rect(12,48,36,132); // Build the rectangle
  30. // Exits out of the draw() loop
  31. exit();
  32. }
  33. </script>
  34. <canvas width="372" height="180"></canvas>
  35. </div> <!-- example -->
  36. </body>
  37. </html>
Figure 2.2

Creating a single bar.

Download Source processing-f2.2.txt

In this first example (Figure 2.2), several Processing.js properties were utilized:

size(W, H)
Sets the size of the drawing canvas assigning a width and a height value. Usually this will match the <canvas> element's width and height.
background(C)
Sets the background color of the <canvas> element. Color values can be passed via RGB values or as HTML hex codes. You can use shorthand for the RGB values as well, so for example the color white could be input as 255 instead of 255,255,255.
noStroke()
By default, each element drawn in Processing.js has a border (line stroke); this command removes it.
fill(C)
This sets the fill color for an element. It takes the same color arguments as background().
rect(X, Y, W, H)
The main function for this example, rect() is what draws the rectangle for our
bar graph. It takes two sets of arguments to build the rectangle: coordinates and dimensions. You first give it an X and a Y coordinate (the default 0,0 position is the upper left of the <canvas> element) and then set a width and a height.

The Processing.js website has a full list of supported (and unsupported) functions. I recommend referencing it often.

How It Was Built

Now that you are a little more familiar with the syntax, let's summarize how the bar drawn in Figure 2.2 was accomplished.

The first function called is the setup() function. In this function we set the size of the drawing canvas and its background color by using the size() and background() functions, respectively.

Then we call the draw() function to create our graphics. First we remove the border on all elements with noStroke(), set the fill color on all elements that are to be drawn with the fill() function and finally draw the rectangle with the rect() function.

The Loop Cascade

You may have picked up on this already, but just to be sure, let's spend a minute discussing how graphics are rendered. The draw() loop has a cascade principle inherit in the various functions called within it.

For example, when we set the fill() command in Figure 2.2 on line 37, every element rendered past this point will have that specific fill color; unless another fill() command is given at some point. To illustrate this further, compare the two cases below:

Case A

  1. void draw()
  2. {
  3. fill(255,0,0); // Red
  4. rect(12,50,36,132); // RECT A
  5. rect(48,50,36,132); // RECT B
  6. }

Case B

  1. void draw()
  2. {
  3. fill(255,0,0); // Red
  4. rect(12,50,36,132); // RECT A
  5.  
  6. fill(0,255,0); // Green
  7. rect(48,50,36,132); // RECT B
  8. }

In Case A both rectangles are rendered red. In Case B the first rectangle drawn is rendered red, and the second green. This principle applies to other commands as well, such as noStroke(), etc.

Adding Aesthetics

The green bar drawn in Figure 2.2 is rather plain, it seems incomplete. In Figure 2.3 another bar is added to the graphic to create a darker border around the top and right edge of the bar. I'm calling it the shadow bar.

This leads to another principle in the way Processing.js defines graphics – layers. As it loops through the draw() function the element that is drawn first is on the bottom "layer," the next is on top of the first, the next on top of both of those and so on. Though of course an element being drawn on top of another is contingent on where you place it.

So to build the shadow a single bar is drawn with the same dimensions as in Figure 2.2, except with a darker color. Then another bar is drawn on top of the first, but two pixels shorter and thinner so that the bar behind it gives it a two-pixel border on the top and right side. (This technique came from the way Mint used to display bar graphs.)

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. // Size of the drawing board
  18. size(372,180);
  19. // Set background to white
  20. background(255);
  21. }
  22. // Draw elements
  23. void draw()
  24. {
  25. // Remove the border (on by default)
  26. noStroke();
  27. // Create the bar
  28. fill(#79b327); // Shadow fill
  29. rect(12,48,36,132); // Builds rectangle for shadow
  30. fill(#99cc33); // Display bar fill
  31. rect(12,50,34,130); // Builds rectangle on top, but smaller
  32. // Exits out of the draw() loop
  33. exit();
  34. }
  35. </script>
  36. <canvas width="372" height="180"></canvas>
  37. </div> <!-- example -->
  38. </body>
  39. </html>
Figure 2.3

Creating a single bar with a shadowed edge.

Download Source processing-f2.3.txt

Now we have a more presentable bar graph. Of course, a single-bar graph isn't a very useful illustration, which leads us to the next step.

Building Multiple-Bar Graphs

To add multiple bars in this graphic all that's necessary is to use the rect() function to build each one with the appropriate coordinates and dimensions. This is accomplished in Figure 2.4 below.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. // Size of the drawing board
  18. size(372,180);
  19. // Set background to white
  20. background(255);
  21. }
  22. // Draw elements
  23. void draw()
  24. {
  25. // Remove the border (on by default)
  26. noStroke();
  27. // Create the shadow bars for each rectangle
  28. fill(#79b327); // Shadow fill
  29. rect(12,48,36,132); // Shadow bar 1
  30. rect(60,48,36,132); // Shadow bar 2
  31. rect(108,80,36,100); // Shadow bar 3
  32. rect(156,48,36,132); // Shadow bar 4
  33. rect(204,20,36,160); // Shadow bar 5
  34. rect(252,48,36,132); // Shadow bar 6
  35. rect(300,48,36,132); // Shadow bar 7
  36. // Create the display bar on top for each rectangle
  37. fill(#99cc33); // Display bar fill
  38. rect(12,50,34,130); // Display bar 1
  39. rect(60,50,34,130); // Display bar 2
  40. rect(108,82,34,98); // Display bar 3
  41. rect(156,50,34,130); // Display bar 4
  42. rect(204,22,34,158); // Display bar 5
  43. rect(252,50,34,130); // Display bar 6
  44. rect(300,50,34,130); // Display bar 7
  45. // Exits out of the draw() loop
  46. exit();
  47. }
  48. </script>
  49. <canvas width="372" height="180"></canvas>
  50. </div> <!-- example -->
  51. </body>
  52. </html>
Figure 2.4

Creating a multiple-bar graph manually.

Download Source processing-f2.4.txt

In Figure 2.4, we took the method used to build one bar and applied it six more times, adjusting the rect() parameters for each one. However, the lack of scalability when doing it this way is painfully obvious. What if you have a graph that needs to display 100 bars, or a 1,000? We need a better method.

Luckily, Processing.js is able to handle this with ease. All that's necessary is to create an array for each variable and then use a for() loop to draw our graph. The same bar graph in Figure 2.4 is drawn using this new technique in Figure 2.5.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. // Size of the drawing board
  18. size(372,180);
  19. // Set background to white
  20. background(255);
  21. }
  22. // Draw elements
  23. void draw()
  24. {
  25. // Remove the border (on by default)
  26. noStroke();
  27. int bar_width = 36; // Set bar width
  28. // Set array of bar heights
  29. int[] bar_height = {132, 132, 100, 132, 160, 132, 132};
  30. for (int i=0; i<bar_height.length; i++) // Loop through the array
  31. {
  32. // Build the shadow first
  33. fill(#79b327);
  34. rect(12+i*48, height-bar_height[i], bar_width, bar_height[i]);
  35. // Then build the display bar
  36. fill(#99cc33);
  37. rect(12+i*48, height-bar_height[i]+2, bar_width-2, bar_height[i]-2);
  38. }
  39. // Exits out of the draw() loop
  40. exit();
  41. }
  42. </script>
  43. <canvas width="372" height="180"></canvas>
  44. </div> <!-- example -->
  45. </body>
  46. </html>
Figure 2.5

Creating a bar graph using a for() loop.

Download Source processing-f2.5.txt

The for() loop makes it much more manageable and scaleable. Of course you will still have to input the values of the array, but as you'll see later in the series with the tutorial on integration with PHP these types of tasks can be automated as well.

I'm not going to detail the specifics on the for() loop, but the Processing.js website offers a helpful summary on how it works.

Lastly, in Figure 2.6, we'll take the graph from Figure 2.5 and change the code to give each bar a unique color.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Processing.js Examples</title>
  5. <script type="text/javascript" href="/path/to/processing.js"></script>
  6. <!--[if IE]>
  7. <script type="text/javascript" href="/path/to/excanvas.compiled.js">
  8. <![endif]-->
  9. <script type="text/javascript" src="/path/to/init.js"></script>
  10. </head>
  11. <body>
  12. <div class="example">
  13. <script type="application/processing">
  14. // Setup canvas
  15. void setup()
  16. {
  17. // Size of the drawing board
  18. size(372,180);
  19. // Set background to white
  20. background(255);
  21. }
  22. // Draw elements
  23. void draw()
  24. {
  25. // Remove the border (on by default)
  26. noStroke();
  27. int bar_width = 36; // Set bar width
  28. // Set array of bar heights
  29. int[] bar_height = {132, 132, 100, 132, 160, 132, 132};
  30. // Set array for individual shadow bar colors
  31. color[] shadow_colors = {#bb8822, #b461c0, #7b7050, #d5ce1a, #2dbad4, #b94d12, #79b327};
  32. // Set array for individual display bar colors
  33. color[] bar_colors = {#cc9933, #c572d1, #8c8061, #e6df2b, #3ecbe5, #ca5e23, #99cc33};
  34. for (int i=0; i<bar_height.length; i++) // Loop through the array
  35. {
  36. // Build the shadow first
  37. fill(shadow_colors[i]);
  38. rect(12+i*48, height-bar_height[i], bar_width, bar_height[i]);
  39. // Then build the display bar
  40. fill(bar_colors[i]);
  41. rect(12+i*48, height-bar_height[i]+2, bar_width-2, bar_height[i]-2);
  42. }
  43. // Exits out of the draw() loop
  44. exit();
  45. }
  46. </script>
  47. <canvas width="372" height="180"></canvas>
  48. </div> <!-- example -->
  49. </body>
  50. </html>
Figure 2.6

Assigning each bar a unique color using the color[] array.

Download Source processing-f2.6.txt

The same principle of cycling through an array with a for() loop is applied to give each bar a unique color.

A couple things to note:

  • Notice how the arrays are declared and that there are specific arrays depending on the value: color – color[], integers – int[] and so on.
  • Note again how we build the shadow for each one first and then the display bar on top of that.

Better than CSS?

Creating bar charts with Processing.js is a simple task. However, the same can be accomplished using CSS, and arguably better since CSS is more accessible than Processing.js (see Accessible Data Visualization with Web Standards). Ultimately you will have to make the call on which method is more suited to your situation.

The next installment of this series – Creating Pie Charts with Processing.js – will move into less ambiguous areas and will highlight the greater benefits of Processing.js's capabilities.

Processing.js A series of concise tutorials.
Part I – Introduction
An introduction to Processing.js
Part II – Bar Charts
Learn the basics while creating aesthetically pleasing bar charts.
Part III – Pie Charts
Easily create pie charts.
Part IV – Integrate jQuery
Learn how to quickly implement Processing.js with native JavaScript.
Part V – Integrate PHP
Create dynamic info-graphics by combining PHP with Processing.js
Part VI – Conclusion
A summary of the series with links to
more resources.
Appendix
An example page with all of the working examples and the appropriate source code.

Send a Message Have something to say? Use the form below to email your comment directly to me.
If warranted, I’ll do my best to respond in a timely matter.

Legend * = Required

(Hint: It’s David)

Content © David Yeiser, 2007–2009 | Published with Habari.