KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > demos > TreeMap


1 package prefuse.demos;
2
3 import java.awt.BorderLayout JavaDoc;
4 import java.awt.Color JavaDoc;
5 import java.awt.Component JavaDoc;
6 import java.awt.Dimension JavaDoc;
7 import java.awt.Font JavaDoc;
8 import java.awt.Shape JavaDoc;
9 import java.awt.event.MouseEvent JavaDoc;
10 import java.awt.geom.Rectangle2D JavaDoc;
11 import java.util.Iterator JavaDoc;
12
13 import javax.swing.BorderFactory JavaDoc;
14 import javax.swing.Box JavaDoc;
15 import javax.swing.JComponent JavaDoc;
16 import javax.swing.JFrame JavaDoc;
17 import javax.swing.JPanel JavaDoc;
18 import javax.swing.SwingConstants JavaDoc;
19
20 import prefuse.Display;
21 import prefuse.Visualization;
22 import prefuse.action.ActionList;
23 import prefuse.action.RepaintAction;
24 import prefuse.action.animate.ColorAnimator;
25 import prefuse.action.assignment.ColorAction;
26 import prefuse.action.layout.Layout;
27 import prefuse.action.layout.graph.SquarifiedTreeMapLayout;
28 import prefuse.controls.ControlAdapter;
29 import prefuse.data.Schema;
30 import prefuse.data.Tree;
31 import prefuse.data.expression.Predicate;
32 import prefuse.data.expression.parser.ExpressionParser;
33 import prefuse.data.io.TreeMLReader;
34 import prefuse.data.query.SearchQueryBinding;
35 import prefuse.render.AbstractShapeRenderer;
36 import prefuse.render.DefaultRendererFactory;
37 import prefuse.render.LabelRenderer;
38 import prefuse.util.ColorLib;
39 import prefuse.util.ColorMap;
40 import prefuse.util.FontLib;
41 import prefuse.util.PrefuseLib;
42 import prefuse.util.UpdateListener;
43 import prefuse.util.ui.JFastLabel;
44 import prefuse.util.ui.JSearchPanel;
45 import prefuse.util.ui.UILib;
46 import prefuse.visual.DecoratorItem;
47 import prefuse.visual.NodeItem;
48 import prefuse.visual.VisualItem;
49 import prefuse.visual.VisualTree;
50 import prefuse.visual.expression.InGroupPredicate;
51 import prefuse.visual.sort.TreeDepthItemSorter;
52
53
54 /**
55  * Demonstration showcasing a TreeMap layout of a hierarchical data
56  * set and the use of dynamic query binding for text search. Animation
57  * is used to highlight changing search results.
58  *
59  * @author <a HREF="http://jheer.org">jeffrey heer</a>
60  */

61 public class TreeMap extends Display {
62
63     public static final String JavaDoc TREE_CHI = "/chi-ontology.xml.gz";
64     
65     // create data description of labels, setting colors, fonts ahead of time
66
private static final Schema LABEL_SCHEMA = PrefuseLib.getVisualItemSchema();
67     static {
68         LABEL_SCHEMA.setDefault(VisualItem.INTERACTIVE, false);
69         LABEL_SCHEMA.setDefault(VisualItem.TEXTCOLOR, ColorLib.gray(200));
70         LABEL_SCHEMA.setDefault(VisualItem.FONT, FontLib.getFont("Tahoma",16));
71     }
72     
73     private static final String JavaDoc tree = "tree";
74     private static final String JavaDoc treeNodes = "tree.nodes";
75     private static final String JavaDoc treeEdges = "tree.edges";
76     private static final String JavaDoc labels = "labels";
77
78     private SearchQueryBinding searchQ;
79     
80     public TreeMap(Tree t, String JavaDoc label) {
81         super(new Visualization());
82         
83         // add the tree to the visualization
84
VisualTree vt = m_vis.addTree(tree, t);
85         m_vis.setVisible(treeEdges, null, false);
86         
87         // ensure that only leaf nodes are interactive
88
Predicate noLeaf = (Predicate)ExpressionParser.parse("childcount()>0");
89         m_vis.setInteractive(treeNodes, noLeaf, false);
90
91         // add labels to the visualization
92
// first create a filter to show labels only at top-level nodes
93
Predicate labelP = (Predicate)ExpressionParser.parse("treedepth()=1");
94         // now create the labels as decorators of the nodes
95
m_vis.addDecorators(labels, treeNodes, labelP, LABEL_SCHEMA);
96         
97         // set up the renderers - one for nodes and one for labels
98
DefaultRendererFactory rf = new DefaultRendererFactory();
99         rf.add(new InGroupPredicate(treeNodes), new NodeRenderer());
100         rf.add(new InGroupPredicate(labels), new LabelRenderer(label));
101         m_vis.setRendererFactory(rf);
102                        
103         // border colors
104
final ColorAction borderColor = new BorderColorAction(treeNodes);
105         final ColorAction fillColor = new FillColorAction(treeNodes);
106         
107         // color settings
108
ActionList colors = new ActionList();
109         colors.add(fillColor);
110         colors.add(borderColor);
111         m_vis.putAction("colors", colors);
112         
113         // animate paint change
114
ActionList animatePaint = new ActionList(400);
115         animatePaint.add(new ColorAnimator(treeNodes));
116         animatePaint.add(new RepaintAction());
117         m_vis.putAction("animatePaint", animatePaint);
118         
119         // create the single filtering and layout action list
120
ActionList layout = new ActionList();
121         layout.add(new SquarifiedTreeMapLayout(tree));
122         layout.add(new LabelLayout(labels));
123         layout.add(colors);
124         layout.add(new RepaintAction());
125         m_vis.putAction("layout", layout);
126         
127         // initialize our display
128
setSize(700,600);
129         setItemSorter(new TreeDepthItemSorter());
130         addControlListener(new ControlAdapter() {
131             public void itemEntered(VisualItem item, MouseEvent JavaDoc e) {
132                 item.setStrokeColor(borderColor.getColor(item));
133                 item.getVisualization().repaint();
134             }
135             public void itemExited(VisualItem item, MouseEvent JavaDoc e) {
136                 item.setStrokeColor(item.getEndStrokeColor());
137                 item.getVisualization().repaint();
138             }
139         });
140         
141         searchQ = new SearchQueryBinding(vt.getNodeTable(), label);
142         m_vis.addFocusGroup(Visualization.SEARCH_ITEMS, searchQ.getSearchSet());
143         searchQ.getPredicate().addExpressionListener(new UpdateListener() {
144             public void update(Object JavaDoc src) {
145                 m_vis.cancel("animatePaint");
146                 m_vis.run("colors");
147                 m_vis.run("animatePaint");
148             }
149         });
150         
151         // perform layout
152
m_vis.run("layout");
153     }
154     
155     public SearchQueryBinding getSearchQuery() {
156         return searchQ;
157     }
158     
159     public static void main(String JavaDoc argv[]) {
160         UILib.setPlatformLookAndFeel();
161         
162         
163         String JavaDoc infile = TREE_CHI;
164         String JavaDoc label = "name";
165         if ( argv.length > 1 ) {
166             infile = argv[0];
167             label = argv[1];
168         }
169         JComponent JavaDoc treemap = demo(infile, label);
170         
171         JFrame JavaDoc frame = new JFrame JavaDoc("p r e f u s e | t r e e m a p");
172         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
173         frame.setContentPane(treemap);
174         frame.pack();
175         frame.setVisible(true);
176     }
177     
178     public static JComponent JavaDoc demo() {
179         return demo(TREE_CHI, "name");
180     }
181     
182     public static JComponent JavaDoc demo(String JavaDoc datafile, final String JavaDoc label) {
183         Tree t = null;
184         try {
185             t = (Tree)new TreeMLReader().readGraph(datafile);
186         } catch ( Exception JavaDoc e ) {
187             e.printStackTrace();
188             System.exit(1);
189         }
190         
191         // create a new treemap
192
final TreeMap treemap = new TreeMap(t, label);
193         
194         // create a search panel for the tree map
195
JSearchPanel search = treemap.getSearchQuery().createSearchPanel();
196         search.setShowResultCount(true);
197         search.setBorder(BorderFactory.createEmptyBorder(5,5,4,0));
198         search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11));
199         
200         final JFastLabel title = new JFastLabel(" ");
201         title.setPreferredSize(new Dimension JavaDoc(350, 20));
202         title.setVerticalAlignment(SwingConstants.BOTTOM);
203         title.setBorder(BorderFactory.createEmptyBorder(3,0,0,0));
204         title.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 16));
205         
206         treemap.addControlListener(new ControlAdapter() {
207             public void itemEntered(VisualItem item, MouseEvent JavaDoc e) {
208                 title.setText(item.getString(label));
209             }
210             public void itemExited(VisualItem item, MouseEvent JavaDoc e) {
211                 title.setText(null);
212             }
213         });
214         
215         Box JavaDoc box = UILib.getBox(new Component JavaDoc[]{title,search}, true, 10, 3, 0);
216
217         JPanel JavaDoc panel = new JPanel JavaDoc(new BorderLayout JavaDoc());
218         panel.add(treemap, BorderLayout.CENTER);
219         panel.add(box, BorderLayout.SOUTH);
220         UILib.setColor(panel, Color.BLACK, Color.GRAY);
221         return panel;
222     }
223     
224     // ------------------------------------------------------------------------
225

226     /**
227      * Set the stroke color for drawing treemap node outlines. A graded
228      * grayscale ramp is used, with higer nodes in the tree drawn in
229      * lighter shades of gray.
230      */

231     public static class BorderColorAction extends ColorAction {
232         
233         public BorderColorAction(String JavaDoc group) {
234             super(group, VisualItem.STROKECOLOR);
235         }
236         
237         public int getColor(VisualItem item) {
238             NodeItem nitem = (NodeItem)item;
239             if ( nitem.isHover() )
240                 return ColorLib.rgb(99,130,191);
241             
242             int depth = nitem.getDepth();
243             if ( depth < 2 ) {
244                 return ColorLib.gray(100);
245             } else if ( depth < 4 ) {
246                 return ColorLib.gray(75);
247             } else {
248                 return ColorLib.gray(50);
249             }
250         }
251     }
252     
253     /**
254      * Set fill colors for treemap nodes. Search items are colored
255      * in pink, while normal nodes are shaded according to their
256      * depth in the tree.
257      */

258     public static class FillColorAction extends ColorAction {
259         private ColorMap cmap = new ColorMap(
260             ColorLib.getInterpolatedPalette(10,
261                 ColorLib.rgb(85,85,85), ColorLib.rgb(0,0,0)), 0, 9);
262
263         public FillColorAction(String JavaDoc group) {
264             super(group, VisualItem.FILLCOLOR);
265         }
266         
267         public int getColor(VisualItem item) {
268             if ( item instanceof NodeItem ) {
269                 NodeItem nitem = (NodeItem)item;
270                 if ( nitem.getChildCount() > 0 ) {
271                     return 0; // no fill for parent nodes
272
} else {
273                     if ( m_vis.isInGroup(item, Visualization.SEARCH_ITEMS) )
274                         return ColorLib.rgb(191,99,130);
275                     else
276                         return cmap.getColor(nitem.getDepth());
277                 }
278             } else {
279                 return cmap.getColor(0);
280             }
281         }
282         
283     } // end of inner class TreeMapColorAction
284

285     /**
286      * Set label positions. Labels are assumed to be DecoratorItem instances,
287      * decorating their respective nodes. The layout simply gets the bounds
288      * of the decorated node and assigns the label coordinates to the center
289      * of those bounds.
290      */

291     public static class LabelLayout extends Layout JavaDoc {
292         public LabelLayout(String JavaDoc group) {
293             super(group);
294         }
295         public void run(double frac) {
296             Iterator JavaDoc iter = m_vis.items(m_group);
297             while ( iter.hasNext() ) {
298                 DecoratorItem item = (DecoratorItem)iter.next();
299                 VisualItem node = item.getDecoratedItem();
300                 Rectangle2D JavaDoc bounds = node.getBounds();
301                 setX(item, null, bounds.getCenterX());
302                 setY(item, null, bounds.getCenterY());
303             }
304         }
305     } // end of inner class LabelLayout
306

307     /**
308      * A renderer for treemap nodes. Draws simple rectangles, but defers
309      * the bounds management to the layout.
310      */

311     public static class NodeRenderer extends AbstractShapeRenderer {
312         private Rectangle2D JavaDoc m_bounds = new Rectangle2D.Double JavaDoc();
313         
314         public NodeRenderer() {
315             m_manageBounds = false;
316         }
317         protected Shape JavaDoc getRawShape(VisualItem item) {
318             m_bounds.setRect(item.getBounds());
319             return m_bounds;
320         }
321     } // end of inner class NodeRenderer
322

323 } // end of class TreeMap
324
Popular Tags