treemap - speeding up the range slider
in
Contributed Library Questions
•
1 year ago
I want a range slider for a treemap (for a quite complex project).
To easy things up i first stared on the included equator_03b.pde example (examples > books > visualizing data > ch07-hierarchies).
I added a id to class WordItem and idCount to the class WordMap as well the function rangeFinishAdd(minId, maxId)
(instand if id i will use dates for my project but that won't be much harder).
About the range slider, it works but it's really slow when setting a big range.
Could someone help me with making it faster (if possible).
I don't know how to acces the items ones a treemap is made, but if that's possible it might be faster to use setSize(0) (method of MapItem).
The following code is mainly of how i have it done now:
- void rangeFinishAdd(int minId, int maxId) {
- // first count the items that are in range
- Iterator i = words.values().iterator();
- int count = 0;
- while(i.hasNext()) {
- WordItem w = (WordItem) i.next(); // why does this still needs to be casted?
- if(w.id >= minId && w.id <= maxId) count++;
- }
- items = new WordItem[count];
- // words.values().toArray(items);
- i = words.values().iterator();
- int index = 0;
- while(i.hasNext()) {
- WordItem w = (WordItem) i.next();
- if(w.id >= minId && w.id <= maxId) {
- items[index] = w;
- index++;
- }
- }
- }
------------------------
All code:
- // Code from Visualizing Data, First Edition, Copyright 2008 Ben Fry.
- import treemap.*;
- import controlP5.*;
- ControlP5 cp5;
- Range range;
- Treemap map;
- WordMap mapData;
- void setup() {
- size(1024, 768);
- smooth();
- strokeWeight(0.25f);
- PFont font = createFont("Serif", 13);
- textFont(font);
- mapData = new WordMap();
- String[] lines = loadStrings("equator.txt");
- for (int i = 0; i < lines.length; i++) {
- mapData.addWord(lines[i]);
- }
- mapData.finishAdd();
- // different choices for the layout method
- //MapLayout algorithm = new SliceLayout();
- //MapLayout algorithm = new StripTreemap();
- //MapLayout algorithm = new PivotBySplitSize();
- //MapLayout algorithm = new SquarifiedLayout();
- //map = new Treemap(mapData, 0, 0, width, height);
- gui();
- }
- // . . . . . . . . . . . . . . . . . .
- void draw() {
- background(255);
- map.draw();
- }
- // . . . . . . . . . . . . . . . . . .
- void gui() {
- cp5 = new ControlP5(this);
- range = cp5.addRange("weeks")
- .setBroadcast(false)
- .setPosition(50, height-50)
- .setSize(width-100, 15)
- .setHandleSize(20)
- .setRange(0, 250)
- .setBroadcast(true)
- .setRangeValues(0, 10)
- .setColorForeground(color(20, 100))
- .setColorBackground(color(100, 100))
- ;
- }
- void controlEvent(ControlEvent theControlEvent) {
- if(theControlEvent.isFrom("weeks")) {
- // 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.
- int minV = int(theControlEvent.getController().getArrayValue(0));
- int maxV = int(theControlEvent.getController().getArrayValue(1));
- println("range update, done.");
- // map to range of mapData
- minV = (int) map(minV, 0, 250, 0, mapData.idCount);
- maxV = (int) map(maxV, 0, 250, 0, mapData.idCount);
- mapData.rangeFinishAdd(minV, maxV);
- map = new Treemap(mapData, 0, 0, width, height);
- }
- }
- // id is added
- // Code from Visualizing Data, First Edition, Copyright 2008 Ben Fry.
- class WordItem extends SimpleMapItem {
- String word;
- int id;
- WordItem(String word, int id) {
- this.word = word;
- this.id = id;
- }
- void draw() {
- fill(255);
- rect(x, y, w, h);
- fill(0);
- if (w > textWidth(word) + 6) {
- if (h > textAscent() + 6) {
- textAlign(CENTER, CENTER);
- text(word, x + w/2, y + h/2);
- }
- }
- }
- }
- // idCount added
- // rangeFinishAdd added
- // added what to store in the HashMap so casting isn't needed
- // Code from Visualizing Data, First Edition, Copyright 2008 Ben Fry.
- class WordMap extends SimpleMapModel {
- HashMap<String, WordItem> words;
- int idCount = 0;
- WordMap() {
- words = new HashMap<String, WordItem>();
- }
- void addWord(String word) {
- WordItem item = words.get(word);
- if (item == null) {
- item = new WordItem(word, idCount++);
- words.put(word, item);
- }
- item.incrementSize();
- }
- void finishAdd() {
- items = new WordItem[words.size()];
- words.values().toArray(items);
- }
- // - - - - - - - - - - - - - - - - -
- void rangeFinishAdd(int minId, int maxId) {
- // first count the items that are in range
- Iterator i = words.values().iterator();
- int count = 0;
- while(i.hasNext()) {
- WordItem w = (WordItem) i.next(); // why does this still needs to be casted?
- if(w.id >= minId && w.id <= maxId) count++;
- }
- items = new WordItem[count];
- // words.values().toArray(items);
- i = words.values().iterator();
- int index = 0;
- while(i.hasNext()) {
- WordItem w = (WordItem) i.next();
- if(w.id >= minId && w.id <= maxId) {
- items[index] = w;
- index++;
- }
- }
- }
- }
1