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<VisualAct> create(ActList acts) { java.util.List<VisualAct> list=new ArrayList<VisualAct>(); 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<VisualAct> create(ActList acts, Field tagField, boolean multipleColors) { if (tagField==null || tagField.getType()==String.class) return create(acts); java.util.List<VisualAct> list=new ArrayList<VisualAct>(); 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<VisualAct> makeEmFit(TFModel model, ArrayList<VisualAct> 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<VisualAct> results=new ArrayList<VisualAct>(); // 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<Color, ArrayList<VisualAct>> colorGroupings=new HashMap<Color, ArrayList<VisualAct>>(); for (VisualAct v:vacts) { Color c=v.color; ArrayList<VisualAct> grouping=colorGroupings.get(c); if (grouping==null) { grouping=new ArrayList<VisualAct>(); 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<VisualAct> 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; } }