center a table in window?

edited October 2017 in Questions about Code

I am trying to center a table in my presentation window, but I cannot find any code samples in the processing guide about table placement, just text. I am a complete noob to code so please be be patient. My current code: size(1200, 675);

Table tabela = loadTable("cidades.tsv", "header");
for (int i = 0; 
  i < tabela.getRowCount(); 
  i = i + 1) {
  TableRow linha = tabela.getRow(i);
  int posX = 100*i;
  int posY = 405;
  float lado = sqrt(linha.getInt("área"));
  ellipse(posX, posY, lado, lado);
  for (int j=0; 
    j<linha.getInt("população")/5000; 
    j=j+1) {
    point(random(posX - lado, posX + lado), 
      random(posY - lado, posY+lado));
  }
}

The data I am pulling from the .tsv: cidade população área Tokyo-Yokohama 37239000 8547 Jakarta (Jabotabek) 26746000 2784 Seoul-Incheon 22868000 2163 Delhi, DL-HR-UP 22826000 1943 Shanghai, SHG 21766000 3497 Manila 21241000 1437 Karachi 20877000 803 New York, NY-NJ-CT 20673000 11642 Sao Paulo 20568000 3173 Mexico City 20032000 2046

Tagged:
«1

Answers

  • edited October 2017

    Ummm...so I feel like I just tried to find a needle in a haystack that was in a foreign language lol. I think I simply need to tell the code that I do not want x to start at zero so that half of the first ellipse is not falling off the screen...so I think I would need to tweak this part of the code:

    int posX = 100*i;

    or am I completely off in thinking it could be that simple?

  • you can calculate this

    size(900, 900);
    Table tabela = loadTable("cidades.csv", "header");
    
    // calc the width of one column 
    float factor = (width - 100) / tabela.getRowCount();  
    
    for (int i = 0; i < tabela.getRowCount(); i++) {
    
      TableRow linha = tabela.getRow(i);
    
      float posX = factor*i + 50;
      int posY = 405;
    
      float lado = .02* sqrt(linha.getInt("area"));
    
      stroke(0);
      noFill();
      ellipse(posX, posY, lado, lado);
    
      for (int j=0; j<linha.getInt("populacao")/5000; j++) {
        //point(random(posX - lado, posX + lado), 
        //  random(posY - lado, posY+lado));
      }
    }
    //
    
  • O, I mixed up row count and column count in line 5

    Apologies

  • edited October 2017

    Thank you Chrisir! A little tweaking, and I got it so that it is not falling off the edge! size(1200, 675);

            Table tabela = loadTable("cities.tsv", "header");
            // calc the width of one column 
            float factor = (width - 25) / tabela.getRowCount();  
    
            for (int i = 0; i < tabela.getRowCount(); i++) {
    
              TableRow linha = tabela.getRow(i);
    
              float posX = factor*i + 50;
              int posY = 405;
    
              float lado = sqrt(linha.getInt("Area")); 
              ellipse(posX, posY, lado, lado);
    
              for (int j=0; 
                j<linha.getInt("Population")/5000; 
                j=j+1){
                point(random(posX - lado, posX + lado), 
                  random(posY - lado, posY+lado));
              }
            }
    

    This is what the visualization looks like so far: sketchtestgraphic

    Now I need to figure out how to get this part of the code:

                 for (int j=0; 
                            j<linha.getInt("Population")/5000; 
                            j=j+1){
                            point(random(posX - lado, posX + lado), 
                              random(posY - lado, posY+lado));
    

    To fill in the Area ellipse with the population density, instead of a square overlay. What I am trying to do it tweak a tutorial we were given which was ugly and boring lol. But not being a coder, it is not as simple as I thought it would be.

  • edited October 2017

    The original visualizaion:

    cidades

  • edited October 2017

    Sorry, wrong graphic...that one was my first attempt at tweaking the code...here is the tutorial graphic in its full ugliness: cidades

  • You need a round shape?

    make a random Radius and a random angle a:

        x=r*cos(a);
        y=r*sin(a);
    

    a is in radians by the way

  • Yes and no, I need the population density to fill in the area (ellipse) by randomly placing one dot for every 5000 people.

  • I showed how to make a circle instead of a rectangle

    Repeat this as often as you need it

  • Use a for loop

  • I guess my question is since the population is being pulled from the same table, and is suppose to be filling in the area ellipse, the circles are not going to be random, just the points used to represent the population which are suppose to fill in the area ellipse are random.

    Maybe I am not explaining it well...according to the tutorial: To see the density of each city here, we will use a straightforward technique: representing the total number of inhabitants as points within the city area.

    Currently, each circle represents the area of one city. I just cant seem to get the points inside the "city area" since I changed it from a square to an ellipse.

  • You are right I forgot to add the position to x and y.

    Those are the center of the circle. And not random

    Only radius and angle is random

  •  x=r*cos(a)+xpos;
     y=r*sin(a)+ypos;
    
  • Would I plug that somewhere into the existing for statement that generates the population density at the bottom? (code dummy here)

  • Yes instead of your point line

    Adjust the variables accordingly

  • no matter where I try to plug it in I get "variable x does not exist" error?

  • float x; before the line

  • Do I need to do that for the r and a variable as well, because I am getting the same error for both of them as well?

  • _Yes instead of your point line

    Adjust the variables accordingly_

    I am also not sure what you mean by this...

  • edited October 2017

    I am pretty sure I am completely screwing this up...what is the "r" variable? The radius? random?

    for (int j=0; 
        j<linha.getInt("Population")/5000; 
        j=j+1) {
        int a;          // Declare variable 'a' of type int
        a = 1;        //a is in radians 
        float r;      //what is r?? 
        float x;
        float y;
        point(random(x=r*cos(a)+posX), 
          random(y=r*sin(a)+posY));
    
        //point(random(posX - lado, posX + lado), 
        // random(posY - lado, posY+lado));
      }
    
  • edited October 2017

    Sorry, I confused you.

    Here is the idea. Apply it to your sketch.

    Here the position of the circle (its center) is mouseX,mouseY.

    Number of points is 444.

    A point is set randomly at position x,y within a maximum radius of 46.

    void setup() {
      size(670, 670);
      background(0);
    }
    
    void draw() {
      //  background(0); 
      for (int j=0; 
        j<444; 
        j=j+1) {
    
        // float radius=46;  
        float radius=random(46);  
        float angle=random(TWO_PI);
    
        float x=radius*cos(angle)+mouseX;
        float y=radius*sin(angle)+mouseY;
    
        stroke(random(255), random(255), random(255));
        point(x, y);
      }
    }
    
  • I know I have got to be missing something simple...I have checked that all my curly brackets have a partner but I keep getting an error on line 24 ( void setup() {)saying missing left curly bracket "{". Here is my full code...I can't see if it works until I figure out the bracket...sigh...

       _ //size of screen
        size(1200, 675);
    
        //add background image
        PImage img;
        img = loadImage("1200x675.png");
        background(img);
    
        Table tabela = loadTable("cities.tsv", "header");
        // calc the width of one column 
        float factor = (width - 25) / tabela.getRowCount();  
    
        //adjust for spacing on screen with additional cities represented
        for (int i = 0; i < tabela.getRowCount(); i++) {
    
          TableRow linha = tabela.getRow(i);
    
          float posX = factor*i + 50;
          int posY = 405;
    
          float lado = sqrt(linha.getInt("Area")); 
          ellipse(posX, posY, lado, lado);
    
            void setup() {
            size(1200, 675);
            background(0);
          } 
          void draw() {
    
            for (int j=0; 
              j<444; 
              j=j+1) {
    
              // float radius=46;  
              float radius=random(46);  
              float angle=random(TWO_PI);
    
              float x=radius*cos(angle)+mouseX;
              float y=radius*sin(angle)+mouseY;
    
              stroke(random(255), random(255), random(255));
              point(x, y);
            }
    
            //point(random(posX - lado, posX + lado), 
            // random(posY - lado, posY+lado));
          }
        }_
    
  • And thank you for you patience. I really appreciate your help in figuring this out.

  • this is a function:

    void setup() {
      size(670, 670);
      background(0);
    }
    

    you can't have commands outside of functions

    your other function is draw()

    it is from { to the correspondent }

  • So the void set up needs to be at the beginning of the code? And everything else in the void draw function?

  • Yes

    this is not a command but a declaration, it belongs before setup

    //add background image
    PImage img;
    

    post your entire code please

  • Ok, it is sorta working, but no longer pulling the population data

    Current code:

    void setup() {
      size(1200, 675); //size of screen
    
      //add background image
      PImage img;
      img = loadImage("1200x675.png");
      background(img);
    }
    
    void draw() {
      Table tabela = loadTable("cities.tsv", "header");
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
        ellipse(posX, posY, lado, lado);
    
        for (int j=0; 
          j<444; 
          j=j+1) {
    
          // float radius=46;  
          float radius=random(46);  
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;
          float y=radius*sin(angle)+posY;
    
          stroke(random(255), random(255), random(255));
          point(x, y);
        }
    
        //point(random(posX - lado, posX + lado), 
        // random(posY - lado, posY+lado));
      }
    }
    

    But I need this part:

     for (int j=0; 
              j<444; 
              j=j+1) {
    
              // float radius=46;  
              float radius=random(46);  
              float angle=random(TWO_PI);
    
              float x=radius*cos(angle)+posX;
              float y=radius*sin(angle)+posY;
    
              stroke(random(255), random(255), random(255));
              point(x, y);
            }
    

    to be pulling the "points" from the table to visually represent the population density. The code for that from my previous code was:

    for (int j=0; j<linha.getInt("Population")/5000; j=j+1)

  • So it is not just about creating random dots in a circle pattern, but filling the existing circles (whose sizes are based on the data in the table) with a prescribed number of dots based on the population data in the table. My original code did everything right, except the shape was incorrect, correct area, just wrong shape. Does that make sense?

    Here is the original tutorial, which I am trying to tweak and make more visually appealing, and add more data, while telling the same narrative. http://geojournalism.org/2013/08/portugues-as-cidades-mais-populosas-do-mundo/

  • Yes.

    This idea is that you join the two codes.

      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
        ellipse(posX, posY, lado, lado);
    
        for (int j=0; 
          j<444;         // replace 444 by populacao from table !!!!!!!!!!!
          j=j+1) {
    
          float radius=random(lado / 2);    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;  // using posX and posY - good!!!!!!!!!!
          float y=radius*sin(angle)+posY;
    
          stroke(random(255), random(255), random(255));
          point(x, y);
        }
    
  • Yeah, to get from rect shape to circle shape you just need to adopt this:

    float radius=random(lado / 2);    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    float angle=random(TWO_PI);
    
    float x=radius*cos(angle)+posX;  // using posX and posY - good!!!!!!!!!!
    float y=radius*sin(angle)+posY;
    
  • you wrote:

    with a prescribed number of dots based on the population data in the table.

    Yes,

    for (int j=0; 
        j<444;         // replace 444 by populacao from table !!!!!!!!!!!
        j=j+1) {
    
  • So, you're almost there

    I'll be back in an hour.

  • YES!!! You are amazing! Thank you so much! Final visual works perfectly!

    The code: void setup() { size(1200, 675); //size of screen

      //add background image
      PImage img;
      img = loadImage("1200x675.png");
      background(img);
    }
    
    void draw() {
      Table tabela = loadTable("cities.tsv", "header");
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
        ellipse(posX, posY, lado, lado);
    
        //pull population data to fill the area
        for (int j=0; 
          j<linha.getInt("Population")/5000; 
          j=j+1) {
    
          float radius=random(lado / 2);    
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;  // using posX and posY - good!!!!!!!!!!
          float y=radius*sin(angle)+posY;
    
          //stroke(random(255), random(255), random(255)); //adds color to points
          point(x, y);
        }
      }
      save("cities.jpg");
    }
    

    Final visual:

    cities

    The visual is much cooler when you run it because the points are in movement which is a great representation for a population! Which part of the code creates that flux?

  • Dunno

    Try moving line 8 into setup ()

    Make tabela a global variable

  • background(img);

    at start of draw() !!!!

    comment out line 21 with //

    use this stroke(random(255), random(255), random(255)); before point

  • my version has a file named .csv instead

    //add background image
    PImage img;
    
    Table tabela;
    
    void setup() {
    
      size(1200, 675);
    
      img = loadImage("1200x675.png");
      //  background(img);
      tabela = loadTable("cities.csv", "header");
      background(0);
    }
    
    void draw() {
    
      background(0);
    
    
      println(tabela.getRowCount()); 
    
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
    
        float count = linha.getInt("populacao");
    
        // ellipse(posX, posY, lado, lado);
        println ("x: "+posX+"; "+lado);
        drawONE(posX, posY, lado/2, count/10000) ;
      }
      println ("done");
    } 
    
    void drawONE(float posX, float posY, 
      float lado, 
      float count) {
    
      for (int j=0; 
        j<count; 
        j=j+1) {
    
        // float radius=46;  
        float radius=random(lado);  
        float angle=random(TWO_PI);
    
        float x=radius*cos(angle)+posX;
        float y=radius*sin(angle)+posY;
    
        stroke(random(255), random(255), random(255));
        point(x, y);
      }
    
      //point(random(posX - lado, posX + lado), 
      // random(posY - lado, posY+lado));
    }
    
  • edited October 2017

    ok, now I want you to do this: When the mouse hovers over a circle the name of the city appears.

    look at if / dist / text in the reference:

    https://www.processing.org/reference/

  • hmmm....wouldn't I need to look at mouse over as well?

  • mouse over is not a command, you need to program it yourself as far as I know

    use if and dist

  • hmmm...

    not sure if I am on the right track:

    //add background image
    PImage img;
    PFont myFont=createFont("Arial", 12);
    Table tabela;
    
    void setup() {
      size(1200, 675); //size of screen
    
      textFont(myFont);
    
      img = loadImage("1200x675.png");
      background(img);
    }
    
    void draw() {   
    
      Table tabela = loadTable("cities.tsv", "header");
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
        ellipse(posX, posY, lado, lado);
    
        //pull population data to fill the area ellipse
        for (int j=0; 
          j<linha.getInt("Population")/5000; 
          j=j+1) {
    
          //generates population points in flux
          float radius=random(lado / 2);    
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;  
          float y=radius*sin(angle)+posY;
    
          //adds  random color to points if you want
          //stroke(random(255), random(255), random(255)); 
          point(x, y);
    
          //When the mouse hovers over a circle the name of the city appears.
          float d = dist(posX, posY);
          if (dist(mouseX,mouseY,posX, posY));
          text(linha = tabela.getColumn("City"), mouseX-20, mouseY);
    
    
          }
        }
      }
      //save("cities.jpg");
    //}
    
  • almost

    text(linha.getString("City"), mouseX-20, mouseY);
    

    should be outside the inner for loop I guess....

    try it and correct it

  • it is not liking line 49, the float d-=

    Capture

  • do you use d at all from this line?

    No.

    this line is not needed.

  • float to boolean?

    Capture2

  • Leaving work...be back on in an hour...thank you for the challenge and help!

  • Oh, that's right

        if(dist(.........) < 45) 
    

    or instead of 45 use the radius of the current city or a value slightly bigger than the biggest circle/ radius

  • lol, I have no idea how to find that lol...would I pull from the code?

  • Hmm...it is not popping up one name but multiples. I tried to move it, thinking it might be pulling from the population code...

     //add background image
    PImage img;
    
    Table tabela;
    
    void setup() {
      size(1200, 675); //size of screen
      PFont myFont=createFont("Arial", 12);
      textFont(myFont);
    
      img = loadImage("1200x675.png");
      background(img);
    }
    
    void draw() {   
    
      Table tabela = loadTable("cities.tsv", "header");
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area")); 
        ellipse(posX, posY, lado, lado);
    
        if (dist(mouseX, mouseY, posX, posY)<25) {
          text(linha.getString("City"), mouseX, mouseY-50);
        }
        //pull population data to fill the area ellipse
        for (int j=0; 
          j<linha.getInt("Population")/5000; 
          j=j+1) {
    
          //generates population points in flux
          float radius=random(lado / 2);    
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;  
          float y=radius*sin(angle)+posY;
    
          //adds  random color to points if you want
          //stroke(random(255), random(255), random(255)); 
          point(x, y);
    
          //When the mouse hovers over a circle the name of the city appears.
    
          //float d = dist(posX, posY);
        }
      }
      //save("cities.jpg");
    }
    

    Capture3

  • looks good.

    few remarks:

    the texts do add up because processing doesn't delete the screen automatically.

    You have to do this:

    So first line in draw():

      background(img);
    

    Next idea: when you have the text add mouseX,mouseY and you move the mouse the text moves as well:

             text(linha.getString("City"), mouseX, mouseY-50);
    

    looks uncool / unstable.

    Idea:

    bring it out at a position of the circle:

        text(linha.getString("City"), posX, posY-50);
    

    now you can move the mouse within the circle and text stays where it is

    and Box around the text

    //add background image
    PImage img;
    
    Table tabela;
    
    void setup() {
      size(1200, 675); //size of screen
      PFont myFont=createFont("Arial", 12);
      textFont(myFont);
    
      img = loadImage("1200x675.png");
      // background(img);
    }
    
    void draw() {   
    
      background(0); 
    
      Table tabela = loadTable("cities.csv", "header");
      // calc the width of one column 
      float factor = (width - 25) / tabela.getRowCount();  
    
      //adjust for spacing on screen with additional cities represented
      for (int i = 0; i < tabela.getRowCount(); i++) {
    
        TableRow linha = tabela.getRow(i);
    
        float posX = factor*i + 50;
        int posY = 405;
    
        float lado = sqrt(linha.getInt("Area"));
    
        fill(0); 
        stroke(255); 
        ellipse(posX, posY, lado, lado);
    
        //pull population data to fill the area ellipse
        for (int j=0; 
          j<linha.getInt("Population")/5000; 
          j=j+1) {
    
          //generates population points in flux
          float radius=random(lado / 2);    
          float angle=random(TWO_PI);
    
          float x=radius*cos(angle)+posX;  
          float y=radius*sin(angle)+posY;
    
          //adds  random color to points if you want
          stroke(random(255), random(255), random(255)); 
          point(x, y);
        } // for
    
        //When the mouse hovers over a circle the name of the city appears.
        if (dist(mouseX, mouseY, posX, posY)<25) {
    
          // draw a box
          float dist = -3;
          stroke(0);
          fill(3, 48, 22); // yellow 
          rect (posX+dist, 
            posY-60+dist, 
            textWidth(linha.getString("City"))+10, 
            32);
          noStroke(); 
    
          // draw text 
          fill(220); 
          text(linha.getString("City"), posX, posY-60+16);
        }
      }//for
      //save("cities.jpg");
    }
    //
    
Sign In or Register to comment.