Dear all,
I would like to build a basic word cloud, but I have issue with overlapping and placing text.
I have seen a mention of a wordcloud library “wordcram.org” but it seems obselete.
The code below is based on 9.8: Random Circles with No Overlap - p5.js Tutorial. My main problem is that the overlapping detection is not working… maybe the question is how to detect overlap with rectangles ?
my data file in csv
generic,pascal tonn,90
specific,jose urloe,130
generic,chantal iuapdf,50
specific,marius jhfoea,80
And the code
ArrayList<Person> pers = new ArrayList<Person>();
int margin = 40;
void setup() {
size(300, 300);
background(255);
textAlign(CENTER, CENTER);
Table table ;
table = loadTable("../data.csv");
IntList vals = new IntList();
// load data
int limit = 0;
for (TableRow row : table.rows()) {
if (row.getString(0).equals("auto") == false) {
if (limit > 50) break;
pers.add(new Person( row.getString(1), row.getString(0), row.getInt(2)));
vals.append(row.getInt(2));
limit +=1;
}
}
// deduce font size and width name
for (Person me : pers) {
// font size
me.fontSize = round(map(me.nb, vals.min(), vals.max(), 10, 30));
// width name
textSize(me.fontSize);
me.nameWidth = round(textWidth(me.name));
int up = round(textAscent() * 0.8);
int down = round(textDescent() * 0.8);
me.nameHeight = up + down;
}
println("number of personnes loaded", pers.size(), '\n');
//deduce positionning
for (int i = 0; i < pers.size(); i++) {
Person me = pers.get(i);
float testx = round(random(width-margin*2));
float xmin = testx - me.nameWidth/2;
float xmax = testx + me.nameWidth/2;
float testy = round(random(height-margin*2));
float ymin = testy - me.nameHeight/2;
float ymax = testy + me.nameHeight/2;
boolean overlapping = false ;
for ( Person you : pers) {
if ( (xmin > you.xmin) && (xmax < you.xmax) &&
(ymin > you.ymin) && (ymax < you.ymax) ) {
overlapping = true;
/*float d = dist(me.xpos, me.ypos, you.xpos, you.ypos);
if (d < me.nameWidth/2 + you.nameWidth/2) {
}*/
}
if (!overlapping) {
me.isPlaced = true;
me.setCoordinate(testx, testy);
}
}
}
// close setup
}
void draw() {
noLoop();
for (int i = 0; i < pers.size(); i ++) {
Person me = pers.get(i);
if (me.isPlaced) {
me.display();
println(me.name, '\t', '\t', me.xmin, me.xmax, me.ymin, me.ymax);
}
}
}
class Person {
String name, type ;
int nb, fontSize, nameWidth, nameHeight;
int xpos, ypos, xmin, xmax, ymin, ymax;
boolean isPlaced;
Person(String _n, String _t, int _nb) {
name = _n ;
type = _t ;
nb = _nb ;
xpos = ypos = xmin = xmax = ymin = ymax = 0;
isPlaced = false;
}
//dist()
void setCoordinate(float x, float y) {
int space = 20;
isPlaced = true;
xpos = round(x);
ypos = round(y);
xmin = xpos - nameWidth/2 - space ;
xmax = xpos + nameWidth/2 + space ;
ymin = ypos - nameHeight/2 - space ;
ymax = ypos + nameHeight/2 + space ;
}
void display() {
/*float x = random(margin, width - margin);
float y = random(margin, height - margin);*/
textSize(fontSize);
if (type.equals("generic")) fill(#ff5733);
if (type.equals("specific")) fill(#2980b9);
//if (type.equals("generique")) fill(140);
text(name, xpos, ypos);
}
}