mirror of
https://github.com/processing/processing4.git
synced 2026-01-28 10:51:07 +01:00
add "visualizing data" examples
This commit is contained in:
14
java/examples/Books/Visualizing Data/ch03-usmap/readme.txt
Normal file
14
java/examples/Books/Visualizing Data/ch03-usmap/readme.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
For this chapter, the a sketch that implements every step described in the
|
||||
book is included. This is because the figures and steps used to develop the
|
||||
code don't really line up (there are more steps than figures). Each sketch
|
||||
has a name like step15_framerate, which should be self-explanatory when used
|
||||
with the book. (I do not recommend using this ugly style of naming for your
|
||||
own sketches, it's done this way simply because the step/figure numbering
|
||||
is relevant and needs to be included).
|
||||
|
||||
All examples have been tested but if you find errors of any kind (typos,
|
||||
unused variables, profanities in the comments, the usual), please contact
|
||||
me through http://benfry.com/writing and I'll be happy to fix the code.
|
||||
|
||||
The code in this file is (c) 2008 Ben Fry. Rights to use of the code can be
|
||||
found in the preface of "Visualizing Data".
|
||||
@@ -0,0 +1,11 @@
|
||||
PImage mapImage;
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,30 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
// Make a data table from a file that contains
|
||||
// the coordinates of each state.
|
||||
locationTable = new Table("locations.tsv");
|
||||
// The row count will be used a lot, store it locally.
|
||||
rowCount = locationTable.getRowCount();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
// Drawing attributes for the ellipses
|
||||
smooth();
|
||||
fill(192, 0, 0);
|
||||
noStroke();
|
||||
|
||||
// Loop through the rows of the locations file and draw the points
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float x = locationTable.getFloat(row, 1); // column 1
|
||||
float y = locationTable.getFloat(row, 2); // column 2
|
||||
ellipse(x, y, 9, 9);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
class Table {
|
||||
String[][] data;
|
||||
int rowCount;
|
||||
|
||||
|
||||
Table() {
|
||||
data = new String[10][10];
|
||||
}
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
// Write this table as a TSV file
|
||||
void write(PrintWriter writer) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
for (int j = 0; j < data[i].length; j++) {
|
||||
if (j != 0) {
|
||||
writer.print(TAB);
|
||||
}
|
||||
if (data[i][j] != null) {
|
||||
writer.print(data[i][j]);
|
||||
}
|
||||
}
|
||||
writer.println();
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,57 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
smooth();
|
||||
fill(192, 0, 0);
|
||||
noStroke();
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Map the size of the ellipse to the data value
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
// Get data value for state
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
// Re-map the value to a number between 2 and 40
|
||||
float mapped = map(value, dataMin, dataMax, 2, 40);
|
||||
// Draw an ellipse for this item
|
||||
ellipse(x, y, mapped, mapped);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,54 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float percent = norm(value, dataMin, dataMax);
|
||||
color between = lerpColor(#FF4422, #4422CC, percent); // red to blue
|
||||
fill(between);
|
||||
ellipse(x, y, 15, 15);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,54 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
tint(255, 160);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float percent = norm(value, dataMin, dataMax);
|
||||
color between = lerpColor(#296F34, #61E2F0, percent);
|
||||
fill(between);
|
||||
ellipse(x, y, 15, 15);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,54 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float percent = norm(value, dataMin, dataMax);
|
||||
color between = lerpColor(#296F34, #61E2F0, percent, HSB);
|
||||
fill(between);
|
||||
ellipse(x, y, 15, 15);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,59 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float diameter = 0;
|
||||
if (value >= 0) {
|
||||
diameter = map(value, 0, dataMax, 3, 30);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
diameter = map(value, 0, dataMin, 3, 30);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipse(x, y, diameter, diameter);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,58 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
if (value >= 0) {
|
||||
float a = map(value, 0, dataMax, 0, 255);
|
||||
fill(#333366, a);
|
||||
} else {
|
||||
float a = map(value, 0, dataMin, 0, 255);
|
||||
fill(#EC5166, a);
|
||||
}
|
||||
ellipse(x, y, 15, 15);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,70 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
// Read the data table
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
// Find the minimum and maximum values
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
if (dist(x, y, mouseX, mouseY) < radius+2) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
// Show the data value and the state abbreviation in parentheses
|
||||
text(value + " (" + abbrev + ")", x, y-radius-4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,70 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
if (dist(x, y, mouseX, mouseY) < radius+2) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
text(name + " " + value, x, y-radius-4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,94 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = MAX_FLOAT;
|
||||
float dataMax = MIN_FLOAT;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float value = dataTable.getFloat(row, 1);
|
||||
if (value > dataMax) {
|
||||
dataMax = value;
|
||||
}
|
||||
if (value < dataMin) {
|
||||
dataMin = value;
|
||||
}
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
|
||||
// Global variables set in drawData() and read in draw()
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
// Use the built-in width and height variables to set the
|
||||
// closest distance high so it will be replaced immediately
|
||||
closestDist = width*height;
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
// Use global variables set in drawData()
|
||||
// to draw text related to closest circle.
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
// Because the following check is done each time a new
|
||||
// circle is drawn, we end up with the values of the
|
||||
// circle closest to the mouse.
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
closestText = name + " " + value;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,90 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
closestText = name + " " + value;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(-10, 10);
|
||||
dataTable.setFloat(row, 1, newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,90 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
closestText = name + " " + nfp(value, 0, 2);
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(-10, 10);
|
||||
dataTable.setFloat(row, 1, newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# An array of the 50 state abbreviations
|
||||
@states = ('AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA',
|
||||
'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD',
|
||||
'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ',
|
||||
'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC',
|
||||
'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY');
|
||||
|
||||
# A CGI script must identify the type of data it's sending,
|
||||
# this line specifies that plain text data will follow.
|
||||
print "Content-type: text/plain\n\n";
|
||||
|
||||
# Loop through each of the state abbreviations in the array
|
||||
foreach $state (@states) {
|
||||
|
||||
# Pick a random number between -10 and 10. (rand() returns a
|
||||
# number between 0 and 1, multiply that by 20 and subtract 10)
|
||||
$r = (rand() * 20) - 10;
|
||||
|
||||
# Print the state name, followed by a tab,
|
||||
# then the random value, followed by a new line.
|
||||
print "$state\t$r\n";
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
updateTable();
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
float value = dataTable.getFloat(abbrev, 1);
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
closestText = name + " " + nfp(value, 0, 2);
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
dataTable = new Table("http://benfry.com/writing/map/random.cgi");
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
class Integrator {
|
||||
|
||||
final float DAMPING = 0.5f;
|
||||
final float ATTRACTION = 0.2f;
|
||||
|
||||
float value;
|
||||
float vel;
|
||||
float accel;
|
||||
float force;
|
||||
float mass = 1;
|
||||
|
||||
float damping = DAMPING;
|
||||
float attraction = ATTRACTION;
|
||||
boolean targeting;
|
||||
float target;
|
||||
|
||||
|
||||
Integrator() { }
|
||||
|
||||
|
||||
Integrator(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
Integrator(float value, float damping, float attraction) {
|
||||
this.value = value;
|
||||
this.damping = damping;
|
||||
this.attraction = attraction;
|
||||
}
|
||||
|
||||
|
||||
void set(float v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
if (targeting) {
|
||||
force += attraction * (target - value);
|
||||
}
|
||||
|
||||
accel = force / mass;
|
||||
vel = (vel + accel) * damping;
|
||||
value += vel;
|
||||
|
||||
force = 0;
|
||||
}
|
||||
|
||||
|
||||
void target(float t) {
|
||||
targeting = true;
|
||||
target = t;
|
||||
}
|
||||
|
||||
|
||||
void noTarget() {
|
||||
targeting = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,106 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
Integrator[] interpolators;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
interpolators = new Integrator[rowCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float initialValue = dataTable.getFloat(row, 1);
|
||||
interpolators[row] = new Integrator(initialValue);
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
interpolators[row].update();
|
||||
}
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
// Figure out what row this is
|
||||
int row = dataTable.getRowIndex(abbrev);
|
||||
// Get the current value
|
||||
float value = interpolators[row].value;
|
||||
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
String val = nfp(interpolators[row].target, 0, 2);
|
||||
closestText = name + " " + val;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(dataMin, dataMax);
|
||||
interpolators[row].target(newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
class Integrator {
|
||||
|
||||
final float DAMPING = 0.5f;
|
||||
final float ATTRACTION = 0.2f;
|
||||
|
||||
float value;
|
||||
float vel;
|
||||
float accel;
|
||||
float force;
|
||||
float mass = 1;
|
||||
|
||||
float damping = DAMPING;
|
||||
float attraction = ATTRACTION;
|
||||
boolean targeting;
|
||||
float target;
|
||||
|
||||
|
||||
Integrator() { }
|
||||
|
||||
|
||||
Integrator(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
Integrator(float value, float damping, float attraction) {
|
||||
this.value = value;
|
||||
this.damping = damping;
|
||||
this.attraction = attraction;
|
||||
}
|
||||
|
||||
|
||||
void set(float v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
if (targeting) {
|
||||
force += attraction * (target - value);
|
||||
}
|
||||
|
||||
accel = force / mass;
|
||||
vel = (vel + accel) * damping;
|
||||
value += vel;
|
||||
|
||||
force = 0;
|
||||
}
|
||||
|
||||
|
||||
void target(float t) {
|
||||
targeting = true;
|
||||
target = t;
|
||||
}
|
||||
|
||||
|
||||
void noTarget() {
|
||||
targeting = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,107 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
Integrator[] interpolators;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
interpolators = new Integrator[rowCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float initialValue = dataTable.getFloat(row, 1);
|
||||
interpolators[row] = new Integrator(initialValue);
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
frameRate(30);
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
interpolators[row].update();
|
||||
}
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
// Figure out what row this is
|
||||
int row = dataTable.getRowIndex(abbrev);
|
||||
// Get the current value
|
||||
float value = interpolators[row].value;
|
||||
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
String val = nfp(interpolators[row].target, 0, 2);
|
||||
closestText = name + " " + val;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(dataMin, dataMax);
|
||||
interpolators[row].target(newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
class Integrator {
|
||||
|
||||
final float DAMPING = 0.5f;
|
||||
final float ATTRACTION = 0.2f;
|
||||
|
||||
float value;
|
||||
float vel;
|
||||
float accel;
|
||||
float force;
|
||||
float mass = 1;
|
||||
|
||||
float damping = DAMPING;
|
||||
float attraction = ATTRACTION;
|
||||
boolean targeting;
|
||||
float target;
|
||||
|
||||
|
||||
Integrator() { }
|
||||
|
||||
|
||||
Integrator(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
Integrator(float value, float damping, float attraction) {
|
||||
this.value = value;
|
||||
this.damping = damping;
|
||||
this.attraction = attraction;
|
||||
}
|
||||
|
||||
|
||||
void set(float v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
if (targeting) {
|
||||
force += attraction * (target - value);
|
||||
}
|
||||
|
||||
accel = force / mass;
|
||||
vel = (vel + accel) * damping;
|
||||
value += vel;
|
||||
|
||||
force = 0;
|
||||
}
|
||||
|
||||
|
||||
void target(float t) {
|
||||
targeting = true;
|
||||
target = t;
|
||||
}
|
||||
|
||||
|
||||
void noTarget() {
|
||||
targeting = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,107 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
Integrator[] interpolators;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
interpolators = new Integrator[rowCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float initialValue = dataTable.getFloat(row, 1);
|
||||
interpolators[row] = new Integrator(initialValue, 0.5, 0.01);
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
//frameRate(30);
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
interpolators[row].update();
|
||||
}
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
// Figure out what row this is
|
||||
int row = dataTable.getRowIndex(abbrev);
|
||||
// Get the current value
|
||||
float value = interpolators[row].value;
|
||||
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
String val = nfp(interpolators[row].target, 0, 2);
|
||||
closestText = name + " " + val;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(dataMin, dataMax);
|
||||
interpolators[row].target(newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
class Integrator {
|
||||
|
||||
final float DAMPING = 0.5f;
|
||||
final float ATTRACTION = 0.2f;
|
||||
|
||||
float value;
|
||||
float vel;
|
||||
float accel;
|
||||
float force;
|
||||
float mass = 1;
|
||||
|
||||
float damping = DAMPING;
|
||||
float attraction = ATTRACTION;
|
||||
boolean targeting;
|
||||
float target;
|
||||
|
||||
|
||||
Integrator() { }
|
||||
|
||||
|
||||
Integrator(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
Integrator(float value, float damping, float attraction) {
|
||||
this.value = value;
|
||||
this.damping = damping;
|
||||
this.attraction = attraction;
|
||||
}
|
||||
|
||||
|
||||
void set(float v) {
|
||||
value = v;
|
||||
}
|
||||
|
||||
|
||||
void update() {
|
||||
if (targeting) {
|
||||
force += attraction * (target - value);
|
||||
}
|
||||
|
||||
accel = force / mass;
|
||||
vel = (vel + accel) * damping;
|
||||
value += vel;
|
||||
|
||||
force = 0;
|
||||
}
|
||||
|
||||
|
||||
void target(float t) {
|
||||
targeting = true;
|
||||
target = t;
|
||||
}
|
||||
|
||||
|
||||
void noTarget() {
|
||||
targeting = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
class Table {
|
||||
int rowCount;
|
||||
String[][] data;
|
||||
|
||||
|
||||
Table(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
data = new String[rows.length][];
|
||||
|
||||
for (int i = 0; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
// copy to the table array
|
||||
data[rowCount] = pieces;
|
||||
rowCount++;
|
||||
|
||||
// this could be done in one fell swoop via:
|
||||
//data[rowCount++] = split(rows[i], TAB);
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (String[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
// find a row by its name, returns -1 if no row found
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (data[i][0].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int row) {
|
||||
return getString(row, 0);
|
||||
}
|
||||
|
||||
|
||||
String getString(int rowIndex, int column) {
|
||||
return data[rowIndex][column];
|
||||
}
|
||||
|
||||
|
||||
String getString(String rowName, int column) {
|
||||
return getString(getRowIndex(rowName), column);
|
||||
}
|
||||
|
||||
|
||||
int getInt(String rowName, int column) {
|
||||
return parseInt(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
int getInt(int rowIndex, int column) {
|
||||
return parseInt(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(String rowName, int column) {
|
||||
return parseFloat(getString(rowName, column));
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int column) {
|
||||
return parseFloat(getString(rowIndex, column));
|
||||
}
|
||||
|
||||
|
||||
void setRowName(int row, String what) {
|
||||
data[row][0] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(int rowIndex, int column, String what) {
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setString(String rowName, int column, String what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = what;
|
||||
}
|
||||
|
||||
|
||||
void setInt(int rowIndex, int column, int what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setInt(String rowName, int column, int what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(int rowIndex, int column, float what) {
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
|
||||
|
||||
void setFloat(String rowName, int column, float what) {
|
||||
int rowIndex = getRowIndex(rowName);
|
||||
data[rowIndex][column] = str(what);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
AL 439 270
|
||||
AK 94 325
|
||||
AZ 148 241
|
||||
AR 368 247
|
||||
CA 56 176
|
||||
CO 220 183
|
||||
CT 576 120
|
||||
DE 556 166
|
||||
FL 510 331
|
||||
GA 478 267
|
||||
HI 232 380
|
||||
ID 143 101
|
||||
IL 405 168
|
||||
IN 437 165
|
||||
IA 357 147
|
||||
KS 302 194
|
||||
KY 453 203
|
||||
LA 371 302
|
||||
ME 595 59
|
||||
MD 538 162
|
||||
MA 581 108
|
||||
MI 446 120
|
||||
MN 339 86
|
||||
MS 406 274
|
||||
MO 365 197
|
||||
MT 194 61
|
||||
NE 286 151
|
||||
NV 102 157
|
||||
NH 580 89
|
||||
NJ 561 143
|
||||
NM 208 245
|
||||
NY 541 107
|
||||
NC 519 221
|
||||
ND 283 65
|
||||
OH 472 160
|
||||
OK 309 239
|
||||
OR 74 86
|
||||
PA 523 144
|
||||
RI 589 117
|
||||
SC 506 251
|
||||
SD 286 109
|
||||
TN 441 229
|
||||
TX 291 299
|
||||
UT 154 171
|
||||
VT 567 86
|
||||
VA 529 189
|
||||
WA 92 38
|
||||
WV 496 178
|
||||
WI 392 103
|
||||
WY 207 125
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL Alabama
|
||||
AK Alaska
|
||||
AZ Arizona
|
||||
AR Arkansas
|
||||
CA California
|
||||
CO Colorado
|
||||
CT Connecticut
|
||||
DE Delaware
|
||||
FL Florida
|
||||
GA Georgia
|
||||
HI Hawaii
|
||||
ID Idaho
|
||||
IL Illinois
|
||||
IN Indiana
|
||||
IA Iowa
|
||||
KS Kansas
|
||||
KY Kentucky
|
||||
LA Louisiana
|
||||
ME Maine
|
||||
MD Maryland
|
||||
MA Massachusetts
|
||||
MI Michigan
|
||||
MN Minnesota
|
||||
MS Mississippi
|
||||
MO Missouri
|
||||
MT Montana
|
||||
NE Nebraska
|
||||
NV Nevada
|
||||
NH New Hampshire
|
||||
NJ New Jersey
|
||||
NM New Mexico
|
||||
NY New York
|
||||
NC North Carolina
|
||||
ND North Dakota
|
||||
OH Ohio
|
||||
OK Oklahoma
|
||||
OR Oregon
|
||||
PA Pennsylvania
|
||||
RI Rhode Island
|
||||
SC South Carolina
|
||||
SD South Dakota
|
||||
TN Tennessee
|
||||
TX Texas
|
||||
UT Utah
|
||||
VT Vermont
|
||||
VA Virginia
|
||||
WA Washington
|
||||
WV West Virginia
|
||||
WI Wisconsin
|
||||
WY Wyoming
|
||||
|
@@ -0,0 +1,50 @@
|
||||
AL 0.1
|
||||
AK -5.3
|
||||
AZ 3
|
||||
AR 7
|
||||
CA 11
|
||||
CO 1.5
|
||||
CT -6.7
|
||||
DE -4
|
||||
FL 9
|
||||
GA 2
|
||||
HI -3.3
|
||||
ID 6.6
|
||||
IL 7.2
|
||||
IN 7.1
|
||||
IA 6.9
|
||||
KS 6
|
||||
KY 1.8
|
||||
LA 7.5
|
||||
ME -4
|
||||
MD 0.1
|
||||
MA -6
|
||||
MI 1.7
|
||||
MN -2
|
||||
MS -4.4
|
||||
MO -2
|
||||
MT 1.0
|
||||
NE 1.2
|
||||
NV 1.6
|
||||
NH 0.5
|
||||
NJ 0.2
|
||||
NM 8.8
|
||||
NY 1.4
|
||||
NC 9.7
|
||||
ND 5.4
|
||||
OH 3.2
|
||||
OK 6
|
||||
OR -4
|
||||
PA -7
|
||||
RI -2
|
||||
SC 1
|
||||
SD 6
|
||||
TN 5
|
||||
TX -3.4
|
||||
UT 2.3
|
||||
VT 4.8
|
||||
VA 3
|
||||
WA 2.2
|
||||
WV 5.4
|
||||
WI 3.1
|
||||
WY -6
|
||||
|
@@ -0,0 +1,107 @@
|
||||
PImage mapImage;
|
||||
Table locationTable;
|
||||
Table nameTable;
|
||||
int rowCount;
|
||||
|
||||
Table dataTable;
|
||||
float dataMin = -10;
|
||||
float dataMax = 10;
|
||||
|
||||
Integrator[] interpolators;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 400);
|
||||
mapImage = loadImage("map.png");
|
||||
locationTable = new Table("locations.tsv");
|
||||
nameTable = new Table("names.tsv");
|
||||
rowCount = locationTable.getRowCount();
|
||||
|
||||
dataTable = new Table("random.tsv");
|
||||
interpolators = new Integrator[rowCount];
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float initialValue = dataTable.getFloat(row, 1);
|
||||
interpolators[row] = new Integrator(initialValue, 0.9, 0.1);
|
||||
}
|
||||
|
||||
PFont font = loadFont("Univers-Bold-12.vlw");
|
||||
textFont(font);
|
||||
|
||||
smooth();
|
||||
noStroke();
|
||||
//frameRate(30);
|
||||
}
|
||||
|
||||
float closestDist;
|
||||
String closestText;
|
||||
float closestTextX;
|
||||
float closestTextY;
|
||||
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
image(mapImage, 0, 0);
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
interpolators[row].update();
|
||||
}
|
||||
|
||||
closestDist = width*height; // abritrarily high
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
String abbrev = dataTable.getRowName(row);
|
||||
float x = locationTable.getFloat(abbrev, 1);
|
||||
float y = locationTable.getFloat(abbrev, 2);
|
||||
drawData(x, y, abbrev);
|
||||
}
|
||||
|
||||
if (closestDist != width*height) {
|
||||
fill(0);
|
||||
textAlign(CENTER);
|
||||
text(closestText, closestTextX, closestTextY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawData(float x, float y, String abbrev) {
|
||||
// Figure out what row this is
|
||||
int row = dataTable.getRowIndex(abbrev);
|
||||
// Get the current value
|
||||
float value = interpolators[row].value;
|
||||
|
||||
float radius = 0;
|
||||
if (value >= 0) {
|
||||
radius = map(value, 0, dataMax, 1.5, 15);
|
||||
fill(#333366); // blue
|
||||
} else {
|
||||
radius = map(value, 0, dataMin, 1.5, 15);
|
||||
fill(#ec5166); // red
|
||||
}
|
||||
ellipseMode(RADIUS);
|
||||
ellipse(x, y, radius, radius);
|
||||
|
||||
float d = dist(x, y, mouseX, mouseY);
|
||||
if ((d < radius + 2) && (d < closestDist)) {
|
||||
closestDist = d;
|
||||
String name = nameTable.getString(abbrev, 1);
|
||||
String val = nfp(interpolators[row].target, 0, 2);
|
||||
closestText = name + " " + val;
|
||||
closestTextX = x;
|
||||
closestTextY = y-radius-4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
updateTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateTable() {
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
float newValue = random(dataMin, dataMax);
|
||||
interpolators[row].target(newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
// first line of the file should be the column headers
|
||||
// first column should be the row titles
|
||||
// all other values are expected to be floats
|
||||
// getFloat(0, 0) returns the first data value in the upper lefthand corner
|
||||
// files should be saved as "text, tab-delimited"
|
||||
// empty rows are ignored
|
||||
// extra whitespace is ignored
|
||||
|
||||
|
||||
class FloatTable {
|
||||
int rowCount;
|
||||
int columnCount;
|
||||
float[][] data;
|
||||
String[] rowNames;
|
||||
String[] columnNames;
|
||||
|
||||
|
||||
FloatTable(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
|
||||
String[] columns = split(rows[0], TAB);
|
||||
columnNames = subset(columns, 1); // upper-left corner ignored
|
||||
scrubQuotes(columnNames);
|
||||
columnCount = columnNames.length;
|
||||
|
||||
rowNames = new String[rows.length-1];
|
||||
data = new float[rows.length-1][];
|
||||
|
||||
// start reading at row 1, because the first row was only the column headers
|
||||
for (int i = 1; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
scrubQuotes(pieces);
|
||||
|
||||
// copy row title
|
||||
rowNames[rowCount] = pieces[0];
|
||||
// copy data into the table starting at pieces[1]
|
||||
data[rowCount] = parseFloat(subset(pieces, 1));
|
||||
|
||||
// increment the number of valid rows found so far
|
||||
rowCount++;
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (float[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
void scrubQuotes(String[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i].length() > 2) {
|
||||
// remove quotes at start and end, if present
|
||||
if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
|
||||
array[i] = array[i].substring(1, array[i].length() - 1);
|
||||
}
|
||||
}
|
||||
// make double quotes into single quotes
|
||||
array[i] = array[i].replaceAll("\"\"", "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int rowIndex) {
|
||||
return rowNames[rowIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getRowNames() {
|
||||
return rowNames;
|
||||
}
|
||||
|
||||
|
||||
// Find a row by its name, returns -1 if no row found.
|
||||
// This will return the index of the first row with this name.
|
||||
// A more efficient version of this function would put row names
|
||||
// into a Hashtable (or HashMap) that would map to an integer for the row.
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (rowNames[i].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// technically, this only returns the number of columns
|
||||
// in the very first row (which will be most accurate)
|
||||
int getColumnCount() {
|
||||
return columnCount;
|
||||
}
|
||||
|
||||
|
||||
String getColumnName(int colIndex) {
|
||||
return columnNames[colIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int col) {
|
||||
// Remove the 'training wheels' section for greater efficiency
|
||||
// It's included here to provide more useful error messages
|
||||
|
||||
// begin training wheels
|
||||
if ((rowIndex < 0) || (rowIndex >= data.length)) {
|
||||
throw new RuntimeException("There is no row " + rowIndex);
|
||||
}
|
||||
if ((col < 0) || (col >= data[rowIndex].length)) {
|
||||
throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
|
||||
}
|
||||
// end training wheels
|
||||
|
||||
return data[rowIndex][col];
|
||||
}
|
||||
|
||||
|
||||
boolean isValid(int row, int col) {
|
||||
if (row < 0) return false;
|
||||
if (row >= rowCount) return false;
|
||||
//if (col >= columnCount) return false;
|
||||
if (col >= data[row].length) return false;
|
||||
if (col < 0) return false;
|
||||
return !Float.isNaN(data[row][col]);
|
||||
}
|
||||
|
||||
|
||||
float getColumnMin(int col) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getColumnMax(int col) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMin(int row) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMax(int row) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMin() {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMax() {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
Year Milk Tea Coffee
|
||||
1910 32.2 9.6 21.7
|
||||
1911 31.3 10.2 19.7
|
||||
1912 34.4 9.6 25.5
|
||||
1913 33.1 8.5 21.2
|
||||
1914 31.1 8.9 21.8
|
||||
1915 29 9.6 25
|
||||
1916 28 9.6 27.1
|
||||
1917 29.7 11.3 28.6
|
||||
1918 34 11.3 23.7
|
||||
1919 30.4 5.8 27.9
|
||||
1920 34 7.7 27.6
|
||||
1921 33.2 6.5 28.4
|
||||
1922 33.5 8 27.8
|
||||
1923 32.5 8.5 29.9
|
||||
1924 32.7 7.5 28.9
|
||||
1925 33.6 8.1 25
|
||||
1926 33.5 7.6 29.3
|
||||
1927 33.2 6.9 28.7
|
||||
1928 33.2 6.9 28.2
|
||||
1929 33.4 6.8 28.7
|
||||
1930 33.2 6.4 29.5
|
||||
1931 33.2 6.5 30.7
|
||||
1932 33.8 7.1 29.4
|
||||
1933 33.7 7.2 30.1
|
||||
1934 32.5 5.5 29.1
|
||||
1935 33 6 31.7
|
||||
1936 33.3 6 32.4
|
||||
1937 33.5 6.4 31.4
|
||||
1938 33.5 6.3 35.2
|
||||
1939 34 6.6 35.2
|
||||
1940 34 6.2 36.6
|
||||
1941 34.4 7.3 38
|
||||
1942 37 5.2 36.2
|
||||
1943 41 5.7 33.1
|
||||
1944 43.6 5.1 41.8
|
||||
1945 44.7 5.2 44.4
|
||||
1946 42.1 5.2 46.4
|
||||
1947 39.9 5.4 40.8
|
||||
1948 38.1 5.4 43.5
|
||||
1949 37.5 5.7 45.1
|
||||
1950 37.2 5.7 38.6
|
||||
1951 37.5 6.1 39.5
|
||||
1952 37.6 5.9 38
|
||||
1953 37 6.2 37.3
|
||||
1954 36.2 6.4 30.5
|
||||
1955 36.2 6 32
|
||||
1956 36.3 5.9 31.6
|
||||
1957 35.9 5.5 30.6
|
||||
1958 35.2 5.5 30.4
|
||||
1959 34.4 5.5 30.9
|
||||
1960 33.9 5.6 30.7
|
||||
1961 33 5.8 31
|
||||
1962 32.9 6 31
|
||||
1963 33 6.2 30.8
|
||||
1964 33 6.3 30.5
|
||||
1965 32.9 6.4 29.4
|
||||
1966 33 6.5 28.9
|
||||
1967 31.4 6.6 29
|
||||
1968 31.3 6.8 29.1
|
||||
1969 31.1 6.8 27.6
|
||||
1970 31.3 6.8 27.4
|
||||
1971 31.3 7.2 25.7
|
||||
1972 31 7.3 26.8
|
||||
1973 30.5 7.4 25.8
|
||||
1974 29.5 7.5 24.2
|
||||
1975 29.5 7.5 23.3
|
||||
1976 29.3 7.7 23.7
|
||||
1977 29 7.5 17.2
|
||||
1978 28.6 7.2 19.9
|
||||
1979 28.2 6.9 21.7
|
||||
1980 27.6 7.3 19.2
|
||||
1981 27.1 7.2 18.7
|
||||
1982 26.4 6.9 18.3
|
||||
1983 26.3 7 18.5
|
||||
1984 26.4 7.1 18.9
|
||||
1985 26.7 7.1 19.3
|
||||
1986 26.5 7.1 19.4
|
||||
1987 26.1 6.9 18.8
|
||||
1988 26.1 7 18.2
|
||||
1989 26 6.9 18.8
|
||||
1990 25.7 6.9 19.4
|
||||
1991 25.5 7.4 19.5
|
||||
1992 25.1 8 18.9
|
||||
1993 24.4 8.3 17.2
|
||||
1994 24.3 8.1 15.6
|
||||
1995 23.9 7.9 15.3
|
||||
1996 23.8 7.6 16.8
|
||||
1997 23.4 7.2 17.9
|
||||
1998 23 8.3 18.3
|
||||
1999 22.9 8.2 19.3
|
||||
2000 22.5 7.8 20
|
||||
2001 22 8.2 18.5
|
||||
2002 21.9 7.8 18.1
|
||||
2003 21.6 7.5 18.5
|
||||
2004 21.2 7.3 18.8
|
||||
|
@@ -0,0 +1,60 @@
|
||||
FloatTable data;
|
||||
float dataMin, dataMax;
|
||||
|
||||
float plotX1, plotY1;
|
||||
float plotX2, plotY2;
|
||||
|
||||
int yearMin, yearMax;
|
||||
int[] years;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(720, 405);
|
||||
|
||||
data = new FloatTable("milk-tea-coffee.tsv");
|
||||
|
||||
years = int(data.getRowNames());
|
||||
yearMin = years[0];
|
||||
yearMax = years[years.length - 1];
|
||||
|
||||
dataMin = 0;
|
||||
dataMax = data.getTableMax();
|
||||
|
||||
// Corners of the plotted time series
|
||||
plotX1 = 50;
|
||||
plotX2 = width - plotX1;
|
||||
plotY1 = 60;
|
||||
plotY2 = height - plotY1;
|
||||
|
||||
smooth();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(224);
|
||||
|
||||
// Show the plot area as a white box
|
||||
fill(255);
|
||||
rectMode(CORNERS);
|
||||
noStroke();
|
||||
rect(plotX1, plotY1, plotX2, plotY2);
|
||||
|
||||
strokeWeight(5);
|
||||
// Draw the data for the first column
|
||||
stroke(#5679C1);
|
||||
drawDataPoints(0);
|
||||
}
|
||||
|
||||
|
||||
// Draw the data as a series of points
|
||||
void drawDataPoints(int col) {
|
||||
int rowCount = data.getRowCount();
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (data.isValid(row, col)) {
|
||||
float value = data.getFloat(row, col);
|
||||
float x = map(years[row], yearMin, yearMax, plotX1, plotX2);
|
||||
float y = map(value, dataMin, dataMax, plotY2, plotY1);
|
||||
point(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
// first line of the file should be the column headers
|
||||
// first column should be the row titles
|
||||
// all other values are expected to be floats
|
||||
// getFloat(0, 0) returns the first data value in the upper lefthand corner
|
||||
// files should be saved as "text, tab-delimited"
|
||||
// empty rows are ignored
|
||||
// extra whitespace is ignored
|
||||
|
||||
|
||||
class FloatTable {
|
||||
int rowCount;
|
||||
int columnCount;
|
||||
float[][] data;
|
||||
String[] rowNames;
|
||||
String[] columnNames;
|
||||
|
||||
|
||||
FloatTable(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
|
||||
String[] columns = split(rows[0], TAB);
|
||||
columnNames = subset(columns, 1); // upper-left corner ignored
|
||||
scrubQuotes(columnNames);
|
||||
columnCount = columnNames.length;
|
||||
|
||||
rowNames = new String[rows.length-1];
|
||||
data = new float[rows.length-1][];
|
||||
|
||||
// start reading at row 1, because the first row was only the column headers
|
||||
for (int i = 1; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
scrubQuotes(pieces);
|
||||
|
||||
// copy row title
|
||||
rowNames[rowCount] = pieces[0];
|
||||
// copy data into the table starting at pieces[1]
|
||||
data[rowCount] = parseFloat(subset(pieces, 1));
|
||||
|
||||
// increment the number of valid rows found so far
|
||||
rowCount++;
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (float[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
void scrubQuotes(String[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i].length() > 2) {
|
||||
// remove quotes at start and end, if present
|
||||
if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
|
||||
array[i] = array[i].substring(1, array[i].length() - 1);
|
||||
}
|
||||
}
|
||||
// make double quotes into single quotes
|
||||
array[i] = array[i].replaceAll("\"\"", "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int rowIndex) {
|
||||
return rowNames[rowIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getRowNames() {
|
||||
return rowNames;
|
||||
}
|
||||
|
||||
|
||||
// Find a row by its name, returns -1 if no row found.
|
||||
// This will return the index of the first row with this name.
|
||||
// A more efficient version of this function would put row names
|
||||
// into a Hashtable (or HashMap) that would map to an integer for the row.
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (rowNames[i].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// technically, this only returns the number of columns
|
||||
// in the very first row (which will be most accurate)
|
||||
int getColumnCount() {
|
||||
return columnCount;
|
||||
}
|
||||
|
||||
|
||||
String getColumnName(int colIndex) {
|
||||
return columnNames[colIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int col) {
|
||||
// Remove the 'training wheels' section for greater efficiency
|
||||
// It's included here to provide more useful error messages
|
||||
|
||||
// begin training wheels
|
||||
if ((rowIndex < 0) || (rowIndex >= data.length)) {
|
||||
throw new RuntimeException("There is no row " + rowIndex);
|
||||
}
|
||||
if ((col < 0) || (col >= data[rowIndex].length)) {
|
||||
throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
|
||||
}
|
||||
// end training wheels
|
||||
|
||||
return data[rowIndex][col];
|
||||
}
|
||||
|
||||
|
||||
boolean isValid(int row, int col) {
|
||||
if (row < 0) return false;
|
||||
if (row >= rowCount) return false;
|
||||
//if (col >= columnCount) return false;
|
||||
if (col >= data[row].length) return false;
|
||||
if (col < 0) return false;
|
||||
return !Float.isNaN(data[row][col]);
|
||||
}
|
||||
|
||||
|
||||
float getColumnMin(int col) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getColumnMax(int col) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMin(int row) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMax(int row) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMin() {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMax() {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
Year Milk Tea Coffee
|
||||
1910 32.2 9.6 21.7
|
||||
1911 31.3 10.2 19.7
|
||||
1912 34.4 9.6 25.5
|
||||
1913 33.1 8.5 21.2
|
||||
1914 31.1 8.9 21.8
|
||||
1915 29 9.6 25
|
||||
1916 28 9.6 27.1
|
||||
1917 29.7 11.3 28.6
|
||||
1918 34 11.3 23.7
|
||||
1919 30.4 5.8 27.9
|
||||
1920 34 7.7 27.6
|
||||
1921 33.2 6.5 28.4
|
||||
1922 33.5 8 27.8
|
||||
1923 32.5 8.5 29.9
|
||||
1924 32.7 7.5 28.9
|
||||
1925 33.6 8.1 25
|
||||
1926 33.5 7.6 29.3
|
||||
1927 33.2 6.9 28.7
|
||||
1928 33.2 6.9 28.2
|
||||
1929 33.4 6.8 28.7
|
||||
1930 33.2 6.4 29.5
|
||||
1931 33.2 6.5 30.7
|
||||
1932 33.8 7.1 29.4
|
||||
1933 33.7 7.2 30.1
|
||||
1934 32.5 5.5 29.1
|
||||
1935 33 6 31.7
|
||||
1936 33.3 6 32.4
|
||||
1937 33.5 6.4 31.4
|
||||
1938 33.5 6.3 35.2
|
||||
1939 34 6.6 35.2
|
||||
1940 34 6.2 36.6
|
||||
1941 34.4 7.3 38
|
||||
1942 37 5.2 36.2
|
||||
1943 41 5.7 33.1
|
||||
1944 43.6 5.1 41.8
|
||||
1945 44.7 5.2 44.4
|
||||
1946 42.1 5.2 46.4
|
||||
1947 39.9 5.4 40.8
|
||||
1948 38.1 5.4 43.5
|
||||
1949 37.5 5.7 45.1
|
||||
1950 37.2 5.7 38.6
|
||||
1951 37.5 6.1 39.5
|
||||
1952 37.6 5.9 38
|
||||
1953 37 6.2 37.3
|
||||
1954 36.2 6.4 30.5
|
||||
1955 36.2 6 32
|
||||
1956 36.3 5.9 31.6
|
||||
1957 35.9 5.5 30.6
|
||||
1958 35.2 5.5 30.4
|
||||
1959 34.4 5.5 30.9
|
||||
1960 33.9 5.6 30.7
|
||||
1961 33 5.8 31
|
||||
1962 32.9 6 31
|
||||
1963 33 6.2 30.8
|
||||
1964 33 6.3 30.5
|
||||
1965 32.9 6.4 29.4
|
||||
1966 33 6.5 28.9
|
||||
1967 31.4 6.6 29
|
||||
1968 31.3 6.8 29.1
|
||||
1969 31.1 6.8 27.6
|
||||
1970 31.3 6.8 27.4
|
||||
1971 31.3 7.2 25.7
|
||||
1972 31 7.3 26.8
|
||||
1973 30.5 7.4 25.8
|
||||
1974 29.5 7.5 24.2
|
||||
1975 29.5 7.5 23.3
|
||||
1976 29.3 7.7 23.7
|
||||
1977 29 7.5 17.2
|
||||
1978 28.6 7.2 19.9
|
||||
1979 28.2 6.9 21.7
|
||||
1980 27.6 7.3 19.2
|
||||
1981 27.1 7.2 18.7
|
||||
1982 26.4 6.9 18.3
|
||||
1983 26.3 7 18.5
|
||||
1984 26.4 7.1 18.9
|
||||
1985 26.7 7.1 19.3
|
||||
1986 26.5 7.1 19.4
|
||||
1987 26.1 6.9 18.8
|
||||
1988 26.1 7 18.2
|
||||
1989 26 6.9 18.8
|
||||
1990 25.7 6.9 19.4
|
||||
1991 25.5 7.4 19.5
|
||||
1992 25.1 8 18.9
|
||||
1993 24.4 8.3 17.2
|
||||
1994 24.3 8.1 15.6
|
||||
1995 23.9 7.9 15.3
|
||||
1996 23.8 7.6 16.8
|
||||
1997 23.4 7.2 17.9
|
||||
1998 23 8.3 18.3
|
||||
1999 22.9 8.2 19.3
|
||||
2000 22.5 7.8 20
|
||||
2001 22 8.2 18.5
|
||||
2002 21.9 7.8 18.1
|
||||
2003 21.6 7.5 18.5
|
||||
2004 21.2 7.3 18.8
|
||||
|
@@ -0,0 +1,74 @@
|
||||
FloatTable data;
|
||||
float dataMin, dataMax;
|
||||
|
||||
float plotX1, plotY1;
|
||||
float plotX2, plotY2;
|
||||
|
||||
int currentColumn = 0;
|
||||
int columnCount;
|
||||
|
||||
int yearMin, yearMax;
|
||||
int[] years;
|
||||
|
||||
PFont plotFont;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(720, 405);
|
||||
|
||||
data = new FloatTable("milk-tea-coffee.tsv");
|
||||
columnCount = data.getColumnCount();
|
||||
|
||||
years = int(data.getRowNames());
|
||||
yearMin = years[0];
|
||||
yearMax = years[years.length - 1];
|
||||
|
||||
dataMin = 0;
|
||||
dataMax = data.getTableMax();
|
||||
|
||||
// Corners of the plotted time series
|
||||
plotX1 = 50;
|
||||
plotX2 = width - plotX1;
|
||||
plotY1 = 60;
|
||||
plotY2 = height - plotY1;
|
||||
|
||||
plotFont = createFont("SansSerif", 20);
|
||||
textFont(plotFont);
|
||||
|
||||
smooth();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(224);
|
||||
|
||||
// Show the plot area as a white box
|
||||
fill(255);
|
||||
rectMode(CORNERS);
|
||||
noStroke();
|
||||
rect(plotX1, plotY1, plotX2, plotY2);
|
||||
|
||||
// Draw the title of the current plot
|
||||
fill(0);
|
||||
textSize(20);
|
||||
String title = data.getColumnName(currentColumn);
|
||||
text(title, plotX1, plotY1 - 10);
|
||||
|
||||
stroke(#5679C1);
|
||||
strokeWeight(5);
|
||||
drawDataPoints(currentColumn);
|
||||
}
|
||||
|
||||
|
||||
// Draw the data as a series of points
|
||||
void drawDataPoints(int col) {
|
||||
int rowCount = data.getRowCount();
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (data.isValid(row, col)) {
|
||||
float value = data.getFloat(row, col);
|
||||
float x = map(years[row], yearMin, yearMax, plotX1, plotX2);
|
||||
float y = map(value, dataMin, dataMax, plotY2, plotY1);
|
||||
point(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
// first line of the file should be the column headers
|
||||
// first column should be the row titles
|
||||
// all other values are expected to be floats
|
||||
// getFloat(0, 0) returns the first data value in the upper lefthand corner
|
||||
// files should be saved as "text, tab-delimited"
|
||||
// empty rows are ignored
|
||||
// extra whitespace is ignored
|
||||
|
||||
|
||||
class FloatTable {
|
||||
int rowCount;
|
||||
int columnCount;
|
||||
float[][] data;
|
||||
String[] rowNames;
|
||||
String[] columnNames;
|
||||
|
||||
|
||||
FloatTable(String filename) {
|
||||
String[] rows = loadStrings(filename);
|
||||
|
||||
String[] columns = split(rows[0], TAB);
|
||||
columnNames = subset(columns, 1); // upper-left corner ignored
|
||||
scrubQuotes(columnNames);
|
||||
columnCount = columnNames.length;
|
||||
|
||||
rowNames = new String[rows.length-1];
|
||||
data = new float[rows.length-1][];
|
||||
|
||||
// start reading at row 1, because the first row was only the column headers
|
||||
for (int i = 1; i < rows.length; i++) {
|
||||
if (trim(rows[i]).length() == 0) {
|
||||
continue; // skip empty rows
|
||||
}
|
||||
if (rows[i].startsWith("#")) {
|
||||
continue; // skip comment lines
|
||||
}
|
||||
|
||||
// split the row on the tabs
|
||||
String[] pieces = split(rows[i], TAB);
|
||||
scrubQuotes(pieces);
|
||||
|
||||
// copy row title
|
||||
rowNames[rowCount] = pieces[0];
|
||||
// copy data into the table starting at pieces[1]
|
||||
data[rowCount] = parseFloat(subset(pieces, 1));
|
||||
|
||||
// increment the number of valid rows found so far
|
||||
rowCount++;
|
||||
}
|
||||
// resize the 'data' array as necessary
|
||||
data = (float[][]) subset(data, 0, rowCount);
|
||||
}
|
||||
|
||||
|
||||
void scrubQuotes(String[] array) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i].length() > 2) {
|
||||
// remove quotes at start and end, if present
|
||||
if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
|
||||
array[i] = array[i].substring(1, array[i].length() - 1);
|
||||
}
|
||||
}
|
||||
// make double quotes into single quotes
|
||||
array[i] = array[i].replaceAll("\"\"", "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
|
||||
String getRowName(int rowIndex) {
|
||||
return rowNames[rowIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getRowNames() {
|
||||
return rowNames;
|
||||
}
|
||||
|
||||
|
||||
// Find a row by its name, returns -1 if no row found.
|
||||
// This will return the index of the first row with this name.
|
||||
// A more efficient version of this function would put row names
|
||||
// into a Hashtable (or HashMap) that would map to an integer for the row.
|
||||
int getRowIndex(String name) {
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
if (rowNames[i].equals(name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//println("No row named '" + name + "' was found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// technically, this only returns the number of columns
|
||||
// in the very first row (which will be most accurate)
|
||||
int getColumnCount() {
|
||||
return columnCount;
|
||||
}
|
||||
|
||||
|
||||
String getColumnName(int colIndex) {
|
||||
return columnNames[colIndex];
|
||||
}
|
||||
|
||||
|
||||
String[] getColumnNames() {
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
|
||||
float getFloat(int rowIndex, int col) {
|
||||
// Remove the 'training wheels' section for greater efficiency
|
||||
// It's included here to provide more useful error messages
|
||||
|
||||
// begin training wheels
|
||||
if ((rowIndex < 0) || (rowIndex >= data.length)) {
|
||||
throw new RuntimeException("There is no row " + rowIndex);
|
||||
}
|
||||
if ((col < 0) || (col >= data[rowIndex].length)) {
|
||||
throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
|
||||
}
|
||||
// end training wheels
|
||||
|
||||
return data[rowIndex][col];
|
||||
}
|
||||
|
||||
|
||||
boolean isValid(int row, int col) {
|
||||
if (row < 0) return false;
|
||||
if (row >= rowCount) return false;
|
||||
//if (col >= columnCount) return false;
|
||||
if (col >= data[row].length) return false;
|
||||
if (col < 0) return false;
|
||||
return !Float.isNaN(data[row][col]);
|
||||
}
|
||||
|
||||
|
||||
float getColumnMin(int col) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getColumnMax(int col) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMin(int row) {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getRowMax(int row) {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMin() {
|
||||
float m = Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] < m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
float getTableMax() {
|
||||
float m = -Float.MAX_VALUE;
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
if (isValid(row, col)) {
|
||||
if (data[row][col] > m) {
|
||||
m = data[row][col];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
Year Milk Tea Coffee
|
||||
1910 32.2 9.6 21.7
|
||||
1911 31.3 10.2 19.7
|
||||
1912 34.4 9.6 25.5
|
||||
1913 33.1 8.5 21.2
|
||||
1914 31.1 8.9 21.8
|
||||
1915 29 9.6 25
|
||||
1916 28 9.6 27.1
|
||||
1917 29.7 11.3 28.6
|
||||
1918 34 11.3 23.7
|
||||
1919 30.4 5.8 27.9
|
||||
1920 34 7.7 27.6
|
||||
1921 33.2 6.5 28.4
|
||||
1922 33.5 8 27.8
|
||||
1923 32.5 8.5 29.9
|
||||
1924 32.7 7.5 28.9
|
||||
1925 33.6 8.1 25
|
||||
1926 33.5 7.6 29.3
|
||||
1927 33.2 6.9 28.7
|
||||
1928 33.2 6.9 28.2
|
||||
1929 33.4 6.8 28.7
|
||||
1930 33.2 6.4 29.5
|
||||
1931 33.2 6.5 30.7
|
||||
1932 33.8 7.1 29.4
|
||||
1933 33.7 7.2 30.1
|
||||
1934 32.5 5.5 29.1
|
||||
1935 33 6 31.7
|
||||
1936 33.3 6 32.4
|
||||
1937 33.5 6.4 31.4
|
||||
1938 33.5 6.3 35.2
|
||||
1939 34 6.6 35.2
|
||||
1940 34 6.2 36.6
|
||||
1941 34.4 7.3 38
|
||||
1942 37 5.2 36.2
|
||||
1943 41 5.7 33.1
|
||||
1944 43.6 5.1 41.8
|
||||
1945 44.7 5.2 44.4
|
||||
1946 42.1 5.2 46.4
|
||||
1947 39.9 5.4 40.8
|
||||
1948 38.1 5.4 43.5
|
||||
1949 37.5 5.7 45.1
|
||||
1950 37.2 5.7 38.6
|
||||
1951 37.5 6.1 39.5
|
||||
1952 37.6 5.9 38
|
||||
1953 37 6.2 37.3
|
||||
1954 36.2 6.4 30.5
|
||||
1955 36.2 6 32
|
||||
1956 36.3 5.9 31.6
|
||||
1957 35.9 5.5 30.6
|
||||
1958 35.2 5.5 30.4
|
||||
1959 34.4 5.5 30.9
|
||||
1960 33.9 5.6 30.7
|
||||
1961 33 5.8 31
|
||||
1962 32.9 6 31
|
||||
1963 33 6.2 30.8
|
||||
1964 33 6.3 30.5
|
||||
1965 32.9 6.4 29.4
|
||||
1966 33 6.5 28.9
|
||||
1967 31.4 6.6 29
|
||||
1968 31.3 6.8 29.1
|
||||
1969 31.1 6.8 27.6
|
||||
1970 31.3 6.8 27.4
|
||||
1971 31.3 7.2 25.7
|
||||
1972 31 7.3 26.8
|
||||
1973 30.5 7.4 25.8
|
||||
1974 29.5 7.5 24.2
|
||||
1975 29.5 7.5 23.3
|
||||
1976 29.3 7.7 23.7
|
||||
1977 29 7.5 17.2
|
||||
1978 28.6 7.2 19.9
|
||||
1979 28.2 6.9 21.7
|
||||
1980 27.6 7.3 19.2
|
||||
1981 27.1 7.2 18.7
|
||||
1982 26.4 6.9 18.3
|
||||
1983 26.3 7 18.5
|
||||
1984 26.4 7.1 18.9
|
||||
1985 26.7 7.1 19.3
|
||||
1986 26.5 7.1 19.4
|
||||
1987 26.1 6.9 18.8
|
||||
1988 26.1 7 18.2
|
||||
1989 26 6.9 18.8
|
||||
1990 25.7 6.9 19.4
|
||||
1991 25.5 7.4 19.5
|
||||
1992 25.1 8 18.9
|
||||
1993 24.4 8.3 17.2
|
||||
1994 24.3 8.1 15.6
|
||||
1995 23.9 7.9 15.3
|
||||
1996 23.8 7.6 16.8
|
||||
1997 23.4 7.2 17.9
|
||||
1998 23 8.3 18.3
|
||||
1999 22.9 8.2 19.3
|
||||
2000 22.5 7.8 20
|
||||
2001 22 8.2 18.5
|
||||
2002 21.9 7.8 18.1
|
||||
2003 21.6 7.5 18.5
|
||||
2004 21.2 7.3 18.8
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user