| 00:00 |
Our assignment for this end project is to
create an interactive visualization of
|
| 00:05 |
Google Trends data about searches for
various opera composers.
|
| 00:11 |
Now, my solution for this begins with
picking the colors.
|
| 00:15 |
I went to Adobe's Kuler, that's kuler.
I went to kuler.adobe.com.
|
| 00:21 |
And I found a palette that I thought
worked well for the visualization.
|
| 00:24 |
And coped the hex codes down into this.
Above that, I have a comment that doesn't
|
| 00:28 |
say what the colors are, but it says what
their purposes or their roles are so I
|
| 00:30 |
know which one to use.
The next thing, is I have two fonts that
|
| 00:34 |
I'm going to be using.
I'm going to be using a large, thick font
|
| 00:38 |
for the title, and a smaller thinner font
for the labels on the grid.
|
| 00:44 |
In processing, you actually need to go
through a process to create each one of
|
| 00:47 |
these fonts, and that's what I'm going to
do right now.
|
| 00:49 |
We go up to Tools to create font.
And the first one we're going to get, I'm
|
| 00:57 |
going to move this off to the side, is
Arial Black 32 pt.
|
| 01:01 |
Now, by the way, Macintoshes, Linux
computers, and Windows PCs don't
|
| 01:04 |
necessarily have the same font lists.
I intentionally chose two very widely
|
| 01:10 |
available fonts.
I know that Macs have these and Windows
|
| 01:13 |
have these.
And so, you can change them if you need
|
| 01:16 |
to, you're just going to have to change
the reference in the code later.
|
| 01:20 |
So, I'm going to go to Arial Black, and
then I'm going to chose 32 point.
|
| 01:28 |
And press OK.
Then I'm going to save the second font,
|
| 01:32 |
which is Arial Narrow 14 point.
Go to Tools, Create Font, come to Arial
|
| 01:41 |
Narrow 14 point.
By the way, what I'm doing is I'm also
|
| 01:47 |
going to be saving these as what's called
P-font.
|
| 01:50 |
That's actually a class here, and I'm
creating an object with the font in it.
|
| 01:54 |
And so these are basically a very complex
variable.
|
| 01:58 |
But I have to create these, so I declare
it as pfont, and then the name that I'm
|
| 02:01 |
giving it is Title Font.
And then Y- font for the y-axis on the
|
| 02:05 |
bar chart grid.
Let's take a quick look at where those are.
|
| 02:08 |
I'm going to go to the File browser.
And you see my end_solution.pde file.
|
| 02:15 |
That's the Processing file.
And the Files folder that came with this
|
| 02:20 |
but when I created the fonts I got an
automatic Data folder.
|
| 02:24 |
Am going to go up to that, and there you
see I have the two fonts that I just created.
|
| 02:31 |
That's great and so I'm going to go back
to the main, here we go and go back to
|
| 02:35 |
processing now.
I also have an object here for composers
|
| 02:41 |
that's in the class of table.
So, I say table and, don't forget
|
| 02:45 |
capitalization is, is specific and you
need to get it the right way.
|
| 02:49 |
And I call the composers that's going to
be creating the data that I worked with.
|
| 02:55 |
Now let's just go back and get that thing
ready cause you remember it needs to be a
|
| 02:58 |
TSV file.
So, I'm going to go to my file browser,
|
| 03:02 |
and I'm going to go into files.
I'm going to open up this CSV file.
|
| 03:12 |
Make that a little bit bigger.
I need to do two things here, number 1 is
|
| 03:16 |
I need to delete the top row headers.
Now when processing 2.0 the full version
|
| 03:23 |
comes out.
It will have a built in table class, and
|
| 03:25 |
among other things, you won't need to
delete the headers, you can simply say
|
| 03:29 |
that you have them.
But for right now this is the simplest
|
| 03:32 |
way to make it work, so I'm going to come
through there and I'm going to delete that.
|
| 03:37 |
And go to File and Save As.
I'm going to Save As the type is "Text
|
| 03:43 |
Tab Delimited", and I press Save.
It's going to tell me I'm losing some
|
| 03:49 |
information, that's just about
formatting, that's the only information
|
| 03:54 |
I'm losing.
Then we close the file because I'm going
|
| 03:59 |
to modify its name manually, that's okay,
I want to save it, and it's alright to
|
| 04:02 |
lose some of those features.
Now I'm going to go back to the File browser.
|
| 04:08 |
And now you can see I have a new file
here called Composers.txt, and if you
|
| 04:12 |
look over to the right under Type, it
says it's a text document.
|
| 04:16 |
Now again, I've changed my system options
so I can always see the extensions on files.
|
| 04:22 |
This is important here 'cuz otherwise,
you'll think you changed it, but you
|
| 04:25 |
won't have.
And you'll get horrible errors when you
|
| 04:27 |
try to run your processing sketch.
What I'm going to do is I'm going to
|
| 04:32 |
click on composers.txt twice slowly so I
can modify the file name.
|
| 04:37 |
And I'm just going to go change the txt
to tsv.
|
| 04:42 |
When I hit enter, it's going to ask me if
I want to really do it, I do.
|
| 04:45 |
And you see that the file type, in the
third column here, changed from text file
|
| 04:49 |
to tsv file.
That's exactly what I need.
|
| 04:53 |
Now, I'm going to add this file to my
sketch.
|
| 04:56 |
Let me show the easy way to do that.
I'm going to take this window and just
|
| 05:00 |
get it off to one half of the screen.
Then I'm going to bring up my processing
|
| 05:04 |
window, and put that on one half of the
screen.
|
| 05:08 |
I come back in here, and I grab my data
file, the TSV format.
|
| 05:12 |
And I just drag it on top of the
processing window.
|
| 05:15 |
And you see I have a message at the
bottom that says one file added to sketch.
|
| 05:20 |
In fact, in the file browser.
If I come right here I go into data
|
| 05:24 |
that's where the fonts are.
You see I now have the TSV file on there
|
| 05:28 |
that's where it needs to be.
Okay going back to the processing sketch
|
| 05:33 |
let me make this bigger right now.
Now, I'm going to create a series of
|
| 05:38 |
variables that I use and create in the
drawing.
|
| 05:41 |
I'm creating these as global variables so
I can declare and initialize them up here.
|
| 05:45 |
And I can call on them in several
different blocks or code or possibly
|
| 05:49 |
modify then dynamically.
The first one is LM, that's the left
|
| 05:53 |
margin of the grid.
That's how far the grid needs to be from
|
| 05:56 |
the left edge of window and I've made it
100 pixels.
|
| 05:59 |
After that is BM for bottom margin, also
100 pixels.
|
| 06:04 |
The next one and by the way, these are
all integer variables or so, int.
|
| 06:08 |
The third one is GW, for grid width and
the grid I'm going to make the bars on is
|
| 06:12 |
going to be 800 pixels wide.
GH is for grid height, that's 300 pixels.
|
| 06:19 |
Then, I have a couple of variables that
set ranges for things.
|
| 06:23 |
I have min X is zero, that's a minimum of
value of x for the slider, and the max X
|
| 06:28 |
is 418.
I got that number because that's how many
|
| 06:33 |
rows there are in the TSV data file once
I remove the header.
|
| 06:37 |
Then I have two variables that specify
the lower and upper limits of the grid
|
| 06:40 |
that I'm going to draw the bars on.
Min Y is zero, max Y is 100, because it's
|
| 06:44 |
a zero to 100 range in the Google data.
And then I have another one, BW for bar
|
| 06:50 |
width, that's how thick I want each bar
to be.
|
| 06:53 |
Scroll down a little bit.
Then I have a variable called Row that
|
| 07:00 |
acutally use as a way of reading through
the data file, and I initalize it as 0.
|
| 07:07 |
I have Row Count that I went through the
file, I know there's 418 rows, so I put
|
| 07:11 |
that in there.
Then I'm going to be creating a slider,
|
| 07:15 |
and I need a variable that indicates the
exposition of the slider.
|
| 07:19 |
And there needs to be global one, so I
can modify it.
|
| 07:22 |
Up here, I'm using a float variable, so I
can take fractional values and I'm
|
| 07:26 |
calling it slider X and I'm initializing
it at zero.
|
| 07:31 |
Then I have another integer variable that
simply indicates how many bars I'm going
|
| 07:34 |
to draw.
So, the N, the sample size is five.
|
| 07:38 |
After that I have three arrays, the first
one is a String array that I'm calling Names.
|
| 07:43 |
And in that array I'm putting the five
names of the composers the way that I
|
| 07:46 |
want them to appear as labels on the
chart, so they are capitalized in this case.
|
| 07:52 |
The second one is a P image or a
processing image array and I'm going to
|
| 07:55 |
call it Portraits.
And at this moment, I'm not putting
|
| 07:59 |
things in it, I'm creating an empty array
that I'm going to fill in a little bit later.
|
| 08:03 |
And so, when you create an empty array,
you put new and then you put the type
|
| 08:06 |
again, p image.
And then in square brackets, how many
|
| 08:10 |
spaces you need.
And I'm going to have five.
|
| 08:12 |
I use that variable n5 just a moment ago.
Then I'm going to create a String array
|
| 08:17 |
called Image Names.
And these are the actual names of the
|
| 08:20 |
image files that I'm going to be adding.
Puccini.jpeg and Verdi.jpeg and so on in
|
| 08:25 |
fact I am going to add those files right
now.
|
| 08:29 |
Let me make this window after the left
now and I am going to come back here to
|
| 08:35 |
my File browser to Files and here I have
images.
|
| 08:47 |
I've got my five images here, and I just
drag them on top.
|
| 08:51 |
And now you see it says five files added
to the sketch.
|
| 08:55 |
Once I've dragged my images onto the
window, and I get the message that says
|
| 08:59 |
five files are added to the sketch.
You can confirm that in the File browser
|
| 09:04 |
by going back to the Data folder.
And you see that in addition to the two
|
| 09:08 |
fonts in the data sheet for Composer CSV,
I now have the five JPEG files.
|
| 09:15 |
There's one more important thing.
I also need to add the Table class, the
|
| 09:19 |
actual code that runs it.
Now, I've already done this here.
|
| 09:23 |
But as a reminder, the way that works is
I go to Files and I take this Table.
|
| 09:29 |
And like the others, I just drag it on
top of the Processing window.
|
| 09:32 |
I've already done that, so I'm not
going to do it again.
|
| 09:35 |
But when I do that, you see that I have
this tab right here, Table and it also
|
| 09:39 |
shows up right here.
Now that I've got those files added, I
|
| 09:44 |
can get into the actual code for the
sketch itself.
|
| 09:47 |
Let me maximize this again.
Now, I've created some really big
|
| 09:54 |
comments that separate my blog.
So, I could find them easier when I'm
|
| 09:58 |
scrolling through that's why I have the
two slashes.
|
| 10:01 |
Then set up then a whole lot of slashes
because I can see those as I'm scrolling
|
| 10:03 |
up and down the code.
I've done those for each of the blocks
|
| 10:06 |
that I have.
The first block is setup, void setup,
|
| 10:09 |
again void because it doesn't return a
data type and then within the curly
|
| 10:13 |
bracket I put in my arguments.
The 1st one is this size of the window.
|
| 10:18 |
I make a 1000 pixels wide, 600 pixels
tall.
|
| 10:22 |
Then I turn on anti-aliasing with smooth.
Then I'm going to load my two fonts.
|
| 10:28 |
The title font I use the function load
font, and then I put in the specific name
|
| 10:34 |
of the font: Arial-black-32.vlw.
Then I give a similar thing for Y font.
|
| 10:41 |
It's easiest by the way to simply copy
the names of those fonts from your Data
|
| 10:44 |
folder and paste them in here.
And please note they need to be in
|
| 10:48 |
quotation marks in the parenthesis.
Next I am going to read the Data file to
|
| 10:52 |
make it available.
I now have Composers, that's the name of
|
| 10:56 |
the object of the Table object that I am
creating.
|
| 11:00 |
So, Composers equals new and then Table
with a capital T.
|
| 11:04 |
And then in parenthesis and quotations.
The name of the TSV file exactly as it
|
| 11:09 |
appears Composers.tsv.
Finally in set up, I'm going to load the
|
| 11:13 |
images into the array.
You want to make sure you do this here
|
| 11:16 |
because if you were to load images in the
draw loop iIt try to be doing the 60
|
| 11:19 |
frames per second.
You'd quickly run out of memory.
|
| 11:22 |
So, here I have a very short loop that
loads the images into the array.
|
| 11:27 |
'Cuz remember there's five images and I
created an empty array with five spots.
|
| 11:32 |
So, I create a for loop for and I equals
zero I less than n, n is five.
|
| 11:38 |
And then I increment one at a time.
And then it goes through starting at 0,
|
| 11:42 |
1, 2, 3, 4, and then because arrays begin
with the index number zero, this works.
|
| 11:47 |
I have the portraits array.
And it's going to load the image and it's
|
| 11:51 |
going to go to the array of image names
and pull down the appropriate image.
|
| 11:56 |
You can actually see it there at the top
of the screen.
|
| 11:59 |
So, the first one is going to be,
Puccini.jpeg, the second will be Verdi.jpeg.
|
| 12:03 |
It's actually index numbers here, one,
two, three and four.
|
| 12:06 |
And that finished my set up block.
Next, I'm going to scroll down to draw.
|
| 12:12 |
Now, I've created a relatively
complicated drawing.
|
| 12:16 |
But I want to make the code a little
simpler to follow, an so what I've done
|
| 12:20 |
here, is within Draw, I only use one
standard function, an that is the Background.
|
| 12:26 |
I use the Background function an I am
actually referring to a color from the palette.
|
| 12:31 |
I have an array earlier called Palette,
an I'm taking the first item in it which
|
| 12:34 |
is index number zero, an that's going to
be the background that refreshes every time.
|
| 12:39 |
When you have a dynamic drawing and you
want to make sure you do that, so you
|
| 12:42 |
don't have trails left all over the
drawing.
|
| 12:45 |
Then what I did is I created four custom
functions for this drawing.
|
| 12:48 |
The reason I did that is because it makes
it easier to separate the code into
|
| 12:51 |
blocks and its easier to follow each one
of them.
|
| 12:54 |
The first one is simply to create the
title, main title and then it has one
|
| 12:58 |
argument and that's the text for the
title.
|
| 13:02 |
The second function is called Grid Lines
and that I have to specify a number of arguments.
|
| 13:08 |
I have to specify the left margin the
bottom margin, the grid width, the grid
|
| 13:11 |
height, the minimum value of y, the
maximum value of y.
|
| 13:16 |
And then I also have to specify how many
divisions there are in it.
|
| 13:20 |
And I want to break it into four pieces.
So, it goes, actually, 0 to 25 or 10 to
|
| 13:25 |
50, 75 to 100%.
And because I declared these variables
|
| 13:29 |
early at the top, I gave them all values,
I can just use the variables names here,
|
| 13:33 |
it makes it easier.
The third custom function is called Slider.
|
| 13:38 |
And now that one, I actually need to have
a title for this slider that I called
|
| 13:42 |
Weak I need to specify the left margin.
I need to specify how far it is from the
|
| 13:47 |
bottom and I just entered that manually
with 50.
|
| 13:50 |
And then I need to give the grid width,
and then I need to give the minimum and
|
| 13:54 |
maximum values for x, that goes from 0 to
418.
|
| 13:58 |
Then I give the labels for the two ends
of the sliders as text here.
|
| 14:03 |
The last function actually goes through a
for loop and what that is is this is the
|
| 14:06 |
one that actually draws the bars.
It's a function I created called Bar,
|
| 14:11 |
and, because I have five bars, this lets
me write it just once, and it works for
|
| 14:14 |
all five of them.
So, I've created a function called Bar,
|
| 14:20 |
and what it does is I have to specify the
left margin, the width of the grid that's
|
| 14:24 |
GW, the bottom margin, the bar width
that's BW.
|
| 14:29 |
I is the current number that it's working
on.
|
| 14:33 |
So, it's going to be zero, one, two,
three, four.
|
| 14:35 |
Then I have another that says names,
length.
|
| 14:38 |
And that's just an indicator of how many
bars there are going to be total in this
|
| 14:41 |
case it's going to be five.
Then I have names I which goes back and
|
| 14:46 |
says what the persons last name is, Verdi
and Puccini etc.
|
| 14:50 |
And then I have in this complicated one
that comes back from the Table class and
|
| 14:54 |
it says Composers that's the name of the
Table object.
|
| 14:59 |
And then dot get end so I'm pointing out
integer variables.
|
| 15:03 |
And Row it is going to go through one row
at a time and I initialized a variable
|
| 15:07 |
row earlier but you'll see that this
slide of this one had actually controls
|
| 15:11 |
the row.
And then I do this one I plus one and the
|
| 15:15 |
reason for that is the person their index
number puccini is zero.
|
| 15:20 |
But they're the second column in the data
sheet, so I just need to move things over
|
| 15:24 |
by adding one.
Okay, so that is the Draw loop that's all
|
| 15:28 |
that's in there, because I've taken the
action and put it into separate functions
|
| 15:31 |
beneath that.
And we'll go through each of those next.
|
| 15:35 |
The first function's an easy one, It's
the main title.
|
| 15:41 |
And what I do is I specify void because
it's asking about the return type of the data.
|
| 15:46 |
It doesn't return any data it returns a
title.
|
| 15:49 |
And that's a main title, and then I have
to specify the arguments that are going
|
| 15:51 |
to come into the function.
This takes only one argument and that is
|
| 15:55 |
the actual text of the title so it's a
string variable.
|
| 15:59 |
And that's one that I specified up
earlier.
|
| 16:00 |
Then, I say that I'm going to center it
on the left and right and I'm going to
|
| 16:04 |
center it top to bottom when I position
it.
|
| 16:08 |
Then I say the font that I'm going to
use.
|
| 16:10 |
Text font is the function, and then I'm
going to refer to the title font that I created.
|
| 16:15 |
Then the fill is what colors the font.
I'm going to use the palette index number
|
| 16:19 |
three, which is actually the fourth item
in the array.
|
| 16:24 |
And then I place the text with the text
function, so it titled text, and then I
|
| 16:27 |
put it in the middle with width divided
by 2, and I put it 20 pixels down from
|
| 16:30 |
the top.
The next function is Grid Lines.
|
| 16:35 |
This is the one that actually draws a
grid for the bar chart.
|
| 16:39 |
This one takes several arguments.
It's void because it doesn't return a
|
| 16:42 |
data type, it's called Grid Lines.
It's going to take the left margin which
|
| 16:45 |
I've said could be a float variable, a
floating point.
|
| 16:49 |
The bottom margin.
How wide is the grid?
|
| 16:52 |
How high is the grid or how tall is it?
What are the minimum and maximum values
|
| 16:56 |
for y?
And how many divisions do I need for
|
| 16:59 |
drawing the in between lines?
Now one thing I'm going to be doing.
|
| 17:03 |
Is I'm going to be doing translation here
moving the origin to make it a little
|
| 17:07 |
easier to deal with.
But before I do that, I don't want to
|
| 17:10 |
mess up anything else that's using the
original system where 00 is the top left
|
| 17:14 |
of the grid.
so, I push the matrix that take the
|
| 17:18 |
existing matrix transformation or to the
standard one at the moment.
|
| 17:22 |
Save it off to the side and then I can
translate.
|
| 17:26 |
So, by translating, what I'm doing is I'm
actually moving the 00 origin to the
|
| 17:30 |
bottom left of the grid.
And LM is the left margine, so I move it
|
| 17:34 |
over to distance of the left margin, it's
100 pixels in this case.
|
| 17:38 |
And then I drop it down to the bottom by
going to the height number.
|
| 17:42 |
That means starting at the top of the
window and going all the way to the bottom.
|
| 17:45 |
An then subtracting the size of the
bottom margin.
|
| 17:48 |
Then I say what color I'm going to use.
The stroke is, cause I'm drawing in lines
|
| 17:53 |
here, is going to be palette index one.
So, palettes an array of colors that I
|
| 17:57 |
defined up above, I'm going to be using
index number one as the second item in it.
|
| 18:02 |
An then, I'm actually going to also
specify stroke cap.
|
| 18:05 |
I want these lines to end very sharp with
squares.
|
| 18:08 |
Now if I were to draw them really thick
that be obvious, but even now.
|
| 18:11 |
So, I'm specifying stroke cap square then
I have a little bit of code that's grayed out.
|
| 18:17 |
I had originally written a code to create
a vertical line on the left side for the
|
| 18:21 |
y axis.
I decided that it wasn't absolutely
|
| 18:25 |
necessary and so I commented out those
two lines of code.
|
| 18:29 |
But if you wanted them you could just
uncomment them like this.
|
| 18:32 |
We just select them and uncomment them.
It'll draw the line now, and I'm going to
|
| 18:37 |
comment them back out, then I have
reference lines that go across the grid.
|
| 18:42 |
Those are going to be very narrow stroke
weight of one pixel.
|
| 18:45 |
And then because I have several of them,
I'm going to use a for loop.
|
| 18:49 |
Now because I'm doing division in here, I
acutally need to use I as floating point
|
| 18:52 |
variable, even though it's normally an
int.
|
| 18:56 |
So, I do float I equals zero.
So, I start at zero.
|
| 19:00 |
And then I is less than or equals to the
divisions of y.
|
| 19:04 |
And that's a variable I created they said
four.
|
| 19:06 |
I want to split that into four pieces.
Please not that I said equals to because
|
| 19:10 |
I want to be able to go all the way to
the end and then I increment one step at
|
| 19:13 |
a time.
Now, one of the reasons it's really
|
| 19:17 |
important to use a float here is because
I and the div y are integer variables.
|
| 19:22 |
And if I try to divide integers by each
other, it's not possible to get a
|
| 19:25 |
floating point variable.
It will either give zero or a whole
|
| 19:29 |
number, and can be excruciatingly
frustrating.
|
| 19:32 |
But by setting I as a float variable,
this works naturally.
|
| 19:36 |
So, I'm going to create a variable called
Y, it's called Float, and this is
|
| 19:39 |
going to be for the vertical position of
the reference lines.
|
| 19:42 |
Y is equal to I divided by div Y.
So, when I is 0, that division is 0 over
|
| 19:50 |
4 is going to be 0 It's going to go to
the top of the grid.
|
| 19:55 |
And that's what happens when I multiply
times minus i.
|
| 19:59 |
So, the first one, line zero, is going to
go to the top.
|
| 20:02 |
And then I actually draw the line itself,
that one was just to get the Y value.
|
| 20:05 |
And then I do zero, so it starts at the
left margin in which, because I translate
|
| 20:09 |
it as the edge of the grid.
And Y that goes all the way across.
|
| 20:15 |
Next, I have some axis numbers.
What I've done here, is I'm using the Y
|
| 20:20 |
font that I've created up above.
So, text font is Y font, I'm going to
|
| 20:23 |
give it a fill, and then I specify how I
wanted the line.
|
| 20:27 |
I want these ones flush right, and I want
them so the bottom of the text is next to
|
| 20:31 |
where the line would be.
And then I run through a for loop again
|
| 20:36 |
using I as a floating point, because I
want these to line up with the lines that
|
| 20:39 |
I had above.
So, I simply copied the one I have here,
|
| 20:43 |
but I'm using it to then place text.
Now, when I do the division of I divided
|
| 20:48 |
by zero times the negative of i, I end up
with numbers with decimal places, so it'd
|
| 20:53 |
be like 25.000.
I don't want the zeros on there and so I
|
| 20:57 |
use a special function here called NFS
and I've got a comment here that explains it.
|
| 21:03 |
What it does is it takes a value and it
converts it from a floating point number
|
| 21:07 |
to a string.
And by setting it with zeros the first
|
| 21:11 |
zero says how many numbers do I want to
add to the left.
|
| 21:15 |
So, if I want it to read as 0025 I could
add that on.
|
| 21:19 |
I don't want to add any so I put it at
zero.
|
| 21:21 |
The second zero is how many decimal
places I want.
|
| 21:24 |
I don't want any and so by doing that it
will cut off all of the decimals and just
|
| 21:28 |
print it as a natural looking percentage
number.
|
| 21:34 |
And then I place it, negative 10 means to
move it slightly to the left of the grid.
|
| 21:38 |
And the Y is following the lines that I
drew across.
|
| 21:42 |
Finally, I finish this with Pop matrix,
because this was all done on a translated
|
| 21:46 |
grid, where I moved it over.
The origin, the zero zero origin to the
|
| 21:51 |
bottom left of the grid.
This restores it back to where it was
|
| 21:54 |
before for all of the other functions.
Now we have a slightly more complicated one.
|
| 22:00 |
Oh, by the way, I uncommented and then
recommented some text.
|
| 22:03 |
So I just need to save it.
I haven't changed anything really.
|
| 22:07 |
The slider that goes across the bottom
takes a lot of information here.
|
| 22:11 |
First, the function takes several
arguments.
|
| 22:13 |
I need to give it a title, the left
margin, the bottom margin, how wide it
|
| 22:17 |
its, it's minimum and maximum values on
x.
|
| 22:22 |
I need to give it a label for the bottom
end and a label for the top end.
|
| 22:26 |
And I explain those in a comment.
I have a variable in here.
|
| 22:29 |
A floating point variable called d.
That's for the diameter of the Slider
|
| 22:33 |
button that you click on.
I draw a line for this lighter, I specify
|
| 22:37 |
the stroke color from the palate that I
used above.
|
| 22:40 |
I make it square end and I make it five
pixels thick.
|
| 22:44 |
Then I draw the line from the one end to
the other near the bottom.
|
| 22:50 |
And then I created a button that you can
actually click on with your mouse to drag across.
|
| 22:55 |
I did this by simply drawing two circles,
I wanted it to be two different colors.
|
| 22:59 |
I turned off the strokes so there's no
outline, I give the first circle it's
|
| 23:03 |
fill and then I have a function that
tells if a person is dragging the slider.
|
| 23:09 |
And it's whether the distance of the
mouse is less than, for instance one
|
| 23:12 |
diameter away from the current center of
the circle for this lighter.
|
| 23:17 |
Now it actually means that the distance
is bigger than the button itself.
|
| 23:22 |
If you make it exactly the size of the
button it's really easy to get off of it
|
| 23:25 |
and it stops scrolling.
So, you give people a little of wiggle room.
|
| 23:30 |
So, if they scroll a little faster they
don't loose the scroll.
|
| 23:34 |
And so I have that distance as long as
that distance between the mouse and the
|
| 23:38 |
Slider button is beneath a certian
amount.
|
| 23:42 |
And the mouse is pressed, then the
variable Slider X takes on the current
|
| 23:46 |
mouse value for the X variable.
So, it will slide with it.
|
| 23:51 |
On the other hand, I don't want it to go
anywhere that the mouse goes.
|
| 23:55 |
And so I constrain it so it won't go off
the end of the slider.
|
| 23:59 |
So, I use slider X and I constrain
itself, and I limit it to the range of
|
| 24:03 |
the line that I drew.
Also, at the end here, you see that I
|
| 24:07 |
have this minus one.
I actually am stopping the slider one
|
| 24:11 |
pixel early on the right.
The reason for that is if I run it all
|
| 24:15 |
the way to the edge on (INAUDIBLE),
because the slider controls the row that
|
| 24:18 |
we're dealing with.
The slider actually goes off the edge of
|
| 24:22 |
the data sheet and we get error messages.
So, by subtracting one, I prevent that
|
| 24:26 |
array error from happening.
Then I draw one circle, and then I draw a
|
| 24:32 |
smaller circle that is a different color
on top, so it's a two color circle.
|
| 24:38 |
Then what I have, is I have a title above
the slider, that simply says it's in the
|
| 24:42 |
center, and I gave it a color, and I
positioned it down where I want it to be.
|
| 24:48 |
That's going to say Weeks.
Then I have the minimum and maximum labels.
|
| 24:53 |
Those are going to be January 2005 and
December 2012.
|
| 24:57 |
Those are each positioned at the end of
the slider line.
|
| 25:00 |
Then I have the slider set data value.
This is the important one right here,
|
| 25:04 |
where the row that we're currently
reading on the data sheet Is a function
|
| 25:08 |
of the sliders.
So, let's take a look at this for a second.
|
| 25:13 |
I have slider X there, that's where it's
positioned and what I do, is I subtract
|
| 25:17 |
the left margin.
So, I'm finding how far away from the
|
| 25:21 |
left margin is it, right?
And then I divide that distance by the
|
| 25:26 |
width of the grid, GW is Grid Width.
So, it's given me, what proportion of the
|
| 25:31 |
width, the slider has gone across.
So, I first get the difference and I
|
| 25:35 |
divide it by the total range and that
gives me a proportion anywhere from zero
|
| 25:38 |
to one.
So, zero is when it's totally on the left
|
| 25:42 |
side, one is when it's all the way over
on the right.
|
| 25:45 |
And then what I do is, I take that
proportion and I multiply it times at the
|
| 25:48 |
row count.
Remember the row count is 418.
|
| 25:52 |
So, I'm taking a number that's like .27
or .705, or whatever, and I'm multiplying
|
| 25:55 |
it times the row count.
And then what I have to do, because that
|
| 26:00 |
could very easily give me a decimal
value, and the row indexes have to be
|
| 26:04 |
whole numbers.
I then wrap all of that in parenthesis,
|
| 26:08 |
and I put int in the front.
And what that means is I'm taking the
|
| 26:12 |
result of that calculation and I'm
casting it as an integer variable so it
|
| 26:15 |
has to be a whole number.
And that way I can use the slider to
|
| 26:19 |
specify the row.
Finally, the next line has the command
|
| 26:23 |
for some text that will appear above the
slider, to say what the current row is,
|
| 26:28 |
based on the date labels, within the data
sheet.
|
| 26:33 |
So, I have text, that's whenever I
want to have something appear.
|
| 26:37 |
And then this long one, Composers, is the
name of the data object.
|
| 26:41 |
And then .getstring means going into that
object, go into that data sheet, and get
|
| 26:45 |
a string variable.
And I want you to use the row that's the
|
| 26:49 |
up and down that has to do with the
slider determining that.
|
| 26:53 |
And then use column 0, that's the first
column in the data sheet that has the
|
| 26:57 |
dates listed.
And then position it directly above the
|
| 27:01 |
slider, give it the same exposition as
the slider, and put it just a little bit
|
| 27:04 |
above it.
That's what the height of the window
|
| 27:08 |
minus the bottom margin, minus 25 pixels.
Something I had to take a little bit of
|
| 27:12 |
trial and error with to get it a good
height above the slider.
|
| 27:16 |
And that finishes the Slider function.
The next part of this is the actual bar
|
| 27:21 |
graph itself.
This is the one that actually shows the data.
|
| 27:25 |
I've created a function called Bar.
And then it takes the arguments of the
|
| 27:29 |
left margin.
The grid width, the bottom margin, the
|
| 27:34 |
bar width, the current number of the bar
that it's drawing.
|
| 27:38 |
The total number of bars, that's bar n,
the name of that bar that is the
|
| 27:42 |
composer's name, that's coming from an
array.
|
| 27:46 |
And then the bar height, and that's
going to be based off the data in the spreadsheet.
|
| 27:53 |
So, the first thing I do is I pick a
color for the bars.
|
| 27:56 |
I've picked it from the Palette array
that I have up earlier, and then I need
|
| 28:00 |
to create several variables that go into
sort intermediate calculations.
|
| 28:05 |
The first one is bar H.
That calculates the actual height of the
|
| 28:08 |
bar, and what it is is I use this one
that's called bar height.
|
| 28:13 |
And, that's a variable that's going to be
from zero to 100, and it's going to
|
| 28:16 |
appear in the, data sheet.
And then I multiply that times, the grid
|
| 28:22 |
height by 100.
Now the reason is, the grid is actually
|
| 28:25 |
300 pixels high.
And if I took the bar heights, nothing
|
| 28:29 |
would get above 100 pixels.
So, it would look like nobody ever went
|
| 28:33 |
about 33 percent.
I need so that 100 in the data sheet goes
|
| 28:36 |
all the way to the top.
So, by taking the bar height, which is
|
| 28:39 |
the number in the data sheet.
And multiplying it times this value,
|
| 28:43 |
which is 300 pixels divided by 100, I
triple it.
|
| 28:46 |
And it makes it so that 100 goes all the
way to the top.
|
| 28:49 |
Next is a relatively long equation that I
used to get the x coordinates, the left
|
| 28:53 |
right coordinates, for spacing the bars
evenly.
|
| 28:57 |
This is called bar x and it's a floating
point variable, and what I do is start
|
| 29:00 |
with the left margin.
And then I take the number of the current
|
| 29:04 |
bar that goes from zero to four and then
I add one so it converts it to one to
|
| 29:08 |
five and then I multiply that times a
ratio.
|
| 29:13 |
The ratio is the grid width and then I'm
dividing that grid width by the number of
|
| 29:17 |
bars plus one.
So, if I want to split something in for
|
| 29:22 |
instance three equal pieces, I need to
have two dividing lines.
|
| 29:26 |
Well, I'm going to have to actually
instead of just having two dividing lines.
|
| 29:30 |
I have to divide the whole thing by three
and put it into thirds so I can put those
|
| 29:33 |
two lines in the middle.
That's why you have that add one onto it.
|
| 29:38 |
So, what do you have again, is the left
margin and to that I add the product of
|
| 29:42 |
the bar index plus one.
So, that converts into a one to five scale.
|
| 29:48 |
And then I multiply that times this ratio
of the total grid with, divided by the
|
| 29:53 |
number of bars I want plus one.
That gets me the even split points.
|
| 29:59 |
The next line after that is bar
underscore, by.
|
| 30:02 |
And that is the y position for the bottom
of the bar.
|
| 30:07 |
And again, part of this is because it's
drawing the things upside down from what
|
| 30:10 |
you want.
You think of zero on a graph as being at
|
| 30:13 |
the bottom.
And then, as numbers get bigger, it goes up.
|
| 30:17 |
Well, in computer graphics, 0's at the
top and a positive number goes down, and
|
| 30:21 |
so you sometimes have to go through these
little machinations.
|
| 30:25 |
i get the total height of the window and
I subtract the bottom margin, and that
|
| 30:28 |
tell some where all of them are supposed
to be at the bottom.
|
| 30:32 |
That's the zero line on the grid.
Then what I have is a variable called
|
| 30:36 |
Bar, and then TY for the top of the bar,
the Y position.
|
| 30:41 |
And that's the one I get by subtracting
bar h, that's the total height of the bar
|
| 30:44 |
that I got a few lines above, and
subtracting that from the bottom position.
|
| 30:50 |
Again, it's because the numbers get
smaller as you go up, and this is what
|
| 30:53 |
makes that transition.
Finally, I have one that says, where do I
|
| 30:57 |
want the labels for the bar labels?
That's the name of the composers, and
|
| 31:01 |
trial and error, I've found the number is
65 pixels.
|
| 31:04 |
So, that's 65 pixels from the top of the
window.
|
| 31:06 |
The next part of the function actually
draws the bar.
|
| 31:09 |
They're rectangles and what you do in a
rectangle is specify by the top left
|
| 31:13 |
coordinates, the x and the y for the top
left, and then how wide it is and how
|
| 31:17 |
tall it is.
There are other ways to specify it, but
|
| 31:21 |
this one worked well for this.
And so I do bar x, that gets me to the
|
| 31:24 |
middle of the bar, and then I subtract
half the width of the bar to get to the
|
| 31:27 |
left edge.
And bar t y is the y position of the top
|
| 31:32 |
of the bar.
So, that gets me the coordinates for the
|
| 31:35 |
top left corner of the bar.
BW is Bar Width, I set that as 100 pixels
|
| 31:39 |
earlier on.
And then Bar H is the height of the bar
|
| 31:42 |
that gets derived from the data sheet.
And that's how far it has to go to reach
|
| 31:46 |
the zero line at the bottom.
Next, beneath that, and the last lines of
|
| 31:50 |
code in this whole thing, are the code to
put the pictures of the composers above
|
| 31:54 |
the labels.
So, I use image.
|
| 31:57 |
That's how you place pictures, and then I
refer to the portraits.
|
| 32:01 |
That's an array that I created of the
images, so I use portraits.
|
| 32:05 |
And then bar I means which index number,
and that's 01234.
|
| 32:11 |
So, that tells me which image to place,
and then I get the X and Y positions.
|
| 32:15 |
The bar underscore x minus BW2, that's
how I positioned the bars themselves a
|
| 32:20 |
moment ago.
And then I give them a vertical position
|
| 32:24 |
80 pixels down.
That I got through trial and error, and
|
| 32:28 |
because the images are 100 pixels wide,
and the bars are 100 pixels wide, this
|
| 32:31 |
will align them.
Then I put labels on and I use Text Align
|
| 32:35 |
to center it, the left and right, that's
the first one, and center top to bottom.
|
| 32:41 |
Then I pick a color that I want for this,
that comes from the color array that I
|
| 32:44 |
called Palette.
And then I actually put the name of the
|
| 32:48 |
composer that's text that appears, and
that completes the entire code.
|
| 32:52 |
So, let me scroll back up to the top.
And, when I run the sketch this is what
|
| 32:57 |
it looks like.
At the top, Google Searches For Opera Composers.
|
| 33:03 |
Then the name and pictures of each of the
composers.
|
| 33:06 |
Then I have five lines: zero, 25, 50, 75,
100.
|
| 33:11 |
And then I have bars at the bottom.
And then the slider at the very bottom.
|
| 33:15 |
You see it currently is at January 2005.
And, if I come down, and I click on that,
|
| 33:21 |
and I drag it across.
We see the values changing for the
|
| 33:25 |
relative popularity of each composer's
name as a search term during that week.
|
| 33:32 |
So, this is one week's data at a time.
You see, what's interesting is that
|
| 33:35 |
things actually jump around a fair
amount.
|
| 33:38 |
I got too far off the button.
Although we see Verdi is generally very
|
| 33:44 |
popular, Mozart is generally very
popular.
|
| 33:47 |
Now what we have is this breakout couple
of years for Mozart, if I get about right
|
| 33:52 |
there we go.
This is the highest search term for any
|
| 33:56 |
of these and again it's for Mozart opera.
And so, December 2009, something
|
| 34:00 |
immensely popular for Mozart, have to go
back and read Opera News to see what was
|
| 34:04 |
happening back then.
And we see that others as we scroll
|
| 34:08 |
through, become more popular over time.
Bizet had a breakout time in May of 2011.
|
| 34:15 |
He basically is only known for Carmen, so
something significant was happening there.
|
| 34:21 |
Always scroll through to the end.
Anyhow, that's where my particular
|
| 34:25 |
visualization looks like.
And they will ask people to look at the
|
| 34:28 |
relative popularity of each of these
composers across a several years span.
|
| 34:33 |
Now there is one more step to this
project, and that is to save this as a
|
| 34:36 |
stand alone application.
Let me show you how that works.
|
| 34:40 |
It's actually really, really easy to do
in processing.
|
| 34:44 |
I'm going to close this window.
And then you see how in the top right
|
| 34:51 |
corner of the window it says java in a
small box?
|
| 34:55 |
We have some choices here.
It is actually able to save things as
|
| 34:59 |
android applications and Javascript,
although that one is still being fully
|
| 35:02 |
developed in the Beta.
So, this particular sketch does not
|
| 35:06 |
convert cleanly to Javascript yet, but
that will change.
|
| 35:10 |
And then there's an experimental mode,
which means you'll be able to add other
|
| 35:12 |
modes as well.
But I'm going to just leave it in Java
|
| 35:15 |
for right now.
Then I'm going to come across to this
|
| 35:19 |
button with a right arrow on it.
It says Export Application.
|
| 35:23 |
If I click that button, it's going to ask
me what platforms do I want.
|
| 35:29 |
Windows, Mac, and Linux, I'll just save
all three of them.
|
| 35:33 |
Then I have a couple of options.
False screen is nice because it puts a
|
| 35:36 |
background to cover up other things.
And a Stop button is also a good thing,
|
| 35:40 |
although you actually can stop by just
hitting escape.
|
| 35:43 |
I'm going to hit Export, and it shows me
that in the File browser, I now have five
|
| 35:48 |
new folders.
The Windows 64 bit application, 32 bit
|
| 35:54 |
application, the Mac OSX and 64 and 32
bit Linux versions.
|
| 36:00 |
I'm on a Windows computer right now, so
let me open up the application Windows 64.
|
| 36:06 |
And you see I've got this thing right
down here.
|
| 36:08 |
If I double click on this one this Batch
file, it's going to open up that window,
|
| 36:13 |
and now I've got the composers
themselves.
|
| 36:17 |
This is a standalone application that
could hide the other ones, and now this
|
| 36:20 |
is one that functions right here.
A person doesn't have to have processing
|
| 36:25 |
on their computer to be able to run this.
And if you're delivering a product to a
|
| 36:30 |
client, this can be a very convenient way
for them to be able to use it.
|
| 36:36 |
Any time they have on their machines with
or without an internet connection.
|
| 36:41 |
And so that is how I ultimately solved
this end challenge project of creating an
|
| 36:46 |
interactive bar chart.
To look at the Google Trends for opera
|
| 36:51 |
composers over a several year period.
Hopefully you came up with something that
|
| 36:56 |
was interesting, exciting, and
informative as well.
|
| 36:58 |
Thanks for working with me, and best of
luck in your own work.
|
| 37:01 |
|
| Collapse this transcript |