/*------------------------------------------------------------ Copyright (c) 2013, Friends of Ed (An Apress Company) All rights reserved. The code provided here accompanies the book: Processing: Creative Coding and Generative Art in Processing 2 By Ira Greenberg, Dianna Xu, and Deepak Kumar Friends of Ed (An APress Company), 2013 ISBN-13 978-1430244646 Please refer to the associated README for a full disclaimer. ------------------------------------------------------------*/ // Sketch 7-11: Word Cloud Visualization import processing.opengl.*; String inputTextFile = "Obama.txt"; WordFreq table; PFont tnr; // The font to be used int N = 150; // The number of words to be displayed void setup() { // Input and parse text file String [] fileContents = loadStrings(inputTextFile); String rawText = join(fileContents, " "); rawText = rawText.toLowerCase(); String [] tokens; String delimiters = " ,./?<>;:'\"[{]}\\|=+-_()*&^%$#@!~"; tokens = splitTokens(rawText, delimiters); println(tokens.length+" tokens found in file: "+inputTextFile); // display stuff size(800, 800, OPENGL); tnr = createFont("Times New Roman", 120); textFont(tnr); textSize(24); noLoop(); // Create the word frequency table table = new WordFreq(tokens); println("Max frequency:"+table.maxFreq()); table.arrange(N); } // setup() void draw() { background(255); table.display(N); table.tabulate(N); } // draw() // Bonus: The start of building interaction... void mouseClicked() { table.interact(mouseX, mouseY); } // mouseClicked() /*------------------------------------------------------------ Copyright (c) 2013, Friends of Ed (An Apress Company) All rights reserved. The code provided here accompanies the book: Processing: Creative Coding and Generative Art in Processing 2 By Ira Greenberg, Dianna Xu, and Deepak Kumar Friends of Ed (An APress Company), 2013 ISBN-13 978-1430244646 Please refer to the associated README for a full disclaimer. ------------------------------------------------------------*/ // Sketch 7-11: Word Cloud Visualization // The WordTile class class WordTile extends Word { // A graphical tile conatining a word and additional attributes PVector location; // The top left corner of the tile (x, y) float tileW, tileH; // width and height of the tile color tileColor; // fill color of word float tileFS = 24; // the font size of tile, default is 24 WordTile(String newWord) { // Constructor super(newWord); setSize(); location = new PVector(0, 0); tileColor = color(0); } // WordTile() void setXY (float x, float y) { location.x = x; location.y = y; } // setXY() void setFontSize() { tileFS = map(freq, 1, 30, 10, 120); setSize(); } // setFontSize() void setSize() { textSize(tileFS); tileW = textWidth(word); tileH = textAscent(); } // setTileSize() boolean intersect(WordTile t2) { float left1 = location.x; // the first tile’s bounding box float right1 = location.x+tileW; float top1 = location.y-tileH; float bot1 = location.y; float left2 = t2.location.x; // the second tile’s bounding box float right2 = left2+t2.tileW; float bot2 = t2.location.y; float top2 = bot2-t2.tileH; return !(right1 < left2 || left1 > right2 || bot1 < top2 || top1 > bot2); // testing intersection } // intersect() void display() { fill(tileColor); textSize(tileFS); text(word, location.x, location.y); } // display() } // class WordTile /*------------------------------------------------------------ Copyright (c) 2013, Friends of Ed (An Apress Company) All rights reserved. The code provided here accompanies the book: Processing: Creative Coding and Generative Art in Processing 2 By Ira Greenberg, Dianna Xu, and Deepak Kumar Friends of Ed (An APress Company), 2013 ISBN-13 978-1430244646 Please refer to the associated README for a full disclaimer. ------------------------------------------------------------*/ // Sketch 7-11: Word Cloud Visualization // Sketch 7-11: The Word frequency table class class WordFreq { // A Frequency table class for Words ArrayList wordFrequency; String [] stopWords = loadStrings("stopwords.txt"); WordFreq(String[] tokens) { // Constructor wordFrequency = new ArrayList(); // Compute the wordFrequency table using tokens for (String t : tokens) { if (!_isStopWord(t, stopWords)) { // See if token t is already a known word int index = _search(t, wordFrequency); if (index >= 0) { ( wordFrequency.get(index)).incr(); } else { wordFrequency.add(new WordTile(t)); } } } // for // Sort the table in reverse order of frequencies _sort(wordFrequency); //Collections.sort(wordFrequency, Collections.reverseOrder()); } // WordFreq() void tabulate(int n) { // console printout //int n = wordFrequency.size(); println("There are "+N()+" entries."); for (int i=0; i < n; i++) { println(wordFrequency.get(i)); } } // tabulate void arrange(int N) { // arrange or map the first N tiles in sketch WordTile tile; for (int i=0; i < N; i++) { tile = wordFrequency.get(i); tile.setFontSize(); // Exploring the spiral layout float cx = width/2-50, cy = height/2, px, py; float R = 0.0, dR = 0.2, theta = 0.0, dTheta = 0.5; do { // find the next x, y for tile, i in spiral float x = cx + R*cos(theta); float y = cy + R*sin(theta); tile.setXY(x, y); px = x; py = y; theta+=dTheta; R += dR; } // until the tile is clear of all other tiles while (!clear (i)); } } // arrange() boolean clear(int n) { // Is tile, i clear of tiles 0..i-1? WordTile tile1 = wordFrequency.get(n); for (int i=0; i < n; i++) { WordTile tile2 = wordFrequency.get(i); if (tile1.intersect(tile2)) { return false; } } // for return true; } // clear() void display(int N) { for (int i=0; i < N; i++) { WordTile tile = wordFrequency.get(i); tile.display(); } } // display() void interact(float mx, float my) { // Find out which tile was clicked WordTile tile = _searchTile(wordFrequency, mx, my); println("Tile Clicked: "+tile); // Do something on it if (tile != null) { tile.tileColor = color(255, 0, 0); tile.display(); } } // interact() int N() { // Number of table entries return wordFrequency.size(); } // N() String[] samples() { // Returns all the words String [] k = new String[N()]; int i=0; for (Word w : wordFrequency) { k[i++] = w.getWord(); } return k; } // keys() int[] counts() { // Returns all the frequencies int [] v = new int[N()]; int i=0; for (Word w : wordFrequency) { v[i++] = w.getFreq(); } return v; } // values() int maxFreq() { // The max frequency return max(counts()); } // maxFreq() int _search(String w, ArrayList L) { // Search for word, w in L for (int i=0; i < L.size(); i++) { if (L.get(i).getWord().equals(w)) return i; } return -1; } // search() WordTile _searchTile(ArrayList L, float mx, float my) { for (int i=0; i < L.size(); i++) { WordTile tile = L.get(i); if (ptInTile(tile, mx, my)) { return(tile); } } return null; } // _searchTile() boolean ptInTile(WordTile t, float x, float y) { float x1 = t.location.x; float y1 = t.location.y - t.tileH; float x2 = x1+t.tileW; float y2 = t.location.y; return ((x >= x1 && x <= x2) && (y >= y1 && y <= y2)); } // ptInTile() boolean _isStopWord(String word, String[] stopWords) { for (String stopWord : stopWords) { if (word.equals(stopWord)) { return true; } } return false; } // isStopWord() void _sort(ArrayList A) { // sort the array A in ascending order // for i=1 through N-1: for (int i=0; i < A.size(); i++) { // insert A[i] in A[0] .. A[i] such that A[0] <= A[1] <= … <= A[i] WordTile a = A.get(i); // Save A[i] in p int pos = i; while ( (pos > 0) && (A.get(pos-1).getFreq() < a.getFreq())) { // while ( (pos > 0) && (a.compareTo(A.get(pos-1))>0)) { // Move A[pos-1] back by 1 A.set(pos, A.get(pos-1)); pos--; } // while // A[pos] is where a gets inserted A.set(pos, a); }// for } // _sort String toString() { // Print representation return "Word Frequency Table with"+N()+" entries."; } // toString() } // class WordFreq