package timeflow.vis; import java.awt.Color; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import timeflow.data.db.Act; import timeflow.data.db.ActDB; import timeflow.data.db.ActList; import timeflow.data.db.Field; import timeflow.model.TFModel; import timeflow.model.VirtualField; public class VisualActFactory { // create one VisualAct per Act private static java.util.List create(ActList acts) { java.util.List list = new ArrayList(); for (Act a : acts) { VisualAct v = new TagVisualAct(a); list.add(v); } return list; } // create one VisualAct per Act/tag combo. public static java.util.List create(ActList acts, Field tagField, boolean multipleColors) { if (tagField == null || tagField.getType() == String.class) { return create(acts); } java.util.List list = new ArrayList(); for (Act a : acts) { String[] tags = a.getTextList(tagField); if (tags == null || tags.length < 2) { VisualAct v = new TagVisualAct(a); if (tags != null && tags.length == 1) { v.setTrackString(tags[0]); } list.add(v); } else { for (String tag : tags) { VisualAct v = multipleColors ? new TagVisualAct(a) : new VisualAct(a); v.setTrackString(tag); list.add(v); } } } return list; } public static Collection makeEmFit(TFModel model, ArrayList vacts, Rectangle bounds) { // Does everything fit? Because, if so, we're already good to go. int area = bounds.width * bounds.height; int room = area / 200; if (vacts.size() <= room) { return vacts; } ArrayList results = new ArrayList(); // OK. If: // * there's room for more than one item, and // * there's more than one color in use, // // Then let's see how many colors there are. Maybe we can do one bubble per color. ActDB db = model.getDB(); if (room > 1 && (db.getField(VirtualField.COLOR) != null || db.getField(VirtualField.TRACK) != null)) { HashMap> colorGroupings = new HashMap>(); for (VisualAct v : vacts) { Color c = v.color; ArrayList grouping = colorGroupings.get(c); if (grouping == null) { grouping = new ArrayList(); colorGroupings.put(c, grouping); } grouping.add(v); } if (colorGroupings.size() <= room) // Great! The colors fit. We now return one group VisualAct per color. { for (Color c : colorGroupings.keySet()) { ArrayList grouping = colorGroupings.get(c); if (grouping.size() == 1) { results.add(grouping.get(0)); } else if (grouping.size() > 1) { results.add(new GroupVisualAct(grouping, false, bounds)); } } return results; } } // OK, too bad, even that doesn't fit. We will just create one fat VisualAct // that descibes the aggregate. C'est la vie! results.add(new GroupVisualAct(vacts, true, bounds)); return results; } }