Loading data / Constructor problem

Hi Everyone,

I am learning processing with Daniel @shiffman Book (learning processing + Youtube video) and got stuck at exercise 18-7 (Data input from text files). I can’t find the solution online, that is why i am asking for help here.

Here is my problem. I have a data.txt file with three different lines

BOB,40,100,50,90,180,150,122.5,130
PENELOPE,78,159,30,90,180,98,67.5,189
JANE,89,98,162,73,241,23,116.5,91

I want to create a sketch to visualizes the data with the following layout for each lines

I managed coding this for one line but when i am turning my code in a object oriented version, my constructor doesn’t work and i am not sure to do the right thing anymore…

Board[] boards;

//Variables data
String [] values;
float [] score;


void setup(){
  size(400,250);
  
  String [] player = loadStrings("data.txt");
  boards = new Board[player.length];
  
  float x = 0;
  float w = width / boards.length;
  
  for (int i = 0; i < boards.length; i++){
      
    values = split(player[i],",");
    score = float(split (player[i],","));
    
    for (int j = 0; j < score.length; j++){
    
    float[]score2 = subset(score,1);
    float l = w /score2[j];
    
    boards = new Board(values[0],score2[j],l,w);
    x += w;
    }
  }
}

void draw(){
  
  background(255);
  for (int i = 0; i < boards.length; i++){
    boards.title();
    boards.pourcentage();
  }
  noLoop();
}

class Board{
  //float total;
  //float avg;
  String headline1;
  float score1;
  float l1;
  float w1;
  float x1;
  
  PFont f;
  
  Board (String _headline1, float _score1, float _l1, float _w1){
    headline1 = _headline1;
    score1  = _score1;
    l1 = _l1;
    w1 = _w1;
    x1 = 0;
    f = createFont ("Arial",32,false);
  }
  
  void title(){
    pushMatrix();
    fill(100,100);
    translate (w1/2,40);
    textFont(f);
    textAlign(CENTER);
    text(headline1,0,0);
    popMatrix();
  }
  
  void pourcentage(){
    stroke(255,200);
    strokeWeight(2);
    fill(100,100);    
    rect(x1,height,l1,-score1);
    x1 += w1;
   }  
 }

Can someone help me please?

Thank you,

Rémy

1 Like

pls. give link to video , code source…

some things could be more easy with
https://processing.org/reference/loadTable_.html

Table table;

void setup() {
  
  table = loadTable("data.txt", "csv");

for a unknown content better start with

Table table;
int i, k, trows, tcols;

void setup() {

  table = loadTable("test.csv", "tsv");  // "test.tsv" // "test.csv" , "tsv" // "test.dat" , "header , csv"
  trows=table.getRowCount();
  tcols=table.getColumnCount();

  println(trows + " rows/lines in table "); //(? - header ?)
  println(tcols + " cols in table");
  println("header: ");
  for ( i =0; i < tcols; i++) {
    println("col: "+i+" "+ table.getColumnTitle(i));
  }

  for ( k =0; k < trows; k++) {
    for ( i =0; i < tcols; i++) {
      println("row: "+k+" col: "+i+" string: "+table.getString(k, i));
    }
  }
}

with this table ( string ) and usage of

table.getFloat(k, i)

there is no need for more string or float arrays.

// ____________
for your Boards class

float _score1

should be the row array of data, not one single value.

and actually a tablerow works fine ( instead of a String array of one line )
my version:


Table table;
int i, k, trows, tcols;

float rwidth=0; //(width-40)/tcols;
float rhighrange = 0;
int max;

boolean dprint = true;   // print first calc only

My_graph[] charts;

void setup() {
  size(500, 500);
  background(100, 100, 0);
  check_table();
  get_ranges();
  charts = new My_graph[trows];
  for ( k =0; k < trows; k++) {
    charts[k] = new My_graph(table.getRow(k), 10, 20+k*(130+5), width-20 , 130, 0, max); //
    charts[k].draw();
  }
}

// tools: get the data and check for columns, rows, and data range

void check_table() {
  table = loadTable("data.txt", "csv");  // "test.tsv" // "test.txt" , "tsv" // "test.dat" , "header , csv"
  trows=table.getRowCount();
  tcols=table.getColumnCount();

  if (dprint) println(trows + " rows/lines in table "); //(? - header ?)
  if (dprint) println(tcols + " cols in table");
  if (dprint) println("header: ");
  for ( i =0; i < tcols; i++) {
    if (dprint) println("col: "+i+" "+ table.getColumnTitle(i));
  }

  for ( k =0; k < trows; k++) {
    for ( i =0; i < tcols; i++) {
      if (dprint) println("row: "+k+" col: "+i+" string: "+table.getString(k, i));
    }
    if (dprint) println(" ");
  }
}


void get_ranges() {
  rwidth=(width-40)/(tcols);
  for ( k =0; k < trows; k++) {
    for ( i =1; i < tcols; i++) {
      float getfnum = table.getFloat(k, i);
      if ( getfnum > rhighrange ) rhighrange = getfnum;
    }
  }
  max = ceil(rhighrange/100.0); // need a loop for 10 100 1000
  max = max*100;
  if (dprint) println("highest value: "+rhighrange+" max "+max+" rwidth "+rwidth);
}

class My_graph {
  TableRow data; 
  int posX, posY, wX, hY; 
  float nullr, highr;
  PFont f;
  float local_rwidth;
  
  // expect data = {"name","1","2","3","4","5.66","6"...}
  My_graph(TableRow _data, int _posX, int _posY, int _wX, int _hY, float _nullr, float _highr) {  
    data = _data; 
    posX = _posX; 
    posY = _posY; 
    wX = _wX; 
    hY = _hY; 
    nullr = _nullr; 
    highr = _highr;

    f = createFont ("Arial", 32, false);
    
    local_rwidth = (wX-20)/tcols;
  }

  void draw() {
    // background and header
    pushMatrix();
    translate (posX, posY); 
    fill(200, 200, 0);
    rect(1, 1, wX-1, hY-1);
    // print NAME
    fill(255);
    textFont(f, 20);
    textAlign(CENTER);
    text(data.getString(0), wX/2, 20);
    textFont(f, 10);
    // print range
    text(nf(nullr, 1, 1), 30, 25 + 100 );
    text(nf(highr, 1, 1), 30, 25);
    // make graph bars
    color cbar = color(random(50,255),random(50,255),random(50,255));
    for ( i =1; i < tcols; i++) {
      float getfnum = data.getFloat(i);
      float bar = map(getfnum/(-nullr+highr), 0, 1.0, 0, hY-25);
      fill(cbar);
      rect(i*(local_rwidth+2), 25, local_rwidth-1, 100);
      fill(0);
      rect(i*(local_rwidth+2), 25, local_rwidth-1, 100-bar);
      // print vals
      fill(255);
      text(nf(getfnum, 1, 1), i*(local_rwidth+2)+20, 35);
    }

    popMatrix();
  }
}


//______________ UNUSED _____________ OLD ( not Class ) WAY

//void draw() {
  //background(100, 100, 0);
  //graph_rows();
//}


void graph_rows() {
  for ( k =0; k < trows; k++) {
    graph_row(k);
  }
}


void graph_row(int k) {
  text("0", 30, 40 + 100 );
  text(max, 30, 40);
  text(table.getString(k, 0), width/2, 30 + k*130);
  for ( i =1; i < tcols; i++) {
    float getfnum = table.getFloat(k, i);
    float bar = map(getfnum/max, 0.0, 1.0, 0, 100);
    fill(0, 200, 0);
    rect(i*(rwidth+2), 40+ k*130, rwidth-1, 100);
    fill(0);
    rect(i*(rwidth+2), 40+ k*130, rwidth-1, 100-bar);
    fill(255);
    text(nf(getfnum, 1, 1), i*(rwidth+2)+10, 50+ k*130);
    if (dprint) println("k "+k+" i "+i+" val "+getfnum+" bar "+nf(bar, 1, 1));
  }
  dprint = false;
}


so actually what is the difference between the class and the old function
( i leave the OLD CODE at the end )
in that case?
the class contains a row data copy,
and is just used once for printing.
so the class array holds a copy of all data
and is actually UNUSED, and from this view unnecessary.

but was a good exercise for me.

2 Likes

Hi @kll

Thank you for the helping hand.

Best,

Rémy

If after working through the intro exercises you are still interested in rendering bar chart data, you may might to look into using the grafica library: https://jagracar.com/sketches/multiplePlots.php

1 Like