How to pull and show text from a JSON File

Hey everybody,

I am trying to pull some text from this DataSet https://github.com/dariusk/corpora/blob/master/data/geography/rivers.json

I'm using JSON for the first time. All I am trying to do is pull the name of each river out of the JSON file and print them to the canvas one at a time.

Originally,I was getting all names on top of each other at the same time...now Im getting either the first or last name depending on whether I have text

(rivers[i].name,width/2, height/2); or

text(rivers[0].name,width/2, height/2);

Any suggestions would be great.

The full draw sketch is

function draw() { background(255);

var rivers = data.rivers;

for (var i = 0; i < rivers.length; i++) { /

for (var j = 0; j < rivers[i].length; j++) {

text(rivers[i].name, width / 2, height / 2);

} console.log(rivers[i].name);

} } .....

Thanks,

Paul

Answers

  • https://forum.Processing.org/two/discussion/15473/readme-how-to-format-code-and-text

    Try out the corresponding raw JSON file instead:
    https://raw.GitHubUserContent.com/dariusk/corpora/master/data/geography/rivers.json

    Although I'm suspicious you're gonna incur in CORS issues regardless. :-SS
    And you won't be able to load it at all! :(

  • Hey GoToLoop,

    Thanks for replying and apologies for not formatting correctly, I 'll keep an eye on in it for the future.

    I should have been clearer in my post..I've already pasted the rivers data into a .Json file within the sketch.

    Since I originally posted i've made some progress (I think)..I can get all text to appear on the screen..this was related to actual location...originally I had them all on top of each other now by using text(words,random, random) They are not on top of each other but are still all connected.

    So now what I'm trying to figure out is:

    A: how to make all text appear separately and randomly on the screen?

    and

    B: My original question/problem: How to make one name appear, followed by another and so on

    Here is the latest code attempt:

    //in this sketch I am trying to get river names to 
    
    //flash individually on screen
    
    var rivers; //declares variable called rivers
    
    function preload() {
      data = loadJSON("rivers.json");
    }
    
    function setup() {
      createCanvas(800, 800); //canvas 
      frameRate(1); //sets framerate 
    }
    
    //start of draw
    function draw() {
      background(255);
      var rivers = data.rivers; // says that rivers is data.rivers..leads to JSON files
      for (var i = 0; i < rivers.length; i += 2) { //for loop it goes all way through river.json
    
        //line and ellipse not using at moment
        //line(random(i), i, width, i);
        //ellipse(random(i), i, i, i);
    
        fill(random(0, 100), random(0, 100), random(0, 100), 125)
        textSize(100);
        textAlign();
        var words = rivers[i].name;
        var loc = random(800, 100);
        text(words, loc, loc);
    
        //}
        console.log(words)
      }
    }
    

    Thanks again,

    Paul

  • edited August 2016

    In order to workaround any CORS issues in GitHub, you can try out luck w/ http://RawGit.com.

  • Sorry GoToLoop,

    I'm not sure about CORSand if it is relevant in this case as I copied and pasted the data and created a new json. file in P5,

    Thanks again,

    Paul

  • Answer ✓

    @Paul - you could use a separate counter variable to delay iteration over all the data (untested and sub-optimal):

    var rivers;
    var counter = 1;
    
    function preload() {
      data = loadJSON("rivers.json");
    }
    
    function setup() {
      createCanvas(800, 800); //canvas 
      frameRate(1); //sets framerate 
    }
    
    function draw() {
      background(255);
      var rivers = data.rivers;
      // use counter as the limit
      for (var i = 0; i < counter ; i ++) {
    
        fill(random(0, 100), random(0, 100), random(0, 100), 125)
        textSize(100);
        textAlign();
        var words = rivers[i].name;
    
        // to keep location consistent you would actually have to store it for each element
        // either in a separate array or by attaching it to the data object...
        var loc = random(800, 100);
        text(words, loc, loc);
    
        console.log(words)
      }
    
      // crude mechanism for deferring increment of counter.
      // using a time-based approach would be better.
      if (frameCount % 1000 === 0) {
        counter++;
      }
    }
    
  • edited October 2019

    Here's my attempt. You can also check it online at the link below: :bz
    https://Glitch.com/~river-names

    "index.html":

    <meta charset=UTF-8>
    <script async src=http://CDN.JSDelivr.net/p5.js/latest/mainfile></script>
    <script defer src=RiverNames.js></script>
    

    "RiverNames.js":

    /**
     * River Names (v1.1.8)
     * GoToLoop (2016-Aug-11)
     *
     * Forum.Processing.org/two/discussion/17813/
     * how-to-pull-and-show-text-from-a-json-file#Item_6
     *
     * Glitch.com/~river-names
    */
    
    'use strict';
    
    const HTTP = 'https:' + '//',
          SITE = 'raw.GitHubUserContent.com',
          PATH = '/dariusk/corpora/master/data/geography/',
          FILE = 'rivers.json',
          URL  = HTTP + SITE + PATH + FILE,
          IS_REMOTE_FILE = false,
          TEXT_SIZE = 18, FPS = .5,
          rivers = [];
    
    function preload() {
      loadJSON(IS_REMOTE_FILE && URL || FILE, ({rivers: names}) => {
        for (const {name} of names)  rivers.push(name);
        print(rivers);
      });
    }
    
    function setup() {
      createCanvas(800, 500).mousePressed(() => background(0));
    
      frameRate(FPS).background(0).noStroke();
      textAlign(LEFT, TOP).textSize(TEXT_SIZE);
    }
    
    function draw() {
      const r = random(rivers),
            x = random(width  - textWidth(r)),
            y = random(height - TEXT_SIZE),
            c = '#' + hex(~~random(0x1000), 3);
    
      fill(c).text(r, x, y);
      console.log(r, c);
    }
    
  • Hi BlindFlish and GoTo,

    Thanks to you both for you replies and code.

    Blindfish when I ran your code the first river appears at random locations of the screen.

    However when I adjust:

    var counter = 1;

    to var counter = 2; //3,4,5, etc

    I will get that amount of rivers appearing on screen at same time. Similarly if i adjust;

    ` if (frameCount % 1000 ===0) { //change 0 to any number

    I will get the first 2 rivers appearing at the a few frames after each other but both remain on screen at the same time.

    Again, all I am trying to do is have first river appear on screen, stay for a few seconds, disappear, second river appears for a few seconds, disappears and then 3rd river appears etc, etc,

    Apologies GoToLoop...first time using .html in P5(and in general!) but will try and decipher it and get back to you.

    Thanks again to you both for your time,

    Paul

  • edited August 2016 Answer ✓

    ... have first river appear on screen, stay for a few seconds, disappear, second river appears for a few seconds, disappears and then 3rd river appears etc, etc.

    In my version, the canvas is cleared w/ background(0) only when we click at it:
    .mousePressed(() => background(0));

    In order to clear it at every frame we can comment out the method mousePressed() at line #31:
    createCanvas(800, 500)//.mousePressed(() => background(0));

    And then prefix background(0). to line #43: *-:)
    background(0).fill(c).text(r, x, y);

    And 1 more thing, we can control the FPS speed by changing the constant FPS at line #20:
    TEXT_SIZE = 18, FPS = .5,

    The lesser the value, the slower the speed. And thus, the time a river name stays on the canvas. :>

  • edited August 2016 Answer ✓

    ... first time using ".html" in P5 (and in general!), but will try and decipher it...

    You mean that small "index.html" file? In order for any browser to kickstart a webpage, it 1st needs to load an ".html" file. From there, the rest of the elements are loaded, including our p5.js <script> too.

    The reason why you haven't spotted any till now is probably b/c you're relying on some IDE, which already got some pre-made ".html' file. But you can bet it's there somewhere! :P

    My own "index.html" file is the minimum necessary in order to grab the p5.js library and execute its sketch. In my case the sketch is called "RiverNames.js".

    Of course, if you already got the bundled ".html" file from your IDE, no need for my "index.html". :-@

  • edited October 2019 Answer ✓

    Don't forget you can visit https://ThimbleProjects.org/gotoloop/91698/ in order to see the sketch running online.

    New link: https://Glitch.com/~river-names

    From there you can hit CTRL + U in order to view its ".html" file.
    Then click at src=RiverNames.js in order to view the sketch code itself. O:-)

  • Hey GoTo and BlindFish,

    Apologies for the delay in replying..I've been on Holidays, I'll be back in the next day or two with an update!

    Regards,

    Paul

  • edited August 2016

    Hi GoTo and BlindFish,

    Apologies again for the delay in replying to you both.

    I have attempted to combine both of your codes to get something close to what I want to do.

    GoTo...I have decided that I do not want to use .html as I will be using this sketch template for another project that will be using a json file that will not be online. However, I do want to use your effect of different text appearing after each other and I have changed the Text X, y location to the center of the screen.

    Here is what I have at the moment :

            TEXT_SIZE = 50, FPS = .5,
                rivers = [];
    
            function preload() {
                data = loadJSON("rivers.json");
    
    
            }
    
            function setup() {
                createCanvas(800, 500) //mousePressed(() => background(0)));
                frameRate(FPS).background(0).noStroke();
                textAlign(LEFT, TOP).textSize(TEXT_SIZE);
            }
    
            function draw() {
                //n = data.name;
                const
                    r= random(data.length),
                    c = '#' + hex(~~random(0x1000), 3);
    
                background(0).fill(c).text(r, width / 2, height / 2);
                console.log(r, c);
            }
    

    However when I run this sketch it is only giving me the letter O in the center of the screen. However, it is giving me different O each iteration.

    I guess the problem is here:

    const r = random(data.length),

    and have tried to change it to

         const r = random(data.length.name),
    

    and similar variations to this

    But this is giving me the 'Nan' error on screen and null in the log

    If either of you have any suggestions that would be great,

    Thanks,

    Paul

  • Hey guys,

    I'm shelving this project for the moment..but thanks again for your help. Just a quick question on forum etiquette..should I mark your answers as yes or no?! They didn't exactly answer what i was looking for (probably as a result of my interpretation)...just want to make sure I don't cause offence etc

    Thanks again

  • Answer ✓

    You can mark as many answers you felt contributed to your question. ;)

  • I'll start with that one ; )

Sign In or Register to comment.