UI using controlP5 and wordcram

edited March 2014 in Library Questions

Hi all

I am trying to create a UI to create word clouds. Some of the operation I want to include in the UI is: the number of words to be displayed in the word cloud and the desired orientation of the words.

I am creating the wordclouds using the wordcram library, and using the controlP5 to create the UI.

I am having trouble combining the two libraries. I am creating the UI and am calling the drawall function of the wordcram inside the draw function. This is causing the wordcloud created to change every time draw is called. I want the word cloud to be updated only when a value is entered in one of the text boxes.

I have attached my code below.

import controlP5.*;
import wordcram.*;
import java.awt.*;


ControlP5 cp5;
public int myColorRect = 255;
public int myColorBackground = 100;

int colorMin = 100;
int colorMax = 100;

Range range;
Textfield textfield;


void setup() {
  size(800, 500);
  noStroke();
  cp5 = new ControlP5(this);


  //Create range field
    range = cp5.addRange("Orientation of words")
             // disable broadcasting since setRange and setRangeValues will trigger an event
             //.setBroadcast(false) 
             .setPosition(350,420)
             .setSize(100,20)
             .setHandleSize(2)
             .setRange(0,360)
             .setRangeValues(50,100)
             // after the initialization we turn broadcast back on again
             .setBroadcast(true)
             .setColorForeground(color(#072271))
             .setColorBackground(color(#077150))
             //.setColorCaptionLabel(color(#072271))          
             ;

    textfield = cp5.addTextfield("Number of words", 100, 420, 100, 20)
              .setAutoClear(false)
              //.setColorBackground(color(#077150))
              .setColor(color(#077150));
}

void draw() {
  background(#7E3C09);
  fill(myColorRect);
  rect(0, 0, width, 400);

  wordCloud();

}
int numberOfWords = 10;
public void textA(String theValue) {
  println("### got an event from textA : "+theValue);
  numberOfWords = Integer.parseInt(theValue);
}

void controlEvent(ControlEvent theControlEvent) {
  if(theControlEvent.isFrom("Orientation of words")) {
    // min and max values are stored in an array.
    // access this array with controller().arrayValue().
    // min is at index 0, max is at index 1.
    colorMin = int(theControlEvent.getController().getArrayValue(0));
    colorMax = int(theControlEvent.getController().getArrayValue(1));
    //println("range update, done.");
  }
}


void wordCloud()
{  
  WordCram wordcram = new WordCram(this);
  long startTime = System.currentTimeMillis();
  wordcram.fromTextFile("dummydata1.txt");

     wordcram.sizedByWeight(8, 40);


  wordcram.withColors(#22A07B, #0E64AD, #8B2893, #A01B2F);
  wordcram.maxNumberOfWordsToDraw(numberOfWords);

try{
  wordcram.drawAll();
  //noLoop();
}
catch(Exception e)
{
}

  long endTime = System.currentTimeMillis();
  //System.out.println("Run time :");
  //System.out.println(endTime - startTime);  
}

Answers

  • It looks like you are creating a new WordCram object each draw loop. Let's make a few changes to only re-create the object when needed. I'm not sure it will solve your issue, but will at least help with performance.

    import controlP5.*;
    import wordcram.*;
    import java.awt.*;
    
    
    ControlP5 cp5;
    public int myColorRect = 255;
    public int myColorBackground = 100;
    
    int colorMin = 100;
    int colorMax = 100;
    
    Range range;
    Textfield textfield;
    //make wordcram a global variable
     WordCram wordcram;
    
    void setup() {
      size(800, 500);
      noStroke();
      cp5 = new ControlP5(this);
    
    
      //Create range field
        range = cp5.addRange("Orientation of words")
                 // disable broadcasting since setRange and setRangeValues will trigger an event
                 //.setBroadcast(false) 
                 .setPosition(350,420)
                 .setSize(100,20)
                 .setHandleSize(2)
                 .setRange(0,360)
                 .setRangeValues(50,100)
                 // after the initialization we turn broadcast back on again
                 .setBroadcast(true)
                 .setColorForeground(color(#072271))
                 .setColorBackground(color(#077150))
                 //.setColorCaptionLabel(color(#072271))          
                 ;
    
        textfield = cp5.addTextfield("Number of words", 100, 420, 100, 20)
                  .setAutoClear(false)
                  //.setColorBackground(color(#077150))
                  .setColor(color(#077150));
    
        //initialize the WordCram object in setup
        wordCloud();
    }
    
    void draw() {
      background(#7E3C09);
      fill(myColorRect);
      rect(0, 0, width, 400);
    
     //try to draw the wordcram object each draw loop
     try{
      wordcram.drawAll();
      //noLoop();
    }
    catch(Exception e)
    {
    }
    
    }
    int numberOfWords = 10;
    public void textA(String theValue) {
      println("### got an event from textA : "+theValue);
      numberOfWords = Integer.parseInt(theValue);
    }
    
    void controlEvent(ControlEvent theControlEvent) {
      if(theControlEvent.isFrom("Orientation of words")) {
        // min and max values are stored in an array.
        // access this array with controller().arrayValue().
        // min is at index 0, max is at index 1.
        colorMin = int(theControlEvent.getController().getArrayValue(0));
        colorMax = int(theControlEvent.getController().getArrayValue(1));
        //println("range update, done.");
      }
    }
    
    
    void wordCloud()
    {  
      wordcram = new WordCram(this);
      long startTime = System.currentTimeMillis();
      wordcram.fromTextFile("dummydata1.txt");
    
      wordcram.sizedByWeight(8, 40);
    
    
      wordcram.withColors(#22A07B, #0E64AD, #8B2893, #A01B2F);
      wordcram.maxNumberOfWordsToDraw(numberOfWords);
    
    
      //no need to draw the wordcram here, we'll do that in the draw loop
    
      long endTime = System.currentTimeMillis();
      //System.out.println("Run time :");
      //System.out.println(endTime - startTime);  
    }
    
    //when you need to re-draw the word cloud, call this method
    void redrawWordCram()
    {
      wordcram.fromTextFile("dummydata1.txt");
    
    }
    

    again, i'm not familiar with the wordcram library so I can guarantee this will fix your issue, but hopefully it will lead you in the right direction. Mostly just pull the WordCram object out of the function so you can just re-draw it each frame rather than re-creating it.

    hope this helps! ak

Sign In or Register to comment.