1 package prefuse.demos; 2 3 import java.awt.BorderLayout ; 4 import java.awt.Color ; 5 import java.awt.Dimension ; 6 import java.awt.Font ; 7 import java.awt.event.ActionEvent ; 8 import java.awt.event.MouseEvent ; 9 import java.awt.geom.Point2D ; 10 11 import javax.swing.AbstractAction ; 12 import javax.swing.BorderFactory ; 13 import javax.swing.Box ; 14 import javax.swing.BoxLayout ; 15 import javax.swing.JComponent ; 16 import javax.swing.JFrame ; 17 import javax.swing.JPanel ; 18 import javax.swing.KeyStroke ; 19 import javax.swing.SwingConstants ; 20 21 import prefuse.Constants; 22 import prefuse.Display; 23 import prefuse.Visualization; 24 import prefuse.action.Action; 25 import prefuse.action.ActionList; 26 import prefuse.action.ItemAction; 27 import prefuse.action.RepaintAction; 28 import prefuse.action.animate.ColorAnimator; 29 import prefuse.action.animate.LocationAnimator; 30 import prefuse.action.animate.QualityControlAnimator; 31 import prefuse.action.animate.VisibilityAnimator; 32 import prefuse.action.assignment.ColorAction; 33 import prefuse.action.assignment.FontAction; 34 import prefuse.action.filter.FisheyeTreeFilter; 35 import prefuse.action.layout.CollapsedSubtreeLayout; 36 import prefuse.action.layout.graph.NodeLinkTreeLayout; 37 import prefuse.activity.SlowInSlowOutPacer; 38 import prefuse.controls.ControlAdapter; 39 import prefuse.controls.FocusControl; 40 import prefuse.controls.PanControl; 41 import prefuse.controls.ZoomControl; 42 import prefuse.controls.ZoomToFitControl; 43 import prefuse.data.Tree; 44 import prefuse.data.Tuple; 45 import prefuse.data.event.TupleSetListener; 46 import prefuse.data.io.TreeMLReader; 47 import prefuse.data.search.PrefixSearchTupleSet; 48 import prefuse.data.tuple.TupleSet; 49 import prefuse.render.DefaultRendererFactory; 50 import prefuse.render.EdgeRenderer; 51 import prefuse.render.AbstractShapeRenderer; 52 import prefuse.render.LabelRenderer; 53 import prefuse.util.ColorLib; 54 import prefuse.util.FontLib; 55 import prefuse.util.ui.JFastLabel; 56 import prefuse.util.ui.JSearchPanel; 57 import prefuse.visual.VisualItem; 58 import prefuse.visual.expression.InGroupPredicate; 59 import prefuse.visual.sort.TreeDepthItemSorter; 60 61 62 68 public class TreeView extends Display { 69 70 public static final String TREE_CHI = "/chi-ontology.xml.gz"; 71 72 private static final String tree = "tree"; 73 private static final String treeNodes = "tree.nodes"; 74 private static final String treeEdges = "tree.edges"; 75 76 private LabelRenderer m_nodeRenderer; 77 private EdgeRenderer m_edgeRenderer; 78 79 private String m_label = "label"; 80 private int m_orientation = Constants.ORIENT_LEFT_RIGHT; 81 82 public TreeView(Tree t, String label) { 83 super(new Visualization()); 84 m_label = label; 85 86 m_vis.add(tree, t); 87 88 m_nodeRenderer = new LabelRenderer(m_label); 89 m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL); 90 m_nodeRenderer.setHorizontalAlignment(Constants.LEFT); 91 m_nodeRenderer.setRoundedCorner(8,8); 92 m_edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_CURVE); 93 94 DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer); 95 rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer); 96 m_vis.setRendererFactory(rf); 97 98 ItemAction nodeColor = new NodeColorAction(treeNodes); 100 ItemAction textColor = new ColorAction(treeNodes, 101 VisualItem.TEXTCOLOR, ColorLib.rgb(0,0,0)); 102 m_vis.putAction("textColor", textColor); 103 104 ItemAction edgeColor = new ColorAction(treeEdges, 105 VisualItem.STROKECOLOR, ColorLib.rgb(200,200,200)); 106 107 ActionList repaint = new ActionList(); 109 repaint.add(nodeColor); 110 repaint.add(new RepaintAction()); 111 m_vis.putAction("repaint", repaint); 112 113 ActionList fullPaint = new ActionList(); 115 fullPaint.add(nodeColor); 116 m_vis.putAction("fullPaint", fullPaint); 117 118 ActionList animatePaint = new ActionList(400); 120 animatePaint.add(new ColorAnimator(treeNodes)); 121 animatePaint.add(new RepaintAction()); 122 m_vis.putAction("animatePaint", animatePaint); 123 124 NodeLinkTreeLayout treeLayout = new NodeLinkTreeLayout(tree, 126 m_orientation, 50, 0, 8); 127 treeLayout.setLayoutAnchor(new Point2D.Double (25,300)); 128 m_vis.putAction("treeLayout", treeLayout); 129 130 CollapsedSubtreeLayout subLayout = 131 new CollapsedSubtreeLayout(tree, m_orientation); 132 m_vis.putAction("subLayout", subLayout); 133 134 AutoPanAction autoPan = new AutoPanAction(); 135 136 ActionList filter = new ActionList(); 138 filter.add(new FisheyeTreeFilter(tree, 2)); 139 filter.add(new FontAction(treeNodes, FontLib.getFont("Tahoma", 16))); 140 filter.add(treeLayout); 141 filter.add(subLayout); 142 filter.add(textColor); 143 filter.add(nodeColor); 144 filter.add(edgeColor); 145 m_vis.putAction("filter", filter); 146 147 ActionList animate = new ActionList(1000); 149 animate.setPacingFunction(new SlowInSlowOutPacer()); 150 animate.add(autoPan); 151 animate.add(new QualityControlAnimator()); 152 animate.add(new VisibilityAnimator(tree)); 153 animate.add(new LocationAnimator(treeNodes)); 154 animate.add(new ColorAnimator(treeNodes)); 155 animate.add(new RepaintAction()); 156 m_vis.putAction("animate", animate); 157 m_vis.alwaysRunAfter("filter", "animate"); 158 159 ActionList orient = new ActionList(2000); 161 orient.setPacingFunction(new SlowInSlowOutPacer()); 162 orient.add(autoPan); 163 orient.add(new QualityControlAnimator()); 164 orient.add(new LocationAnimator(treeNodes)); 165 orient.add(new RepaintAction()); 166 m_vis.putAction("orient", orient); 167 168 170 setSize(700,600); 172 setItemSorter(new TreeDepthItemSorter()); 173 addControlListener(new ZoomToFitControl()); 174 addControlListener(new ZoomControl()); 175 addControlListener(new PanControl()); 176 addControlListener(new FocusControl(1, "filter")); 177 178 registerKeyboardAction( 179 new OrientAction(Constants.ORIENT_LEFT_RIGHT), 180 "left-to-right", KeyStroke.getKeyStroke("ctrl 1"), WHEN_FOCUSED); 181 registerKeyboardAction( 182 new OrientAction(Constants.ORIENT_TOP_BOTTOM), 183 "top-to-bottom", KeyStroke.getKeyStroke("ctrl 2"), WHEN_FOCUSED); 184 registerKeyboardAction( 185 new OrientAction(Constants.ORIENT_RIGHT_LEFT), 186 "right-to-left", KeyStroke.getKeyStroke("ctrl 3"), WHEN_FOCUSED); 187 registerKeyboardAction( 188 new OrientAction(Constants.ORIENT_BOTTOM_TOP), 189 "bottom-to-top", KeyStroke.getKeyStroke("ctrl 4"), WHEN_FOCUSED); 190 191 193 setOrientation(m_orientation); 195 m_vis.run("filter"); 196 197 TupleSet search = new PrefixSearchTupleSet(); 198 m_vis.addFocusGroup(Visualization.SEARCH_ITEMS, search); 199 search.addTupleSetListener(new TupleSetListener() { 200 public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) { 201 m_vis.cancel("animatePaint"); 202 m_vis.run("fullPaint"); 203 m_vis.run("animatePaint"); 204 } 205 }); 206 } 207 208 210 public void setOrientation(int orientation) { 211 NodeLinkTreeLayout rtl 212 = (NodeLinkTreeLayout)m_vis.getAction("treeLayout"); 213 CollapsedSubtreeLayout stl 214 = (CollapsedSubtreeLayout)m_vis.getAction("subLayout"); 215 switch ( orientation ) { 216 case Constants.ORIENT_LEFT_RIGHT: 217 m_nodeRenderer.setHorizontalAlignment(Constants.LEFT); 218 m_edgeRenderer.setHorizontalAlignment1(Constants.RIGHT); 219 m_edgeRenderer.setHorizontalAlignment2(Constants.LEFT); 220 m_edgeRenderer.setVerticalAlignment1(Constants.CENTER); 221 m_edgeRenderer.setVerticalAlignment2(Constants.CENTER); 222 break; 223 case Constants.ORIENT_RIGHT_LEFT: 224 m_nodeRenderer.setHorizontalAlignment(Constants.RIGHT); 225 m_edgeRenderer.setHorizontalAlignment1(Constants.LEFT); 226 m_edgeRenderer.setHorizontalAlignment2(Constants.RIGHT); 227 m_edgeRenderer.setVerticalAlignment1(Constants.CENTER); 228 m_edgeRenderer.setVerticalAlignment2(Constants.CENTER); 229 break; 230 case Constants.ORIENT_TOP_BOTTOM: 231 m_nodeRenderer.setHorizontalAlignment(Constants.CENTER); 232 m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER); 233 m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER); 234 m_edgeRenderer.setVerticalAlignment1(Constants.BOTTOM); 235 m_edgeRenderer.setVerticalAlignment2(Constants.TOP); 236 break; 237 case Constants.ORIENT_BOTTOM_TOP: 238 m_nodeRenderer.setHorizontalAlignment(Constants.CENTER); 239 m_edgeRenderer.setHorizontalAlignment1(Constants.CENTER); 240 m_edgeRenderer.setHorizontalAlignment2(Constants.CENTER); 241 m_edgeRenderer.setVerticalAlignment1(Constants.TOP); 242 m_edgeRenderer.setVerticalAlignment2(Constants.BOTTOM); 243 break; 244 default: 245 throw new IllegalArgumentException ( 246 "Unrecognized orientation value: "+orientation); 247 } 248 m_orientation = orientation; 249 rtl.setOrientation(orientation); 250 stl.setOrientation(orientation); 251 } 252 253 public int getOrientation() { 254 return m_orientation; 255 } 256 257 259 public static void main(String argv[]) { 260 String infile = TREE_CHI; 261 String label = "name"; 262 if ( argv.length > 1 ) { 263 infile = argv[0]; 264 label = argv[1]; 265 } 266 JComponent treeview = demo(infile, label); 267 268 JFrame frame = new JFrame ("p r e f u s e | t r e e v i e w"); 269 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 270 frame.setContentPane(treeview); 271 frame.pack(); 272 frame.setVisible(true); 273 } 274 275 public static JComponent demo() { 276 return demo(TREE_CHI, "name"); 277 } 278 279 public static JComponent demo(String datafile, final String label) { 280 Color BACKGROUND = Color.WHITE; 281 Color FOREGROUND = Color.BLACK; 282 283 Tree t = null; 284 try { 285 t = (Tree)new TreeMLReader().readGraph(datafile); 286 } catch ( Exception e ) { 287 e.printStackTrace(); 288 System.exit(1); 289 } 290 291 final TreeView tview = new TreeView(t, label); 293 tview.setBackground(BACKGROUND); 294 tview.setForeground(FOREGROUND); 295 296 JSearchPanel search = new JSearchPanel(tview.getVisualization(), 298 treeNodes, Visualization.SEARCH_ITEMS, label, true, true); 299 search.setShowResultCount(true); 300 search.setBorder(BorderFactory.createEmptyBorder(5,5,4,0)); 301 search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11)); 302 search.setBackground(BACKGROUND); 303 search.setForeground(FOREGROUND); 304 305 final JFastLabel title = new JFastLabel(" "); 306 title.setPreferredSize(new Dimension (350, 20)); 307 title.setVerticalAlignment(SwingConstants.BOTTOM); 308 title.setBorder(BorderFactory.createEmptyBorder(3,0,0,0)); 309 title.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 16)); 310 title.setBackground(BACKGROUND); 311 title.setForeground(FOREGROUND); 312 313 tview.addControlListener(new ControlAdapter() { 314 public void itemEntered(VisualItem item, MouseEvent e) { 315 if ( item.canGetString(label) ) 316 title.setText(item.getString(label)); 317 } 318 public void itemExited(VisualItem item, MouseEvent e) { 319 title.setText(null); 320 } 321 }); 322 323 Box box = new Box (BoxLayout.X_AXIS); 324 box.add(Box.createHorizontalStrut(10)); 325 box.add(title); 326 box.add(Box.createHorizontalGlue()); 327 box.add(search); 328 box.add(Box.createHorizontalStrut(3)); 329 box.setBackground(BACKGROUND); 330 331 JPanel panel = new JPanel (new BorderLayout ()); 332 panel.setBackground(BACKGROUND); 333 panel.setForeground(FOREGROUND); 334 panel.add(tview, BorderLayout.CENTER); 335 panel.add(box, BorderLayout.SOUTH); 336 return panel; 337 } 338 339 341 public class OrientAction extends AbstractAction { 342 private int orientation; 343 344 public OrientAction(int orientation) { 345 this.orientation = orientation; 346 } 347 public void actionPerformed(ActionEvent evt) { 348 setOrientation(orientation); 349 getVisualization().cancel("orient"); 350 getVisualization().run("treeLayout"); 351 getVisualization().run("orient"); 352 } 353 } 354 355 public class AutoPanAction extends Action { 356 private Point2D m_start = new Point2D.Double (); 357 private Point2D m_end = new Point2D.Double (); 358 private Point2D m_cur = new Point2D.Double (); 359 private int m_bias = 150; 360 361 public void run(double frac) { 362 TupleSet ts = m_vis.getFocusGroup(Visualization.FOCUS_ITEMS); 363 if ( ts.getTupleCount() == 0 ) 364 return; 365 366 if ( frac == 0.0 ) { 367 int xbias=0, ybias=0; 368 switch ( m_orientation ) { 369 case Constants.ORIENT_LEFT_RIGHT: 370 xbias = m_bias; 371 break; 372 case Constants.ORIENT_RIGHT_LEFT: 373 xbias = -m_bias; 374 break; 375 case Constants.ORIENT_TOP_BOTTOM: 376 ybias = m_bias; 377 break; 378 case Constants.ORIENT_BOTTOM_TOP: 379 ybias = -m_bias; 380 break; 381 } 382 383 VisualItem vi = (VisualItem)ts.tuples().next(); 384 m_cur.setLocation(getWidth()/2, getHeight()/2); 385 getAbsoluteCoordinate(m_cur, m_start); 386 m_end.setLocation(vi.getX()+xbias, vi.getY()+ybias); 387 } else { 388 m_cur.setLocation(m_start.getX() + frac*(m_end.getX()-m_start.getX()), 389 m_start.getY() + frac*(m_end.getY()-m_start.getY())); 390 panToAbs(m_cur); 391 } 392 } 393 } 394 395 public static class NodeColorAction extends ColorAction { 396 397 public NodeColorAction(String group) { 398 super(group, VisualItem.FILLCOLOR); 399 } 400 401 public int getColor(VisualItem item) { 402 if ( m_vis.isInGroup(item, Visualization.SEARCH_ITEMS) ) 403 return ColorLib.rgb(255,190,190); 404 else if ( m_vis.isInGroup(item, Visualization.FOCUS_ITEMS) ) 405 return ColorLib.rgb(198,229,229); 406 else if ( item.getDOI() > -1 ) 407 return ColorLib.rgb(164,193,193); 408 else 409 return ColorLib.rgba(255,255,255,0); 410 } 411 412 } 414 415 } | Popular Tags |