Community Growth Web - Coeur d'Alene, ID

Girls Who Code - Dynamically Changing Data

Tabular Data

A table consists of data arranged as a set of rows and columns, also called “tabular data.” If you've ever used a spreadsheet, this is tabular data. Processing's loadTable() function takes comma-separated (csv) or tab-separated (tsv) values and automatically places the contents into a Table object storing the data in columns and rows. This is a great deal more convenient than struggling to manually parse large data files with split(). It works as follows. Let's say you have a data file that looks like:


Instead of saying:

String[] stuff = loadStrings("data.csv"); 
We can now say:
Table table = loadTable("data.csv"); 
Now I've missed an important detail. Take a look again at the data.csv text file above. Notice how the first line of text is not the data itself, but rather a header row. This row includes labels that describe the data included in each subsequent row. The good news is that Processing can automatically interpret and store the headers for you, if you pass in the option "header" when loading the table. (In addition to "header", there are other options you can specify. For example, if your file is called data.txt but is comma separated data you can pass in the option "csv". If it also has a header row, then you can specifiy both options like so: "header,csv"). A full list of options can be found on the loadTable() documentation page.
Table table = loadTable("data.csv", "header"); 
Now that the table is loaded, I can show how you grab individual pieces of data or iterate over the entire table. Let's look at the data visualized as a grid. 

 

In the above grid you can see that the data is organized in terms of rows and columns. One way to access the data, therefore, would be to request a value by its numeric row and column location (with zero being the first row or first column). This is similar to accessing a pixel color at a given (x,y) location, though in this case the y position (row) comes first. The following code requests a piece of data at a given (row, column) location.

int val1 = table.getInt(2, 1);      // val now has the value 235  
float val2 = table.getFloat(3, 2);  // val2 now has the value 44.758068  
String s = table.getString(0, 3);   // s now has the value “Happy” 
While the numeric index is sometimes useful, it’s generally going to be more convenient to access each piece of data by the column name. For example, I could pull out a specific row from the Table.
TableRow row = table.getRow(2); // Gets the third row (index 2) 
Note in the above line of code that a Table object refers to the entire table of data while a TableRow object handles an individual row of data within the Table.

Once I have the TableRow object, I can ask for data from some or all of the columns.

int x = row.getInt("x"); // 	    // x has the value 273  
int y = row.getInt("y");            // y has the value 235  
float d = row.getFloat("diameter"); // d has the value 61.14072  
String s = row.getString("name");   // s has the value “Joyous” 
The method getRow() returns a single row from the table. If you want to grab all the rows and iterate over them you can do so in a loop with a counter accessing each row one at a time. The total number of available rows can be retrieved with getRowCount().
for (int i = 0; i<table.getRowCount(); i++) {    
// Access each row of the table one at a time, in a loop.   
TableRow row = table.getRow(i);   
float x = row.getFloat("x");   
float y = row.getFloat("y");   
float d = row.getFloat("diameter");   
String n = row.getString("name");    // Do something with the data of each row  } 
If you want to search for a select number of rows within the table, you can do so with findRows() and matchRows().

In addition to being read, Table objects can be altered or created on the fly while a sketch is running. Cell values can be adjusted, rows can be removed, and new rows can be added. For example, to set new values in a cell there are functions setInt(), setFloat(), and setString().

row.setInt("x", mouseX); // Update the value of column "x" to mouseX in a given TableRow. 
To add a new row to a Table, simply call the method addRow() and set the values of each column.
//Create a new row. TableRow row = table.addRow();  
//Set the values of all columns in that row. 
row.setFloat("x", mouseX); 
row.setFloat("y", mouseY); 
row.setFloat("diameter", random(40, 80)); 
row.setString("name", "new label"); 
To delete a row, simply call the method removeRow() and pass in the numeric index of the row you would like removed. For example, the following code removes the first row whenever the size of the table is greater than ten rows.
// If the table has more than 10 rows if (table.getRowCount()>10) {  
//Delete the first row (index 0).   
table.removeRow(0); } 

The following example puts all of the above code together. Notice how each row of the table contains the data for a Bubble object.

// The data from the Table object will fill the array of Bubble objects 
Table table; 
Bubble[] bubbles;  
void setup() {   
	size(480, 360);   
	loadData(); }  

void draw() {   
	background(255);   
	// Display all bubbles   
	for (int i = 0; i<bubbles.length; i++) {     
		bubbles[i].display();   
	} 
}  

void loadData() {   
	// "header" indicates the file has header row. The size of the array    
	// is then determined by the number of rows in the table.    
	table = loadTable("data.csv", "header");   
	bubbles = new Bubble[table.getRowCount()];     

	for (int i = 0; i<table.getRowCount(); i++) {     
	// Iterate over all the rows in a table.     
	TableRow row = table.getRow(i);  	     

	// Access the fields via their column name (or index).     
	float x = row.getFloat("x");     
	float y = row.getFloat("y");     
	float d = row.getFloat("diameter");     
	String n = row.getString("name");     
	// Make a Bubble object out of the data from each row.     
	bubbles[i] = new Bubble(x, y, d, n);   
	} 
}   

void mousePressed() {   
	// When the mouse is pressed, create a new row and set the values for each column of that row.   
	TableRow row = table.addRow();   
	row.setFloat("x", mouseX);   
	row.setFloat("y", mouseY);   
	row.setFloat("diameter", random(40, 80));   
	row.setString("name", "Blah");    

	// If the table has more than 10 rows, delete the oldest row.   
	if (table.getRowCount()>10) {     
		table.removeRow(0);   
	}    

	// This writes the table back to the original CSV file   
	// and reloads the file so that what's drawn matches.   
	saveTable(table, "data/data.csv");   
	loadData(); 
}  

	// This simple Bubble class draws a circle to the window  
	// and displays a text label when the mouse hovers. 
class Bubble {   
	float x, y;   
	float diameter;   
	String name;      

	boolean over = false;      

	// Create the Bubble   
	Bubble(float tempX, float tempY, float tempD, String s) {     
		x = tempX;     
		y = tempY;     
		diameter = tempD;     
		name = s;   
}      

// Checking if mouse is over the bubble   
void rollover(float px, float py) {     
	float d = dist(px, py, x, y);     
	if (d<diameter/2) {       
		over = true;      
	} else {       
	over = false;     
	}   
}      

// Display the Bubble   
void display() {     
	stroke(0);     
	strokeWeight(2);     
	noFill();     
	ellipse(x, y, diameter, diameter);     
	if (over) {       
		fill(0);       
		textAlign(CENTER);       
		text(name, x, y+diameter/2+20);     
		}   
	} 
}