# Basic word cloud without overlapping

**URL:** <https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316>\
**Category:** Coding Questions\
**Created:** [December 16, 2020, 9:28pm UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316 "2020-12-16T21:28:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mloiz](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mloiz/32/11462_2.png) [@mloiz](https://discourse.processing.org/u/mloiz)\
**Post date:** [December 16, 2020, 9:28pm UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316/1 "2020-12-16T21:28:51Z")

</div>

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”](https://forum.processing.org/one/topic/announcing-open-source-word-clouds-by-wordcram.html) but it seems obselete.  
The code below is based on [9.8: Random Circles with No Overlap - p5.js Tutorial](https://www.youtube.com/watch?v=XATr_jdh-44&feature=emb_title). 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

```auto
generic,pascal tonn,90
specific,jose urloe,130
generic,chantal iuapdf,50
specific,marius jhfoea,80

```

And the code

```auto
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);
  }
}

```

---

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [December 17, 2020, 8:12am UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316/2 "2020-12-17T08:12:31Z")

</div>

I don’t thing there is anything fundamentally wrong with [https://github.com/danbernier/WordCram](https://github.com/danbernier/WordCram), it just doesn’t seem loadable from processing ide and the link to the library code seems to be down. I created a rubygem based on this library for [Picrate](https://ruby-processing.github.io/PiCrate/), [propane](https://ruby-processing.github.io/propane/) and [JRubyArt](https://ruby-processing.github.io) (my ruby-processing projects) and they still work fine. Indeed if I place the jar files I created in processing library folder this test sketch works fine:-

```java
import wordcram.*;

// Set up the Processing sketch
size(1000, 600);
colorMode(HSB);
background(230);

// Make a wordcram from a random wikipedia page.
new WordCram(this)
  .fromWebPage("https://en.wikipedia.org/wiki/Special:Random")
  .withColors(color(30), color(110),
              color(random(255), 240, 200))
  .sizedByWeight(5, 120)
  .withFont("Copse")
  .drawAll();

```

NB: Using my jars only works with jdk11 ie processing4

 ![wordcram](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/ce4ac3881dcec645cf095cf597596836fc0677b2.png)

---

<div class="post-metadata">

**Author:** ![villares](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/villares/32/3166_2.png) [@villares](https://discourse.processing.org/u/villares)\
**Post date:** [April 6, 2021, 11:24am UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316/3 "2021-04-06T11:24:49Z")

</div>

**wordcram** download is broken :((  
could you provide a functional library folder we could add to our libraries folder in our local sketchbooks?

UPDATE: From the Internet Archive wayback machine (the original domain is gone): [https://web.archive.org/web/20161126072647/http://wordcram.org/wordcram.1.0.0.zip](https://web.archive.org/web/20161126072647/http://wordcram.org/wordcram.1.0.0.zip)

---

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [April 6, 2021, 12:49pm UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316/4 "2021-04-06T12:49:40Z")

</div>

A picture tells the story NB: Case is important:-

 ![wordcram](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c3ad3952e661ebeee2b2a22ed79f386c83955aab.png). In my [wordcram gem](https://github.com/ruby-processing/WordCram) I’ve managed to do away with cue language jar and I’ve updated to use jsoup-1.13.1.

---

<div class="post-metadata">

**Author:** ![villares](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/villares/32/3166_2.png) [@villares](https://discourse.processing.org/u/villares)\
**Post date:** [April 6, 2021, 1:06pm UTC](https://discourse.processing.org/t/basic-word-cloud-without-overlapping/26316/5 "2021-04-06T13:06:07Z")

</div>

Super cool, thank you!
