• fullscreen
  • buergschaft4.pde
  • classBuergschaft.pde
  • classTextAnalyzer.pde
  • classTextDisplayer.pde
  • classWord.pde
  • fastblur.pde
  • io.pde
  • tools.pde
  • /*---------------------------------------------------------
    Code by Diana Lange
    http://www.diana-lange.de
    http://vimeo.com/dianalange
    http://www.flickr.com/photos/dianalange/
    http://openprocessing.org/portal/?userID=5969
    
    Fastblur by Mario Klingemann
    
    Text by Friedrich Schiller
    ---------------------------------------------------------*/
    
    import processing.pdf.*;
    import processing.video.*;
    
    Buergschaft vis;
    MovieMaker mm;
    
    boolean saveMov = false, savePDF = false;
    String txtInputType = "utf", txtSource = "buergschaft.txt", txtTitle = "Schiller: Die Bürgschaft";
    
    
    void setup ()
    {
      size(800, 800, JAVA2D);
      //cursor(HAND);
      colorMode(HSB, 360, 100, 100, 255);
      background (0, 0, 97);
      vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
    
      smooth();
      frameRate (30);
    
    }
    
    void draw ()
    {
      if (savePDF) beginRecord (PDF, "export/" + timestamp() + ".pdf");
      vis.display();
      if (saveMov) mm.addFrame();
      if (savePDF) {
        savePDF = false;
        endRecord();
      }
    }
    
    
    
    
    
    
    
    
    
    class Buergschaft
    {
      private Word [] txt;
      private int fullSize, aninmationCount, animationMode = 1;
      private PVector pos = new PVector (width /2, height / 2);
      private float measure = 0.25;
      private float dBig = 300, dSmal = 150;
      private float strokeW = 0.5;
      private TextDisplayer rawTxt, listed;
      private PGraphics pg; 
      private HashMap colors;
      private String title;
      private PFont font;
      private boolean showText, showHeadline, animate;
      private TextAnalyzer textAnalyzer;
    
      public Buergschaft (TextAnalyzer txt, String title)
      {
        this.animate = txt.getMode();
        this.txt = txt.getWordArray();
        this.title = title;
        this.font = createFont ("Rockwell", 24);
        fullSize = txt.getFullSize();
        showText = false;
        showHeadline = true;
        if (animate) {
          this.textAnalyzer = txt;
          aninmationCount = 0;
        }
    
        HashMap txtColors = new HashMap();
        txtColors.put ("text", new Integer (color (0, 0, 20)));
        txtColors.put ("highlight", new Integer (color (355, 95, 50)));
        txtColors.put ("bg", new Integer (color (0, 0, 97, 15)));
        txtColors.put ("scrollbar", new Integer (color (0, 0, 3, 150)));
        txtColors.put ("scrollbarBG", new Integer (color (0, 0, 3, 60))); 
    
        int [] bordersBlock = {
          110, 70, 350, 600, 15
        };   
    
        int [] bordersList = {
          500, 70, 250, 600, 15
        };   
    
        pg = createGraphics (width, height, JAVA2D);
    
        rawTxt = new TextDisplayer (txt.getRawTxt(), bordersBlock, 12, txtColors, false);
        listed = new TextDisplayer (wordArrayToStringArray(this.txt), bordersList, 12, txtColors, true);
    
        colors = new HashMap();
        colors.put ("stroke", new Integer (color (0, 0, 3, 80)));
        colors.put ("bg", new Integer (color (0, 0, 97)));
        colors.put ("bgRect", new Integer (color (0, 0, 92)));
        colors.put ("highlight", new Integer (color (355, 95, 50)));
        colors.put ("ellipse", new Integer (color (0, 0, 20)));
        colors.put ("ellipseStroke", new Integer (color (355, 95, 50, 200)));
        colors.put ("connections", new Integer (color (0, 0, 3, 30)));
    
        if (showText) createBluredBG();
      }
    
      // ----------------------------------------------------------------------------------------------------
      // IO / Set / Get
      // ----------------------------------------------------------------------------------------------------
    
      public void measureUp ()
      {
        measure += 0.01;
        if (measure > 1.0) measure = 1.0;
      }
    
      public void measureDown ()
      {
        measure -= 0.01;
        if (measure < 0.0) measure = 0.0;
      }
    
      public void displayMode ()
      {
        showText = !showText;
    
        if (showText) createBluredBG ();
        else colorMode (HSB, 360, 100, 100, 255);
      }
    
      public void toggleHeadline ()
      {
        showHeadline = !showHeadline;
    
        createBluredBG ();
      }
      
      public void toggleAnimationMode ()
      {
        animationMode++;
        if (animationMode > 1) animationMode = 0;
      }
    
      private void createBluredBG ()
      {
        colorMode (RGB, 255, 255, 255, 255);
        pg.beginDraw();
        pg.smooth();
        displayBG (true, 10);
        displayGraph(true);
        if (showHeadline) displayHeadline(true, 0, int (height/2.0 - height/5.0), 30, 15);
        pg.endDraw();
        rawTxt.setBG(createCroppedImg(pg, rawTxt.getX(), rawTxt.getY(), rawTxt.getWidth(), rawTxt.getHeight()));
        listed.setTxt(wordArrayToStringArray(txt));
        listed.setBG(createCroppedImg(pg, listed.getX(), listed.getY(), listed.getWidth(), listed.getHeight()));
      }
    
      private PImage createCroppedImg (PImage source, int x, int y, int w, int h)
      {
        PImage blur = createImage (source.width, source.height, ARGB);
        System.arraycopy(source.pixels, 0, blur.pixels, 0, blur.pixels.length);
        fastblur(blur, 30);
        PImage result = createImage (w, h, ARGB);
    
        source.loadPixels();
    
        int count = 0;
        for (int i = y; i < y+h; i++)
        {
          for (int j = x; j < x+w; j++)
          {
            int index = j+i*blur.height;
            result.pixels[count] = blur.pixels[index];
            count++;
          }
        }
        result.updatePixels();
        return result;
      }
    
      // ----------------------------------------------------------------------------------------------------
      // Switch
      // ----------------------------------------------------------------------------------------------------
    
      public void display()
      {
        if (showText)
        {
          image (pg, 0, 0);
          rawTxt.display();
          listed.display();
        }
        else {
          if (animate)
          {
            if (textAnalyzer.getAnimation())
            {
              textAnalyzer.createWordArrayList("utf", aninmationCount);
              txt = textAnalyzer.getWordArray();
              aninmationCount++;
            }
          }
          displayBG(false, 10);
          displayGraph(false);
          if (showHeadline) displayHeadline(false, 0, int (height/2.0 - height/5.0), 30, 15);
        }
      }
    
      private void displayBG (boolean writeToImage, int padd)
      {
        if (writeToImage)
        {
          pg.background ((Integer) colors.get("bg"));
          pg.noStroke();
          pg.fill ((Integer) colors.get("bgRect"));
          pg.rect (padd, padd, width-padd*2, height-padd*2);
        }
        else
        {
          background ((Integer) colors.get("bg"));
          noStroke();
          fill ((Integer) colors.get("bgRect"));
          rect (padd, padd, width-padd*2, height-padd*2);
        }
      }
    
      private void displayHeadline (boolean writeToImage, int x, int y, int s, int padd)
      {
    
        color c = (Integer) colors.get("highlight");
    
        if (writeToImage)
        {
          pg.textFont (this.font, s);
          pg.textAlign (LEFT);
          pg.noStroke();
    
          pg.fill (red (c), green(c), blue (c), 200);
          pg.rect (x, y, padd*2 + textWidth (title), s*1.4);
    
          pg.fill ((Integer) colors.get("bgRect"));
          pg.text (title, x+padd, y+s);
        }
        else {
          textFont (this.font, s);
          textAlign (LEFT);
          noStroke();
    
          fill (hue (c), saturation(c), brightness (c), 200);
          rect (x, y, padd*2 + textWidth (title), s*1.4);
    
          fill ((Integer) colors.get("bgRect"));
          text (title, x+padd, y+s);
        }
      }
    
      // ----------------------------------------------------------------------------------------------------
      // Graph
      // ----------------------------------------------------------------------------------------------------
    
      private void displayGraph (boolean writeToImage)
      {
        textFont (font);
        float angle = 0.0;
        float steps = 360.0 / (float) fullSize;
        if (animationMode == 1 && animate) {
          if (textAnalyzer.getAnimation()) {
            if (aninmationCount != 0) steps = 360.0 / (float) aninmationCount;
            else steps = 360.0;
          }
          else steps = 360.0 / (float) fullSize;
        }
        boolean active = false, hover = false;
        int id = -1;
        int [] index;
    
        for (int i = 0; i < txt.length; i++)
        {
          hover = false;
          index = txt[i].getIndex();
    
          angle += steps*(float) index.length/2.0;
    
          PVector p1 = createPos (angle, dBig, pos);  
    
          if (!active && checkHover(p1.x, p1.y, steps*(float) index.length*2.0)) 
          {
            addText (str (txt[i].getCount()) + "x " + txt[i].getTxt(), pos.x, 40, 24, "center", 'u');
            active = true;
            hover = true;
            id = i;
          }
          else {       
            hover = false;
          }
    
          showConnections (writeToImage, angle, index, i, p1);
    
          showWordIndex (writeToImage, index, p1.x, p1.y, steps*(float) index.length*4.0, angle, strokeW, hover);
          //addEllipse (p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), hover);
          angle += steps*(float) index.length/2.0;
        }
    
        angle = 0.0;
    
        for (int i = 0; i < txt.length; i++)
        {
          index = txt[i].getIndex();
          angle += steps*(float) index.length/2.0;
          PVector p1 = createPos (angle, dBig, pos);  
    
          if (i == id) addEllipse (writeToImage, p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), true);
          else addEllipse (writeToImage, p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), false);
          angle += steps*(float) index.length/2.0;
        }
      }
    
      private void showConnections (boolean writeToImage, float angle, int [] index, int i, PVector p1)
      {
        ArrayList apositions = new ArrayList();
        float mangle = lerp (angle, 360.0 / (float) txt.length *txt [i].getLast(), 0.5);
        if (angle - 360.0 / (float) txt.length *txt [i].getLast() > 180) mangle -= 180;
    
        apositions.add (p1);
        apositions.add (createPos (mangle, dBig + dBig / (float) index.length / 2.0, pos));
        apositions.add (createPos (360.0 / (float) txt.length *txt [i].getLast(), dBig, pos));
        if (angle - 360.0 / (float) txt.length *txt [i].getLast() > 90) apositions.add (2, createPos (lerp (angle, 360.0 / (float) txt.length *txt [i].getLast(), 0.75), dBig + abs (width-2*dBig) / (float) index.length, pos));
    
        PVector [] positions = arrayListToPVector(apositions);
        if (index.length > 2) addCurve (writeToImage, positions, (Integer) colors.get("connections"), strokeW+0.12*(float)index.length);
      }
    
      private void showWordIndex (boolean writeToImage, int [] index, float x, float y, float xd, float angle, float strokeW, boolean hover)
      {
        PVector [] positions = new PVector [4];
    
        for (int j = 0; j < index.length; j++)
        {
          positions [0] = createPos (360.0 / (float) index.length * (float) j, xd/2, new PVector (x, y));
          positions [3] = createPos (360.0 / (float) fullSize * (float) index [j], dSmal, pos);
          positions [1] = createPos (lerp (angle, 360.0 / (float) fullSize * (float) index [j], measure), lerp (dBig, dSmal, (float) j / (float) index.length), pos);
          positions [2] = createPos (lerp (360.0 / (float) fullSize * (float) index [j], angle, measure), lerp (dSmal, dBig, (float) j / (float) index.length), pos );
    
          addCurve (writeToImage, positions, strokeW / (float) index.length, hover);
        }
      }
    
      // ----------------------------------------------------------------------------------------------------
      // Visuals
      // ----------------------------------------------------------------------------------------------------
    
      private void addText (String txt, float x, float y, int s, String align, char h)
      {
        noStroke ();
        fill ((Integer) colors.get("highlight"));
        if (align.equals ("left")) textAlign (LEFT);
        else if (align.equals ("center")) textAlign (CENTER);
        else textAlign (RIGHT);
        if (h == 'u') txt = txt.toUpperCase();
        textFont (this.font, s);
        text (txt, x, y);
      }
    
      private void addCurve (boolean writeToImage, PVector [] positions, float sW, boolean hover)
      {
    
        if (hover) 
        {
          sW = strokeW;
          if (writeToImage) {
            color t = (Integer) colors.get("highlight");
            pg.stroke ((Integer) colors.get("highlight"));
          }
          else stroke ((Integer) colors.get("highlight"));
        }
        else {
          if (writeToImage) {
            color t = (Integer) colors.get("stroke");
            pg.stroke ((Integer) colors.get("stroke"));
          }
          else stroke ((Integer) colors.get("stroke"));
        }
        if (writeToImage) {
          pg.noFill();
          pg.strokeWeight (sW);
          pg.beginShape();
        }
        else {
          noFill();
          strokeWeight (sW);
          beginShape();
        }
        for (int i = 0; i < positions.length; i++)
        {
          if (writeToImage) {
            pg.curveVertex (positions[i].x, positions[i].y);
            if (i == 0 ||i ==  positions.length-1)  pg.curveVertex (positions[i].x, positions[i].y);
          } 
          else {
            curveVertex (positions[i].x, positions[i].y);
            if (i == 0 ||i ==  positions.length-1)  curveVertex (positions[i].x, positions[i].y);
          }
        }
        if (writeToImage) pg.endShape();
        else endShape();
      }
    
      private void addCurve (boolean writeToImage, PVector [] positions, int c, float sW)
      {
        if (writeToImage)
        {
          pg.strokeWeight (sW);
          pg.stroke (c);
          pg.noFill();
          pg.beginShape();
        } 
        else
        {
          strokeWeight (sW);
          stroke (c);
          noFill();
          beginShape();
        }
        for (int i = 0; i < positions.length; i++)
        {
          if (writeToImage) {
            pg.curveVertex (positions[i].x, positions[i].y);
            if (i == 0 ||i ==  positions.length-1)  pg.curveVertex (positions[i].x, positions[i].y);
          } 
          else {
            curveVertex (positions[i].x, positions[i].y);
            if (i == 0 ||i ==  positions.length-1)  curveVertex (positions[i].x, positions[i].y);
          }
        }
        if (writeToImage) pg.endShape();
        else endShape();
      }
    
      private void addEllipse (boolean writeToImage, float x, float y, float d, float sW, boolean hover)
      {
        if (writeToImage) {
          if (hover) pg.fill ((Integer) colors.get("highlight"));
          else pg.fill ((Integer) colors.get("ellipse"));
        }
        else
        {
          if (hover) fill ((Integer) colors.get("highlight"));
          else fill ((Integer) colors.get("ellipse"));
        }
    
        if (sW < d)
        {
          if (writeToImage) {
            pg.strokeWeight (sW);
            pg.stroke ((Integer) colors.get("ellipseStroke"));
          }
          else {
            strokeWeight (sW);
            stroke ((Integer) colors.get("ellipseStroke"));
          }
        }
        else {
          if (writeToImage) pg.noStroke();
          else noStroke();
        }
        if (writeToImage) pg.ellipse (x, y, d, d);
        else ellipse (x, y, d, d);
      }
    }
    
    
    class TextAnalyzer
    {
      private ArrayList fullTxt, words;
      private Word [] wordArray;
      private int last;
      private String [] rawTxt;
      private PFont font;
      private boolean animate, isAnimating;
    
      public TextAnalyzer (String loadPath, String inputFormat, boolean animate)
      {
        this.animate = animate;
        if (animate) isAnimating = true;
        fullTxt = new ArrayList();
        words = new ArrayList();
        this.font = createFont ("Verdana", 12);
    
        splitText (loadStrings (loadPath));
        if (!animate) createWordArrayList(inputFormat);
        //createWordArray();
      }
    
      public TextAnalyzer (String loadString, boolean animate)
      {
        this.animate = animate;
        if (animate) isAnimating = true;
        fullTxt = new ArrayList();
        words = new ArrayList();
        this.font = createFont ("Verdana", 12);
    
        String [] temp = { 
          loadString     };
        splitText (temp);
        if (!animate) createWordArrayList("ansi");
        //createWordArray();
      }
    
      public boolean getAnimation ()
      {
        if (animate && isAnimating) return true;
        else return false;
      }
    
      public boolean getMode ()
      {
        return animate;
      }
    
      public int getFullSize()
      {
        return fullTxt.size();
      }
    
      public Word [] getWordArray()
      {
        createWordArray();
        return wordArray;
      }
    
      public String getRawTxt ()
      {
        String raw = "";
    
        for (int i = 0; i < rawTxt.length; i++)
        {
          raw += rawTxt [i] + " ";
        }
        return raw;
      }
    
      private void splitText (String [] rawTxt)
      {
        this.rawTxt = rawTxt;
        String tokens = ",.;:-_!?&\"□▫¶~ +%=()[]{}«»#&%§'|";
        for (int i = 0; i < rawTxt.length; i++)
        {
          String [] rowTxt = splitTokens (rawTxt [i], tokens);
    
          for (int j = 0; j < rowTxt.length; j++)
          {
            fullTxt.add (new String (rowTxt [j]));
          }
        }
      }
    
      private String removeFirstChar (String word)
      {
        char [] c = new char [word.length()-1];
        for (int k = 0; k < c.length; k++)
        {
          c [k] = word.charAt(k+1);
        }
    
        return new String (c);
      }
    
      private void createWordArrayList (String textFormat)
      {
        // ertser Eintrag
        // words.add (new String ((String) fullTxt.get (0)));
    
        boolean found = false;
    
        for (int i = 0; i < fullTxt.size(); i++)
        {
          String full = (String) fullTxt.get(i);
          //println(i + ", Words: " + words.size());
          if (words.size() == 0)
          {
            //erster Eintrag
            if (textFormat.equals("utf")) full = removeFirstChar(full);
            words.add (new Word (full, 0, 0));
          }
          else {
            found = false;
    
            for (int j = 0; j < words.size(); j++)
            {
              Word temp = (Word) words.get (j);
    
              if (temp.getTxt().equals ( full.toLowerCase()))
              {
                // wort in liste gefunden
                temp.increase(i);
                found = true;
              }
    
              if (found)
              {
                j =  words.size();
                continue;
              }
            }
    
            if (!found)
            {
              //neues Wort
              quicksort (full.toLowerCase(), words.size(), 0, i);
            }
    
          }
        }
      }
    
      private void createWordArrayList (String textFormat, int count)
      {
        // ertser Eintrag
        // words.add (new String ((String) fullTxt.get (0)));
    
        boolean found = false;
    
        if (count < fullTxt.size())
        {
          String full = (String) fullTxt.get(count);
          //println(i + ", Words: " + words.size());
          if (words.size() == 0)
          {
            //erster Eintrag
            if (textFormat.equals("utf")) full = removeFirstChar(full);
            words.add (new Word (full, 0, 0));
          }
          else {
            found = false;
    
            for (int j = 0; j < words.size(); j++)
            {
              Word temp = (Word) words.get (j);
    
              if (temp.getTxt().equals ( full.toLowerCase()))
              {
                // wort in liste gefunden
                temp.increase(count);
                found = true;
              }
    
              if (found)
              {
                j =  words.size();
                continue;
              }
            }
    
            if (!found)
            {
              //neues Wort
              quicksort (full.toLowerCase(), words.size(), 0, count);
            }
    
          }
        }
        else {
          isAnimating = false;
        }
      }
    
      private void quicksort (String input, float iSize, float index, int txtIndex)
      {
    
        if (round (iSize) == 1)
        {
          int i = round (index);
          Word listedWord = (Word) words.get (i);
          String listed = listedWord.getTxt(); 
    
          if (compareString (input, listed)) addWord (input, i+1, txtIndex);
          else addWord (input, i, txtIndex);
        }
        else {
          int i = floor (index+iSize/2.0);
    
          Word listedWord = (Word) words.get (i);
          String listed = listedWord.getTxt(); 
    
          if (compareString (input, listed)) quicksort (input, iSize/2.0, index+iSize/2.0, txtIndex);
          else quicksort (input, iSize/2.0, index, txtIndex);
        }
      }
    
      private boolean compareString (String input, String listed)
      {
    
        int dir  = input.compareTo(listed);
    
        if (dir > 0 ) return true;
        else return false;
      }
    
      private void addWord (String input, int pos, int txtIndex)
      {
        words.add (pos, new Word (input, txtIndex, last));
        last = pos;
      }
    
      private void createWordArray()
      {
        wordArray = new Word [words.size()];
    
        for (int i = 0; i < wordArray.length; i++)
        {
          wordArray [i] = (Word) words.get (i);
        }
      }
    
      public void displayArrayList ()
      {
        textFont (this.font, 12);
        fill (5);
        noStroke();
    
        float x = 20, y = 20;
    
        for (int i = 0; i < words.size(); i++)
        {
          Word temp = (Word) words.get(i);
    
          text (nf (i, 3, 0) + ". " + temp.getTxt() + ", " + str (temp.getCount()), x, y);
    
          y+= 15;
    
          if (y >= height -15)
          {
            y = 20;
            x += 100;
          }
        }
      }
    
      public void display ()
      {
        textFont (this.font, 12);
        fill (5);
        noStroke();
    
        float x = 20, y = 20;
    
        for (int i = 0; i < wordArray.length; i++)
        {
          text (nf (i, 3, 0) + ". " + wordArray[i].getTxt() + ", " + str (wordArray[i].getCount()), x, y);
    
          y+= 15;
    
          if (y >= height -15)
          {
            y = 20;
            x += 100;
          }
        }
      }
    }
    
    
    
    class TextDisplayer
    {
      private PFont font;
      private String txt;
      private int s; // fontSize
      private float totalHeight; // total height for displaying all text;
      private float startY /* position of first row of the text*/, sliderY /*position of slider*/, sliderWidth;
      private HashMap colors;
      private int x, y, w, h, padding;
      private String [] splitted;
      private PImage bg;
      private boolean listed;
    
      TextDisplayer (String txt, int [] borders, int s, HashMap colors, boolean listed)
      {
        this.listed = listed;
        this.s = s;
        this.txt = txt;
        this.font = createFont ("Arial", s);
        bg = createImage (borders [2], borders [3], ARGB);
        splitted = split (txt, " ");
        x = borders [0];
        y = borders [1];
        w = borders [2];
        h = borders [3];
        padding = borders [4];
        this.colors = colors;
        startY = sliderY = borders [1] + borders [4];
        createTotalHeight();
      }
    
      TextDisplayer (String [] txt, int [] borders, int s, HashMap colors, boolean listed)
      {
        this.listed = listed;
        this.s = s;
        this.txt = "";
        bg = createImage (borders [2], borders [3], ARGB);
        for (int i = 0; i < txt.length; i++)
        {
          this.txt += txt[i];
        }
    
        this.font = createFont ("Arial", s);
        splitted = txt;
        x = borders [0];
        y = borders [1];
        w = borders [2];
        h = borders [3];
        padding = borders [4];
        this.colors = colors;
        startY = sliderY = borders [1] + borders [4];
        createTotalHeight(); // check if the text fits into the created window and / or calculate how much height the next needs == totalHeight
      }
    
      public void setTxt (String [] txt)
      {
        this.txt = "";
        bg = createImage (w, h, ARGB);
        for (int i = 0; i < txt.length; i++)
        {
          this.txt += txt[i];
        }
    
        splitted = txt;
        createTotalHeight(); 
      }
    
      public void setBG (PImage img)
      {
        System.arraycopy(img.pixels, 0, bg.pixels, 0, bg.pixels.length);
        bg.updatePixels();
      }
    
      public int getX ()
      {
        return x;
      }
    
      public int getY ()
      {
        return y;
      }
    
      public int getWidth ()
      {
        return w;
      }
    
      public int getHeight ()
      {
        return h;
      }
    
      public void createTotalHeight()
      {
        float textx = x + padding, texty = y + padding + s;
        textFont (this.font, s);
        textAlign (LEFT);
    
        for (int i = 0; i < splitted.length; i++)
        {     
          if (!listed)
          {
            textx += textWidth (splitted[i] + " ");
            if (i < splitted.length-1 && checkNext (splitted [i+1], textx) )
            {
              textx = x + padding;
              texty += s * 1.5;
            }
          }
          else texty += s * 1.5;
        }
        if ( texty > h ) 
        {
          totalHeight = texty + padding;
          sliderWidth = padding * 3/5;
        }
        else {
          totalHeight = h;
          sliderWidth = 0;
        }
      }
    
      public void display()
      {
        image (bg, x, y);
        fill ((Integer) colors.get("bg"));
        rect (x, y, w, h);
        fill ((Integer) colors.get("text"));
    
        float textx = x + padding, texty = startY + s;
        textFont (this.font, s);
        textAlign (LEFT);
    
        for (int i = 0; i < splitted.length; i++)
        {
          if (!listed)
          {
            if ( texty >= y + padding + s && texty < y + h - padding ) text (splitted [i]+ " ", textx, texty);
            textx += textWidth (splitted[i] + " ");
            if (i < splitted.length-1 && checkNext (splitted [i+1], textx) )
            {
              textx = x + padding;
              texty += s * 1.5;
            }
          }
          else {
            if ( texty >= y + padding + s && texty < y + h - padding ) text (splitted [i]+ " ", textx, texty);
            texty += s * 1.5;
          }
        }
    
        if (totalHeight > h)
        {
          noStroke ();
          fill ((Integer) colors.get("scrollbarBG"));
    
          rect (x + w - sliderWidth, y + padding, sliderWidth, h - 2 * padding);
    
          float mapped = ((float) h - 2.0 * (float) padding) / (float) totalHeight * 100; // == sliderBth height
          if (mapped <  10) mapped = 10;
    
          if (checkHover (x + w - sliderWidth, y + padding, sliderWidth, h - 2 * padding)) {
            fill ((Integer) colors.get("highlight"));
            if (mousePressed)
            {
              sliderY = mouseY;
              if (sliderY + mapped > y + h - padding) sliderY = y + h - padding - mapped;
              if (sliderY < y +padding) sliderY = y + padding;
              startY =  map (sliderY, y + padding, y + h - padding - mapped, y + padding, y - totalHeight + h + 2 * padding);
            }
          }
          else fill ((Integer) colors.get("scrollbar"));
          rect (x + w - sliderWidth, sliderY, sliderWidth, mapped);
        }
      }
    
      private boolean checkNext (String next, float currentx)
      {
        if ( (currentx += textWidth (next)) > x - padding + w ) return true;
        else return false;
      }
    }
    
    
    class Word 
    {
      private String txt;
      private int count;
      private int last;
      private int letters;
      private ArrayList index = new ArrayList();
    
      public Word (String txt, int index, int last)
      {
        this.txt = txt.toLowerCase();
        this.last = last;
        letters = this.txt.length();
        count = 1;
        this.index.add (new Float (index));   
      }
    
      public int [] getIndex ()
      {
        int [] indexArray = new int [index.size()];
    
        for (int i = 0; i < index.size(); i++)
        { 
          indexArray [i] = int ( (Float) index.get(i) );
        }
        
        return indexArray;
      }
      
      public int getLength()
      {
        return letters;
      }
      
      public int getLast()
      {
        return last;
      }
    
      public int getFirstIndex ()
      {
        return int ( (Float) index.get(0) );
      }
    
      public String getTxt ()
      {
        return txt;
      }
    
      public int getCount()
      {
        return count;
      }
    
      public void increase (int index)
      {
        this.index.add (new Float (index));
        count++;
      }
    }
    
    
    // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
    
    void fastblur(PImage img,int radius){
    
      if (radius<1){
        return;
      }
      int[] pix=img.pixels;
      int w=img.width;
      int h=img.height;
      int wm=w-1;
      int hm=h-1;
      int wh=w*h;
      int div=radius+radius+1;
    
      int r[]=new int[wh];
      int g[]=new int[wh];
      int b[]=new int[wh];
      int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
      int vmin[] = new int[max(w,h)];
    
      int divsum=(div+1)>>1;
      divsum*=divsum;
      int dv[]=new int[256*divsum];
      for (i=0;i<256*divsum;i++){
        dv[i]=(i/divsum);
      }
    
      yw=yi=0;
    
      int[][] stack=new int[div][3];
      int stackpointer;
      int stackstart;
      int[] sir;
      int rbs;
      int r1=radius+1;
      int routsum,goutsum,boutsum;
      int rinsum,ginsum,binsum;
    
      for (y=0;y<h;y++){
        rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
        for(i=-radius;i<=radius;i++){
          p=pix[yi+min(wm,max(i,0))];
          sir=stack[i+radius];
          sir[0]=(p & 0xff0000)>>16;
          sir[1]=(p & 0x00ff00)>>8;
          sir[2]=(p & 0x0000ff);
          rbs=r1-abs(i);
          rsum+=sir[0]*rbs;
          gsum+=sir[1]*rbs;
          bsum+=sir[2]*rbs;
          if (i>0){
            rinsum+=sir[0];
            ginsum+=sir[1];
            binsum+=sir[2];
          } else {
            routsum+=sir[0];
            goutsum+=sir[1];
            boutsum+=sir[2];
          }
        }
        stackpointer=radius;
    
        for (x=0;x<w;x++){
    
          r[yi]=dv[rsum];
          g[yi]=dv[gsum];
          b[yi]=dv[bsum];
          
          rsum-=routsum;
          gsum-=goutsum;
          bsum-=boutsum;
    
          stackstart=stackpointer-radius+div;
          sir=stack[stackstart%div];
          
          routsum-=sir[0];
          goutsum-=sir[1];
          boutsum-=sir[2];
          
          if(y==0){
            vmin[x]=min(x+radius+1,wm);
          }
          p=pix[yw+vmin[x]];
          
          sir[0]=(p & 0xff0000)>>16;
          sir[1]=(p & 0x00ff00)>>8;
          sir[2]=(p & 0x0000ff);
    
          rinsum+=sir[0];
          ginsum+=sir[1];
          binsum+=sir[2];
    
          rsum+=rinsum;
          gsum+=ginsum;
          bsum+=binsum;
          
          stackpointer=(stackpointer+1)%div;
          sir=stack[(stackpointer)%div];
         
          routsum+=sir[0];
          goutsum+=sir[1];
          boutsum+=sir[2];
         
           rinsum-=sir[0];
          ginsum-=sir[1];
          binsum-=sir[2];
         
           yi++;
        }
        yw+=w;
      }
      for (x=0;x<w;x++){
        rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
        yp=-radius*w;
        for(i=-radius;i<=radius;i++){
          yi=max(0,yp)+x;
         
           sir=stack[i+radius];
          
          sir[0]=r[yi];
          sir[1]=g[yi];
          sir[2]=b[yi];
         
          rbs=r1-abs(i);
          
          rsum+=r[yi]*rbs;
          gsum+=g[yi]*rbs;
          bsum+=b[yi]*rbs;
         
          if (i>0){
            rinsum+=sir[0];
            ginsum+=sir[1];
            binsum+=sir[2];
          } else {
            routsum+=sir[0];
            goutsum+=sir[1];
            boutsum+=sir[2];
          }
          
          if(i<hm){
            yp+=w;
          }
        }
        yi=x;
        stackpointer=radius;
        for (y=0;y<h;y++){
          pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
    
          rsum-=routsum;
          gsum-=goutsum;
          bsum-=boutsum;
    
          stackstart=stackpointer-radius+div;
          sir=stack[stackstart%div];
         
          routsum-=sir[0];
          goutsum-=sir[1];
          boutsum-=sir[2];
         
           if(x==0){
            vmin[y]=min(y+r1,hm)*w;
          }
          p=x+vmin[y];
          
          sir[0]=r[p];
          sir[1]=g[p];
          sir[2]=b[p];
          
          rinsum+=sir[0];
          ginsum+=sir[1];
          binsum+=sir[2];
    
          rsum+=rinsum;
          gsum+=ginsum;
          bsum+=binsum;
    
          stackpointer=(stackpointer+1)%div;
          sir=stack[stackpointer];
         
          routsum+=sir[0];
          goutsum+=sir[1];
          boutsum+=sir[2];
          
          rinsum-=sir[0];
          ginsum-=sir[1];
          binsum-=sir[2];
    
          yi+=w;
        }
      }
      
      img.updatePixels();
    }
    
    boolean animate = false;
    
    void keyPressed ()
    { 
      if (keyCode == KeyEvent.VK_SPACE) vis.displayMode();
      if (keyCode == KeyEvent.VK_RIGHT) vis.measureUp();
      if (keyCode == KeyEvent.VK_LEFT) vis.measureDown();
      if (keyCode == KeyEvent.VK_H) vis.toggleHeadline();
      if (keyCode == KeyEvent.VK_S) vis.toggleAnimationMode();
      if (keyCode == KeyEvent.VK_A)
      {
        animate = !animate;
        vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
      }
      /*
      if (keyCode == KeyEvent.VK_M) {
        saveMov = !saveMov;
        if (saveMov) {
          mm = new MovieMaker(this, width, height, "export/" + timestamp() + "_data.mov", 30, MovieMaker.ANIMATION, MovieMaker.HIGH);
          vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
        }
      }
      
      if (keyCode == KeyEvent.VK_E)
      {
        if (saveMov) mm.finish();
        saveMov = false;
      }
       if (keyCode == KeyEvent.VK_P) savePDF = !savePDF;
       if (keyCode == KeyEvent.VK_O) saveFrame ( "export/" + timestamp() + ".png");
       */
    }
    
    
    // ----------------------------------------------------------------------------------------------------
    // Tools
    // ----------------------------------------------------------------------------------------------------
    
    String [] wordArrayToStringArray(Word [] words)
    {
      String [] txt = new String [words.length];
      
      for (int i = 0; i < txt.length; i++)
      {
        txt[i] = nf(i, 4, 0) + " [" + nf(words[i].getFirstIndex(), 4, 0) + "] " + words[i].getTxt() + " " + str(words[i].getCount()) + "x";
      }
      
      return txt;
    }
    
    PVector [] arrayListToPVector (ArrayList listed)
    {
      PVector [] vector = new PVector [listed.size()];
    
      for (int i = 0; i < vector.length; i++)
      {
        vector [i] = (PVector) listed.get(i);
      }
    
      return vector;
    }
    
    int [] arrayListToInt (ArrayList listed)
    {
      int [] in = new int [listed.size()];
    
      for (int i = 0; i < in.length; i++)
      {
        in [i] = (Integer) listed.get(i);
      }
    
      return in;
    }
    
    PVector createPos (float angle, float d, PVector pvCenter)
    {
      PVector position = new PVector (pvCenter.x + cos (radians (angle))*d, pvCenter.y + sin (radians (angle))*d);
      return position;
    }
    
    boolean checkHover (float x, float y, float d)
    {
      if (dist (mouseX, mouseY, x, y) < d) return true;
      else return false;
    }
    
    boolean checkHover (float x, float y, float w, float h)
    {
      if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) return true;
      else return false;
    }
    
    String timestamp()
    {
      String time, year, month, day, hour, minute, second;
    
      year = nf( year(), 4 );
      month = nf( month(), 2 );
      day = nf( day(), 2 );
      hour = nf( hour(), 2 );
      minute = nf( minute(), 2 );
      second = nf( second(), 2 );
    
      time = year + "_" + month + "_" + day + "_" + hour + "_" + minute + "_" + second;
    
      return time;
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Diana Lange

    Visualizing text

    Add to Faves Me Likey@! 107
    You must login/register to add this sketch to your favorites.

    Playing again with text data. The goal was to write an effective and fast algorithm for sorting text in an alphabetical order using the 'divide and conquer' method / recursion which would work with my written 'Word' class.

    Controls:
    Hover circle = shows word and how often it was found in text
    Space = Text on / off
    H = Headline on / off
    A = Animation on / off
    S = Animation mode
    Left / Right = Position of control points

    Check video:
    http://vimeo.com/31203226

    Flickr:
    http://www.flickr.com/photos/dianalange/sets/72157627657832455/

    ale plus+
    1 Nov 2011
    Really good work, it reminds me one of Boris Muller works for Poetry on the Road:
    http://www.esono.com/boris/projects/poetry06/
    regards
    ^-^
    Diana Lange
    1 Nov 2011
    Thanx. Actually Boris Müller held a presentation about his work in 2008 at my university. After that I wanted to learn programming, which I started one semester afterwards.
    ale plus+
    2 Nov 2011
    Yep, he is also one of my reference, say, 'coding artists'. I love his work on Poetry on the Road, it´s one of the best examples on how you can blend coding skills and superb graphic design.
    ^-^
    this is very very VERY inspiring
    Klaus Rummler
    26 Jun 2013
    Hi Diana,
    Your script is very cool.
    Could you please help me to tweak the script a little in order to shorten() the word array by common German or English words. I am quite new to processing and I`m eager to learn. What I`ve got is sth like this in classTextAnalyzer after line 77.

    String [] excludeWords = { "die" , "der" , "das" , "da" , "ein" , "einer"};
    excludeWords = shorten(rowTxt);

    It doesn`t work of course but I hope you could quickly help me a bit.

    All the best
    @klausr
    Diana Lange
    26 Jun 2013
    Hi,

    I wouldn't shorten the list, but prevent the exluded words to be added to the list. This might look like this:

    <<< class TextAnalyzer >>>

    String [] excludeWords = { "die" , "der" , "das" , "da" , "ein" , "einer"};

    void createWordArrayList (String textFormat)
    {
    (...)
    if (!checkWord (excludeWords, full))
    {
    words.add (new Word (full, 0, 0));
    }
    (...)
    }

    boolean checkWord (String [] excluded, String lookup)
    {
    for (int i = 0; i < excluded.length; i++) if (excluded[i].equals (lookup)) return true;
    else return false;
    }
    Klaus Rummler
    26 Jun 2013
    Thanks a lot.
    Although it didn`t work right away I`ll keep trying and will report
    Lukasz Zyla
    26 Jun 2013
    Hi Diana,
    "cannot find anything named "KeyEvent.VK_SPACE"". I have no idea what is wrong :/
    Diana Lange
    26 Jun 2013
    The KeyEvent thing is a Java default which is no longer included since Processing 2.0. The question about that seems to come regulary. But sorry to say that, if you're not able to change a simple key condition you will not understand anything else of my code.

    http://processing.org/reference/key.html
    Klaus Rummler
    26 Jun 2013
    Just use the old Processing Version 1.5.1. It worked for me
    Lyndie Chiou plus+
    29 Jul 2013
    wow
    Dave Sun
    24 Apr 2014
    The file "buergschaft.txt" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable. I check this file is located in "Data" folder , see any something wrong in processing 2.0 ?
    RoIT TW
    14 Jun 2014
    Dave, I had the same error message about the buergschaft.txt file, which is assumed in the subdirectory data if only with file name identified. However, if full path of file name identified, it works.
    Loreto E. Torres
    17 Jul 2014
    It's unfortunate that my Mac (OS X Mavericks) consider this app unsafe. I cannot find a way to get around it.

    Too bad, I cannot take a "look" at the sketch. :-(
    Mick Paulusma
    6 Oct 2014
    I am quite new Processing but have a background in data analysis and a keen interest in film and design - these is very inspiring. Thank you
    Emily Arec
    3 Dec 2014
    Kol ha kavod. כָּל הַכָּבוֹד

    Hallo Diana, Do you have any idea how I could throw some random words onto a sketch window i.e. (in, ”, beholder, the, of, is, eye, “, Beauty, the) animate them, have them dance in sketch window, move around on some nice background and then ask the user to make up a sentence/saying/ or some verse using those words (word puzzle of sorts). I would want them to come up with “Beauty is in the eye of the beholder” of course. Would the user be able to drag the words below to make up a sentence or how could this be done? How could I reward the user for getting it right? Light up the verse/ saying? Any ideas? Cheers.
    Diana Lange
    3 Dec 2014
    @ Emily: 42
    You need to login/register to comment.