Description:
I wrote a code that reads from the billboard top 100 songs (not the most recent). I edit the .csv file I found online to remove redundant data that I did not need and I used the left data to draw circles at random locations for each of the top 100.
I added a small alpha value to show the layering of circles as they are random.
I had to deal with longer song names and make them wrap around.
Instead of trying to find a library that works, I decided to try to make the wrap work myself to explore and know what I can do to manipulate a string.
key:
Code:
I started with a circle class to draw each circle at a random location and depending on circle details. I added an array to save the circles.
String names[]; int ranks[]; int weeks[]; boolean arrDone[] = new boolean[100]; boolean flag = false; int counterDone = 0; PFont myFont; class Circles { //attributes PVector pos ; int col; int diam; String text; // number of weeks on board gives color shade, and rank determines radius Circles(int weeks, int ranks, String _text) { pos = new PVector(random(0, width), random(0, height)); //calculate fraction from 255 col = int((255*weeks/87)); text = _text; //max diam = 70 diam =int((width)/ranks); diam = constrain(diam, 50, 500); } void draw_circle() { fill(0, 0, col, 200); //fill(255,100); noStroke(); ellipse(pos.x, pos.y, diam, diam); // split text into lines String[] words = split(text, ' ' ); writetext(words); }
The next function is part of the circle class, I put it here separately because it includes the code for the wrap of the text.
void writetext(String[] arr) { String[] temp = new String[arr.length]; int n=0; for (int i=0; i<arr.length; i++) { fill(255); textSize(diam/5); textAlign(CENTER); if (arr.length>1) { if (i<arr.length-1) { if ((textWidth(arr[i])+textWidth(arr[i+1]))<diam/2) { temp[i] = arr[i] + " " + arr[i+1]; n++; //i++; continue; } else { temp[i] = arr[i]; n++; } } else { temp[i] = arr[i]; n++; } } else { temp[i] = arr[i]; n++; } } for (int k=-1; k<n-1; k++) { if (arr.length>1 && textWidth(temp[k+1])>0) { if (n>=3) { text(temp[k+1], pos.x, pos.y+k*diam/5); } else { text(temp[k+1], pos.x, pos.y+(k+1)*diam/5); } } else { text(arr[0], pos.x, pos.y+(k+1)*diam/5); } } } }
Here, I declared the circle’s object array and then loaded and processed the data from the .csv file.
void readData() { String stuff[] = loadStrings("charts.csv"); String data[]= new String[3]; // Convert String into an array of integers using ',' as a delimiter // string array is returned, which we cast to an int array names = new String[stuff.length]; ranks = new int[stuff.length]; weeks = new int[stuff.length]; for (int i=1; i<stuff.length; i++) { data = split(stuff[i], ',' ); //fill arrays with data ranks[i] = int(data[0]); names[i] = data[1]; weeks[i] = int(data[2]); } }
in the creat function here I added a boolean array to check if the song has been output on the screen or not to avoid repitition.
void create() { int num = int(random(1, 99)); boolean flag = false; if (arrDone[num]) { flag= true; } else { arrDone[num] = true; } if (!flag && count<=100) { // int weeks, int ranks, String _text){ circle[count] = new Circles(weeks[num], ranks[num], names[num]); circle[count].draw_circle(); count++; } }
I only used the draw function for the text to appear at the beginning of the code running time. I generated the circles with mouse clicks instead to give time for the user to analyze each new circle.
void setup() { size(1000, 1000); background(200); readData(); } void draw() { myFont = createFont("SourceCodePro-Light.ttf", 60); textFont(myFont); if (frameCount<25) { String textt = "Press at a random location"; textSize(60); text(textt, width/2-(textWidth(textt)/2), height/2-32/2); }else if(frameCount<30){ background(200); } } void mouseClicked() { if (frameCount>30){ create(); } }
Video:
Looks great Fatema. Nice job on figuring out the text wrap. Are the sizes related to the songs’ positions on the top 100?