Data Visualization (biomass)

I am having trouble getting my visualization to apply to my code. I want to have gray scale bars going across the window in accordance to the data file being called. I cannot give the data file, but hopefully someone can look at the lines in void display below and tell me if there is anything glaring. There are 110 rows of data. Thanks in advance.

// parseFile2
/** 
Load a csv file into an array of strings <br>
Construct data objects out of each line and store in array
*/
String[] data;
Item[] items;
int y = 300;
int x = 15;


void setup() {
  //standard setup
  size(1000,500);
  background(0);

  // Load data from a file as array of strings
  data = loadStrings("biomass.csv");
  //create object array
  items = new Item[data.length];
  //fill object array
  for (int i=0; i<data.length; i++) {
    //split each line into pieces on ","
    String[] pieces = data[i].split(",");
    //trim - doesnt really change anything from what I can see
    trim(pieces[1]);
    // start
    items[i] = new Item(pieces[0], int(pieces[1]));
  }

  for (int i=0; i<items.length; i++) {
    println(items[i]);
  }


}

class Item {  
  String country;  // Country name
  int tons;         // biomass in tons
  //double score;

  // constructor splits on "," and puts pieces into data fields
  Item(String country, int tons) {
    this.country = country;
    this.tons = tons;
    //this.score = score;
  }

  String toString() {
    String msg = "In " + country;
     msg += " there is a biomass of " + tons + " tons";
    return(msg);
  }

  void display() {
    //graphing
  stroke(0);
  strokeWeight(1);
  for (int i=0; i<items.length; i++) {
   fill((int)items[i].tons/110);
   pushMatrix();
   translate(x*i, y);
   rect(0.0,0.0,(float)x, (float)-items[i].tons);
   println(items[i].tons);
   popMatrix();
  }

  }
}

Answers

  • edited May 2016

    First: where's your draw() function?

    The class Item is one data set, right? Then you shouldn't loop over the entire array inside the class, it defies the logic / the idea of a class.

    Instead take the entire function display out of the class and rename it draw()

    A function/ method display in the class

    • a) needs to be called from draw

    • b) only displays the item in the class line 61 to 66 only without items[i]. Because tons is known in the class

    That is the idea of class: look at one item but it then works for all items (like a good cookie maker (the class) makes good cookies / objects (the items in the array items))

  • Thanks guys I will work on it. My professor said she wanted me to use a class, ut I figured out a way to get a few things to show up. It's super sloppy and messy code right now but I'll post what I'm getting some results from:

    // parseFile2
    /** 
    Load a csv file into an array of strings <br>
    Construct data objects out of each line and store in array
    */
    String[] data;
    Item[] items;
    int y = 300;
    int x = 15;
    int bx;
    int by;
    int boxSize = 5;
    boolean overBox;
    boolean locked;
    
    void setup() {
      //standard setup
      size(1400,500);
      background(255);
    
      // Load data from a file as array of strings
      data = loadStrings("biomass.csv");
      //create object array
      items = new Item[data.length];
      //fill object array
      for (int i=0; i<data.length; i++) {
        //split each line into pieces on ","
        String[] pieces = data[i].split(",");
        //trim - doesnt really change anything from what I can see
        trim(pieces[1]);
        // start
        items[i] = new Item(pieces[0], int(pieces[1]));
      }
    
      for (int i=0; i<items.length; i++) {
        println(items[i]);
      }
    
       //graphing
      stroke(0);
      strokeWeight(1);
      for (int i=0; i<items.length; i++) {
       fill((int)items[i].tons*110);
       pushMatrix();
       translate(x*i, y);
       rect(0.0,0.0,(float)x, (float)+items[i].tons);
       println(items[i].tons);
       popMatrix();
      }
    
      // Test if the cursor is over the box 
      if (mouseX > bx-boxSize && mouseX < bx+boxSize && 
          mouseY > by-boxSize && mouseY < by+boxSize) {
        overBox = true;  
        if(!locked) { 
          stroke(255); 
          fill(153);
        } 
      } else {
        stroke(153);
        fill(153);
        overBox = false;
      }
    
      // Draw the box
      rect(bx, by-100, boxSize, boxSize);
    
    }
    
    class Item {  
      String country;  // Country name
      int tons;         // biomass in tons
      //double score;
    
      // constructor splits on "," and puts pieces into data fields
      Item(String country, int tons) {
        this.country = country;
        this.tons = tons;
        //this.score = score;
      }
    
      String toString() {
        String msg = "In " + country;
         msg += " there is a biomass of " + tons + " tons";
        return(msg);
      }
    }
    
    void mousePressed() {
    
    
    }
    
  • class Item is not a super name, item could be anything (like thing)

    better a cool name like BiomassPerCountry or so

  • edited May 2016

    ok, I think you did a good job so far!

    Just few remarks to keep you working on it ;-)

    you are doing great!

    without draw(), you can't register mouse moves because the sketch doesn't work then

    even mousePressed() won't work

    test it yourself:

    void mousePressed() {
      //
      println("mouse!");
    }
    

    you'll never see 'mouse' printed without a function draw().

    my advice was to make a draw()

    so the 2nd half of your setup() belongs into draw

    Remarks on objects

    and again, when you think of OOP (object oriented programming) and objects, your goal would be to bring the functionality and data into the class.

    so this:

    int y = 300;
    int x = 15;
    int bx;
    int by;
    int boxSize = 5;
    boolean overBox;
    boolean locked;
    

    belongs into the class because one rect / bar is a property of the data of one country.

    what is the difference of x,y and bx,by? Give better names.

    bx refers to box. boxSize refers to box - so why not be consistent and use box as a part of the name throughout? boxX, boxY...

    boxSize is not a good name since the box has a height which is different from its width (which you named x, better would be boxWidth).

    Boxes

    now you check the mouse against bx etc. but you never define them:

    if (mouseX > bx-boxSize && mouseX < bx+boxSize && 
          mouseY > by-boxSize && mouseY < by+boxSize) {
    

    bx atc. are all 0. Won't work.

    you need to define bx etc. and then use bx with rect()

    also, you draw each rect twice. Always suspicious. Lines 46 and 66

    Better draw it only once

    ;-)

  • edited May 2016
    // parseFile2
    /* 
     Load a csv file into an array of strings 
     Construct data objects out of each line and store in array
    
     the csv must be in the sketch's data folder, name "biomass.csv" and look like this e.g.  
     USA    ,23443
     POLAND                          ,321
     ITALY,9823
    
    
     */
    
    
    
    // very tidy here 
    float maxValueTonsBioMass=25000; // ADAPT THIS 
    BiomassPerCountry[] items;       // the main array 
    
    // -----------------------------------------
    
    void setup() {
      //standard setup
      size(1400, 500);
      background(255);
    
      String[] data;
    
      // Load data from a file as array of strings
      data = loadStrings("biomass.csv");
    
      //create object array
      items = new BiomassPerCountry[data.length];
    
      //fill object array
      // splits on "," and puts pieces into data fields
      for (int i=0; i<data.length; i++) {
    
        //split each line into pieces on ","
        String[] pieces = data[i].split(",");
    
        // error? 
        if (pieces.length!=2) {
          println ("error in line " + data[i]);
        } // if 
    
        //trim - remove empty spaces at the beginning or end 
        pieces[0]=trim(pieces[0]);
        pieces[1]=trim(pieces[1]);
    
        // start
        items[i] = new BiomassPerCountry(pieces[0], int(pieces[1]), i);
      } // for 
    
      for (int i=0; i<items.length; i++) {
        println(items[i]);
      } // for 
    
      // some final preparations for drawing 
      stroke(0);
      strokeWeight(1);
    } // func 
    
    void draw() {
    
      //graphing
      background(255);
    
      // very tidy here, all the work is done in the class  
      for (int i=0; i<items.length; i++) {
        items[i].display();
      } // for
    } //func 
    
    void mousePressed() {
      println("mouse!");
    } //func 
    
    // =============================================== 
    
    class BiomassPerCountry {  
    
      String country;   // Country name
      int tons;         // biomass in tons
      //double score;
    
      float boxX;
      float boxY;
      float boxWidth = 15;
      float boxHeight; 
      color boxColor;
    
      boolean overBox=false;
      boolean locked=false;
    
      // constructor
      BiomassPerCountry (String country, int tons, float i_number) {
    
        // we get the data 
        this.country = country;
        this.tons    = tons;
    
        // we calcluate the box here since it won't change later 
        boxX      = i_number * boxWidth; 
        boxHeight = map (  (float)tons, 0, maxValueTonsBioMass, 0, height-12 ) ;  
        boxY      = height - boxHeight; 
        boxColor  = color (map ( tons, 0, maxValueTonsBioMass, 0, 255));
        //this.score = score;
      }
    
      String toString() {
        String msg = "In " + country;
        msg += " there is a biomass of " 
          + tons + " tons.";
        return(msg);
      }
    
      void display() {
    
        fill( boxColor );
        stroke(153);
    
        // Test if the cursor is over the box 
        if (mouseX > boxX && mouseX < boxX+boxWidth && 
          mouseY > boxY && mouseY < boxY+boxHeight) {
          overBox = true; 
          fill(255, 0, 0); // red
          text(toString(), 300, 40, 120, 700);
          if (!locked) { 
            fill(255, 0, 0); // red  
            // fill(153);
          }
        } else {
          // stroke(153);
          //fill(153);
          overBox = false;
        }
    
        // Draw the box
        rect(boxX, boxY, 
          boxWidth, boxHeight);
      }// method
    } // class 
    // 
    
  • not sure what locked signifies though

    ;-)

  • Nice! To have draw() called only once use noLoop(); inside setup().

  • noLoop() would defy the mouse interaction

  • Oh yeah. Whoops!

Sign In or Register to comment.