Tagging Strings in a visualization

Hi,

I was trying to create a small visualization using processing. I have an array of numbers showing years and another array showing some names associated with the years mentioned in the previous array. the aim of the visualization is to create a small timeline with years and the related names grouped.

I was able to plot the year and the points in the visualization, but didn't able to tag the points with the names. Would be great if someone can help me with this :)

The code is as follows

    String [] year =   {"1901", "1901", "1902", "1903", "1903", "1903"};
    String [] name = {"name1", "name2", "name3", "name4", "name5", "name6"};

    int [] fyear ;
    String [] nyear ;
    IntDict Years;

    void setup() {

      size(500, 500);
      smooth();

      Years = new IntDict();


      fyear = new int [Years.size()];

      nyear = new String [Years.size()];


      for (int i =0; i<year.length; i++) {

        Years.increment(year[i]);
      }

      fyear  = Years.valueArray();
      nyear  = Years.keyArray();
      println(name.length);
    }

    void draw() {
      background(15);


      for (int i=0; i<Years.size(); i++) {


        for (int j=0; j<fyear[i]; j++) {

          fill(255);
          rect(100+50*i, 300+50*j, 40, 40);

          textSize(15);
          fill(255, 0, 0);
          text(nyear[i], 100+50*i, 280 );

          textSize(10);
          fill(85);

          text("name", 105+50*i, 320 +50*j);
        }
      }
    }

The current and expected out put are as follows

output

Answers

  • you're using a constant "name" in line 50. use i as an index into the name array instead...

  • thanks for the reply @koogs. I actually tried with both 'i' and 'j' as the index. it didn't work. the index must be a series from 0 to 5. the value of 'i' is only from 0 to 2.

  • sorry, i didn't run it, am at work, was just looking for obvious things.

    you need to tie the years in with the names, but you lose position information when you put them in the dict. you need some way of keeping this link. traditionally you'd use a class containing both year and name... i will try and think of a way to avoid this.

  • Answer ✓

    i rewrote this to use advanced objects, a treemap of lists, as there was no other way of maintaining the structure of the data.

    import java.util.List;
    import java.util.TreeMap;
    
    String [] year =   {"1901", "1901", "1902", "1903", "1903", "1903"};
    String [] name = {"name1", "name2", "name3", "name4", "name5", "name6"};
    
    // a Treemap will keep the keys (1901...) sorted
    // a list can contain multiple values (name, name...), in insertion order
    // so basically you can store
    // 1901: name1, name2
    // 1902: name3
    // 1903: name4, name5, name6
    TreeMap<String, List<String>> years;
    
    void setup() {
    
      size(500, 500);
      smooth();
    
      years = new TreeMap<String, List<String>>();
    
      for (int i = 0 ; i < year.length ; i++) {
        if (years.get(year[i]) == null) {
          // we haven't seen this year before, so make a new list for this year
          years.put(year[i], new ArrayList<String>());
        }
        // add relevant name to the list for this year
        years.get(year[i]).add(name[i]);
      }
    
      // data isn't change, so why redraw?
      noLoop();
    }
    
    void draw() {
      background(15);
    
      // loop through all the years
      int i = 0;
      for (String key : years.keySet()) {
    
        // get the list for this year
        List<String> yearList = years.get(key);
        // and draw all the boxes therein
        for (int j = 0 ; j < yearList.size() ; j++) {
    
          fill(255);
          rect(100 + 50 * i, 300 + 50 * j, 40, 40);
    
          textSize(15);
          fill(255, 0, 0);
          text(key, 100 + 50 * i, 280);
    
          textSize(10);
          fill(85);
    
          text(yearList.get(j), 105 + 50 * i, 320 + 50 * j);
        }
        i++;
      }
    }
    
  • edited February 2016

    a TreeMap of lists, as there was no other way of maintaining the structure of the data.

    Processing's IntDict, FloatDict & StringDict keep insertion order.
    Dunno where did you hear about otherwise! :-@
    Not only that, they've also got methods to sort by keys & values, ascending & descending orders:

    1. https://Processing.org/reference/IntDict_sortKeys_.html
    2. https://Processing.org/reference/IntDict_sortKeysReverse_.html
    3. https://Processing.org/reference/IntDict_sortValues_.html
    4. https://Processing.org/reference/IntDict_sortValuesReverse_.html

    I've done an experiment w/ IntDict here:
    https://forum.Processing.org/two/discussion/14393/getting-the-dominant-color-of-an-image#Item_3

    P.S.: Of course something like text("name", 105 + 50*i, 320 +50*j); is gonna display "name" only! :-\"

  • that won't work here because you need multiple values for the same key (assuming you're using the years for the keys)

    it might work using names as the keys... will try...

  • That's great! Thanks a lot @koogs :) :)

  • edited February 2016

    Indeed key/value pair datatype for that is at very minimum <Short, StringList>.
    Just b/c I've never used TreeMap before, I'd go w/ LinkedHashMap<Short, StringList> myself.

    That's what I did for "Dominant Color Sort II" & "Dominant Color Sort III" below:
    https://forum.Processing.org/two/discussion/14393/getting-the-dominant-color-of-an-image#Item_4

    Nonetheless, your TreeMap<String, List> is quite valid.
    I'd only change it to something simpler like TreeMap<Integer, StringList> instead. :ar!

  • linked hash map maintains insertion order, treemap maintains 'natural' key order.

    StringList might be handy but isn't available in 1.5.1... i've only moved to p3 in the last month or so.

    (p3 uses a lot of cpu for something that calls noLoop(), at least on my laptop. but not always. even the same program will be different on two consecutive runs)

Sign In or Register to comment.