// 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;
}
}
//Timo van Tilburg
FloatTable data;
float dataMin, dataMax;
float plotX1, plotY1;
float plotX2, plotY2;
float labelX, labelY;
int rowCount;
int columnCount;
int currentColumn = 0;
int yearMin, yearMax;
int[] years;
int yearInterval = 10;
int volumeInterval = 50;
int volumeIntervalMinor = 5;
PImage mapImage;// achtergrond
PFont plotFont;
void setup() {
size(720, 405);
data = new FloatTable("elftal.tsv");
rowCount = data.getRowCount();
columnCount = data.getColumnCount();
years = int(data.getRowNames());
yearMin = years[0];
yearMax = years[years.length - 1];
dataMin = 0;
dataMax = ceil(data.getTableMax() / volumeInterval) * volumeInterval;
plotX1 = 120;
plotX2 = width - 80;
labelX = 50;
plotY1 = 60;
plotY2 = height - 70;
labelY = height - 25;
mapImage = loadImage("shirt.png");
plotFont = createFont("SansSerif", 20);
textFont(plotFont);
smooth();
}
void draw() {
background(#FFFFFF);
// Show the plot area as a white box
fill(#ff9c00);//oranje
//rectMode(CORNERS);
noStroke();
rect(plotX1, plotY1, plotX2, plotY2);
drawTitle();
drawAxisLabels();
drawYearLabels();
drawVolumeLabels();
stroke(#5679C1);
strokeWeight(5);
drawDataPoints(currentColumn);
image(mapImage, 10,60);// achtergrondplaatje
//lijn1
stroke(#ffffff);
strokeWeight(1);
line(720, 115, 120, 115);
line(720, 170, 120, 170);
line(720, 225, 120, 225);
line(720, 280, 120, 280);
line(720, 335, 120, 335);
}
void drawTitle() {
fill(0);
textSize(20);
textAlign(LEFT);
String title = data.getColumnName(currentColumn);
text(title, plotX1, plotY1 - 10);
}
void drawAxisLabels() {
fill(0);
textSize(13);
textLeading(15);
textAlign(CENTER, CENTER);
text("Doelpunten", labelX, (plotY1+plotY2)/2);
textAlign(CENTER);
}
//namen
void drawYearLabels() {
fill(0);
textSize(10);
textAlign(CENTER, TOP);
stroke(224);
strokeWeight(10);
text("Patrick\nKluivert", 140, 340);
text("Dennis\nBergkamp", 198, 340);
text("Faas\nWilkes", 256, 340);
text("Abe\nLenstra", 314, 340);
text("Johan\nCruijff", 372, 340);
text("Ruud\nvan\nNistelrooy", 430, 340);
text("Beb\nBakhuysp", 488, 340);
text("Kick\nSmit", 546, 340);
text("Marco\nvan\nBasten", 604, 340);
text(" Leen\nVente", 662, 340);
}
void drawVolumeLabels() {
fill(0);
textSize(10);
stroke(128);
strokeWeight(1);
for (float v = dataMin; v <= dataMax; v += volumeIntervalMinor) {
if (v % volumeIntervalMinor == 0) { // If a tick mark
float y = map(v, dataMin, dataMax, plotY2, plotY1);
if (v % volumeInterval == 0) { // If a major tick mark
if (v == dataMin) {
textAlign(RIGHT); // Align by the bottom
} else if (v == dataMax) {
textAlign(RIGHT, TOP); // Align by the top
} else {
textAlign(RIGHT, CENTER); // Center vertically
}
text(floor(v), plotX1 - 10, y);
line(plotX1 - 4, y, plotX1, y); // Draw major tick
} else {
// Commented out, too distracting visually
line(plotX1 - 2, y, plotX1, y); // Draw minor tick
}
}
}
}
void drawDataPoints(int col) {
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);
}
}
}
void keyPressed() {
if (key == '[') {
currentColumn--;
if (currentColumn < 0) {
currentColumn = columnCount - 1;
}
} else if (key == ']') {
currentColumn++;
if (currentColumn == columnCount) {
currentColumn = 0;
}
}
}
Topscorers aller tijden Nederlands Elftal | opdracht 1