/viz-workshop

Dartmouth CS52 17S visualization workshop!

Primary LanguageJavaScript

Let's visualize with p5.js & Raphaël!

p5.js is a JavaScript library that starts with the original goal of Processing, to make code accessible for artists, designers, educators, and beginners, and reinterprets this for today's web. p5.js has a full set of drawing functionality, which you can turn into your whole brower page as your sketch.

Raphaël uses the SVG W3C Recommendation and VML as a base for creating graphics. This means every graphical object you create is also a DOM object, so you can attach JavaScript event handlers or modify them later. Raphaël’s goal is to provide an adapter that will make drawing vector art compatible cross-browser and easy.

Now let's start the workshop!

Be sure to look out for the following notations:

  • 🚀: key step
  • ✅: checkpoint reached!

We will work on two separate tasks, one in p5.js and one in Raphaël.

Part 1: A drawable canvas in p5.js

🚀 Step 1

First let's download the p5.js complete library. Clone the repository into yours and you will see the your repository like this:

screenshot1

🚀 Step 2

Now let's link the library to your html. Include the following script into your header of the index.html:

<script language="javascript" type="text/javascript" src="libraries/p5.js"></script>

If your index.html cannot link to the p5.js file, you can alternatively link via the p5.js file that is hosted online. Just include the following script into the header of the index.html:

<script src="//cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/p5.js"></script>

We've also included an empty sketch.js file. Link that to your index.html as well:

<script language="javascript" type="text/javascript" src="sketch.js"></script>

🚀 Step 3

Now let's draw something on your page! Start your handy dandy python server by running

python -m SimpleHTTPServer 9000

on your 💻.

Check it out on your localhost. Nothing on the page yet, so let's set up the canvas first, copy these two empty functions into sketch.js:

function setup() {

}

function draw() {

}

Add the canvas by adding the following line into the setup() function:

createCanvas(640, 480);

Next, let's draw a simple circle onto your page. Add the following code in the draw() function:

ellipse(50, 50, 80, 80);

This will draw an ellipse on a spot 50 pixels right and bottom from the screen. The ellipse will have a width and height of 80 pixels.

✅ Your page should now look something like this:

screenshot3

🚀 Step 4

In your draw() function, let's draw circles with our mouse by changing our original line ot the one below:

ellipse(mouseX, mouseY, 80, 80);

Refresh your page and drag your mouse all over the page. This is how it should look like:

screenshot4

Let's make the drawing interactive with clicking. As a start, let's try making the circle black when we press our mouse. A helpful if-else statement would be

if (mouseIsPressed) {

} else {

}

The statement fill(0); makes the fill black, while fill(255); makes it white.

(Hint: add the if statements before the ellipse line.)

✅ This is how your page should look like with a series of random presses!

screenshot5

🚀 Step 5

Now let's add random colors!

We want to keep the black circles when the mouse is pressed, so lets give random colors to the fill under else.

A simple way to do this is to create red, green, and blue variables -- each set to random(255). Then we can replace fill(255) with fill(red, green, blue). You can play around with the random variables in case you want to stay within certain color ranges.

✅ Now your page should look something like this.

screenshot6

🚀 Step 6

Now let's do something cool!! This is what we will make, upgrading from the little circles we made.

screenshot7

First, we are going to change the fill so that the colors will change based on the position of the mouse cursor.

fill((mouseX / width) * 255, (mouseY / height) * 255, 0, 100);

This will make sure that the RGB is set based on the position of the mouse. The circles will look ugly now because of the black strokes(outlines). Let's change it.

Add the stroke function:

stroke(255, 255, 255, 25);

Now you'll have beautiful circles all around the page. Next, we will change the circles to rectangles. Just update ellipse() to rect().

rect(mouseX,mouseY,50,50);

If the mouse is clicked, it will turn the rectangles to black.

✅ Cool! Now you can draw all the cool stuff. Take a screenshot of your coolest drawing! Let's move on to the next part.

Part 2: Interactive graph in Raphaël

🚀 Step 1

Not really a draw person? We'll now move on to visualizing data with Raphaël. In this tutorial, we will create a diagram using Raphaël. We will draw some arcs using mathematical functions and we'll be displaying a skill percentage in a main circle when we hover over the arcs. Let's switch to the raphael_tutorial.html file.

🚀 Step 2

Let's link the library to your html. Include the following scripts into your header:

<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/raphael.js" type="text/javascript"></script>
<script src="init.js" type="text/javascript"></script>

🚀 Step 3

We've provided you with the markup in html and css so don't worry about those, but look through them to get a general idea. In init.js, we've created a new Raphaël object (variable 'r') and drew our first circle with a radius that we specified in 'rad'. Then we created a new circle in the Raphael object. We centered the circle (x: 300px and y: 300px) and we added some text to it.

✅ Now run the server again with

python -m SimpleHTTPServer 9000

This time go on http://localhost:9000/raphael_tutorial.html, you should see something like this!

screenshot8

Only the legend and one circle show right now, but don't worry!

🚀 Step 4

You'll extend the Raphael object with some custom attributes.

Some things to note:

  • alpha – angle of the arc
  • random – random number from the specified range
  • sx, sy – start drawing from this point
  • x, y – end drawing at this point
  • M – move to the starting point. No line is drawn. All path data must begin with a moveto command.
  • A – radius-x, radius-y x-axis-rotation, large-arc-flag, sweep-flag, x, y (read more: https://developer.mozilla.org/en/SVG/Tutorial/Paths)

Let's start by adding the following line to init.js:

r.customAttributes.arc = function(value, color, rad){

}

Then copy and paste the following into the function:

var v = 3.6*value,
  alpha = v == 360 ? 359.99 : v,
  random = o.random(91, 240),
  a = (random-alpha) * Math.PI/180,
  b = random * Math.PI/180,
  sx = 300 + rad * Math.cos(b),
  sy = 300 - rad * Math.sin(b),
  x = 300 + rad * Math.cos(a),
  y = 300 - rad * Math.sin(a),
  path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]];

and make sure this var v returns

{ path: path, stroke: color }

🚀 Step 5

Next, copy this empty function call (still within var o, inside the diagram: function()):

$('.get').find('.arc').each(function(i){

});

Add the variables

var t = $(this),
  color = t.find('.color').val(),
  value = t.find('.percent').val(),
  text = t.find('.text').text();

rad += 30;
var z = r.path().attr({ arc: [value, color, rad], 'stroke-width': 26 });

✅ Cool! Now we have a diagram like this, but we want to make it more exciting! Let's add some cool hover effects.

screenshot9

🚀 Step 6

Copy and paste this after our defined variables but still within the function following $('.get').

z.mouseover(function(){
  this.animate({ 'stroke-width': 50, opacity: .75 }, 1000, 'elastic');
  if(Raphael.type != 'VML') //solves IE problem
    this.toFront();
  title.stop().animate({ opacity: 0 }, speed, '>', function(){
    this.attr({ text: text + '\n' + value + '%' }).animate({ opacity: 1 }, speed, '<');
  });
}).mouseout(function(){
  this.stop().animate({ 'stroke-width': 26, opacity: 1 }, speed*4, 'elastic');
  title.stop().animate({ opacity: 0 }, speed, '>', function(){
    title.attr({ text: defaultText }).animate({ opacity: 1 }, speed, '<');
  });
});

Test out the hover and see the cool arcs expand! screenshot10

✅ Hurray! You're done!!

Go ahead and have fun making pretty stuff :D 🎨

Submit screenshots of your final pages (both p5.js & Raphaël), especially fun drawings!

Sources