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.MouseEvent ; 8 import java.util.Iterator ; 9 10 import javax.swing.BorderFactory ; 11 import javax.swing.Box ; 12 import javax.swing.BoxLayout ; 13 import javax.swing.JFrame ; 14 import javax.swing.JPanel ; 15 import javax.swing.SwingConstants ; 16 17 import prefuse.Constants; 18 import prefuse.Display; 19 import prefuse.Visualization; 20 import prefuse.action.ActionList; 21 import prefuse.action.GroupAction; 22 import prefuse.action.ItemAction; 23 import prefuse.action.RepaintAction; 24 import prefuse.action.animate.ColorAnimator; 25 import prefuse.action.animate.PolarLocationAnimator; 26 import prefuse.action.animate.QualityControlAnimator; 27 import prefuse.action.animate.VisibilityAnimator; 28 import prefuse.action.assignment.ColorAction; 29 import prefuse.action.assignment.FontAction; 30 import prefuse.action.layout.CollapsedSubtreeLayout; 31 import prefuse.action.layout.graph.RadialTreeLayout; 32 import prefuse.activity.SlowInSlowOutPacer; 33 import prefuse.controls.ControlAdapter; 34 import prefuse.controls.DragControl; 35 import prefuse.controls.FocusControl; 36 import prefuse.controls.HoverActionControl; 37 import prefuse.controls.PanControl; 38 import prefuse.controls.ZoomControl; 39 import prefuse.controls.ZoomToFitControl; 40 import prefuse.data.Graph; 41 import prefuse.data.Node; 42 import prefuse.data.Table; 43 import prefuse.data.Tuple; 44 import prefuse.data.event.TupleSetListener; 45 import prefuse.data.io.GraphMLReader; 46 import prefuse.data.query.SearchQueryBinding; 47 import prefuse.data.search.PrefixSearchTupleSet; 48 import prefuse.data.search.SearchTupleSet; 49 import prefuse.data.tuple.DefaultTupleSet; 50 import prefuse.data.tuple.TupleSet; 51 import prefuse.render.AbstractShapeRenderer; 52 import prefuse.render.DefaultRendererFactory; 53 import prefuse.render.EdgeRenderer; 54 import prefuse.render.LabelRenderer; 55 import prefuse.util.ColorLib; 56 import prefuse.util.FontLib; 57 import prefuse.util.ui.JFastLabel; 58 import prefuse.util.ui.JSearchPanel; 59 import prefuse.util.ui.UILib; 60 import prefuse.visual.VisualItem; 61 import prefuse.visual.expression.InGroupPredicate; 62 import prefuse.visual.sort.TreeDepthItemSorter; 63 64 65 71 public class RadialGraphView extends Display { 72 73 public static final String DATA_FILE = "/socialnet.xml"; 74 75 private static final String tree = "tree"; 76 private static final String treeNodes = "tree.nodes"; 77 private static final String treeEdges = "tree.edges"; 78 private static final String linear = "linear"; 79 80 private LabelRenderer m_nodeRenderer; 81 private EdgeRenderer m_edgeRenderer; 82 83 private String m_label = "label"; 84 85 public RadialGraphView(Graph g, String label) { 86 super(new Visualization()); 87 m_label = label; 88 89 m_vis.add(tree, g); 91 m_vis.setInteractive(treeEdges, null, false); 92 93 m_nodeRenderer = new LabelRenderer(m_label); 95 m_nodeRenderer.setRenderType(AbstractShapeRenderer.RENDER_TYPE_FILL); 96 m_nodeRenderer.setHorizontalAlignment(Constants.CENTER); 97 m_nodeRenderer.setRoundedCorner(8,8); 98 m_edgeRenderer = new EdgeRenderer(); 99 100 DefaultRendererFactory rf = new DefaultRendererFactory(m_nodeRenderer); 101 rf.add(new InGroupPredicate(treeEdges), m_edgeRenderer); 102 m_vis.setRendererFactory(rf); 103 104 106 ItemAction nodeColor = new NodeColorAction(treeNodes); 108 ItemAction textColor = new TextColorAction(treeNodes); 109 m_vis.putAction("textColor", textColor); 110 111 ItemAction edgeColor = new ColorAction(treeEdges, 112 VisualItem.STROKECOLOR, ColorLib.rgb(200,200,200)); 113 114 FontAction fonts = new FontAction(treeNodes, 115 FontLib.getFont("Tahoma", 10)); 116 fonts.add("ingroup('_focus_')", FontLib.getFont("Tahoma", 11)); 117 118 ActionList recolor = new ActionList(); 120 recolor.add(nodeColor); 121 recolor.add(textColor); 122 m_vis.putAction("recolor", recolor); 123 124 ActionList repaint = new ActionList(); 126 repaint.add(recolor); 127 repaint.add(new RepaintAction()); 128 m_vis.putAction("repaint", repaint); 129 130 ActionList animatePaint = new ActionList(400); 132 animatePaint.add(new ColorAnimator(treeNodes)); 133 animatePaint.add(new RepaintAction()); 134 m_vis.putAction("animatePaint", animatePaint); 135 136 RadialTreeLayout treeLayout = new RadialTreeLayout(tree); 138 m_vis.putAction("treeLayout", treeLayout); 140 141 CollapsedSubtreeLayout subLayout = new CollapsedSubtreeLayout(tree); 142 m_vis.putAction("subLayout", subLayout); 143 144 ActionList filter = new ActionList(); 146 filter.add(new TreeRootAction(tree)); 147 filter.add(fonts); 148 filter.add(treeLayout); 149 filter.add(subLayout); 150 filter.add(textColor); 151 filter.add(nodeColor); 152 filter.add(edgeColor); 153 m_vis.putAction("filter", filter); 154 155 ActionList animate = new ActionList(1250); 157 animate.setPacingFunction(new SlowInSlowOutPacer()); 158 animate.add(new QualityControlAnimator()); 159 animate.add(new VisibilityAnimator(tree)); 160 animate.add(new PolarLocationAnimator(treeNodes, linear)); 161 animate.add(new ColorAnimator(treeNodes)); 162 animate.add(new RepaintAction()); 163 m_vis.putAction("animate", animate); 164 m_vis.alwaysRunAfter("filter", "animate"); 165 166 168 setSize(600,600); 170 setItemSorter(new TreeDepthItemSorter()); 171 addControlListener(new DragControl()); 172 addControlListener(new ZoomToFitControl()); 173 addControlListener(new ZoomControl()); 174 addControlListener(new PanControl()); 175 addControlListener(new FocusControl(1, "filter")); 176 addControlListener(new HoverActionControl("repaint")); 177 178 180 m_vis.run("filter"); 182 183 m_vis.addFocusGroup(linear, new DefaultTupleSet()); 187 m_vis.getGroup(Visualization.FOCUS_ITEMS).addTupleSetListener( 188 new TupleSetListener() { 189 public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) { 190 TupleSet linearInterp = m_vis.getGroup(linear); 191 if ( add.length < 1 ) return; linearInterp.clear(); 192 for ( Node n = (Node)add[0]; n!=null; n=n.getParent() ) 193 linearInterp.addTuple(n); 194 } 195 } 196 ); 197 198 SearchTupleSet search = new PrefixSearchTupleSet(); 199 m_vis.addFocusGroup(Visualization.SEARCH_ITEMS, search); 200 search.addTupleSetListener(new TupleSetListener() { 201 public void tupleSetChanged(TupleSet t, Tuple[] add, Tuple[] rem) { 202 m_vis.cancel("animatePaint"); 203 m_vis.run("recolor"); 204 m_vis.run("animatePaint"); 205 } 206 }); 207 } 208 209 211 public static void main(String argv[]) { 212 String infile = DATA_FILE; 213 String label = "name"; 214 215 if ( argv.length > 1 ) { 216 infile = argv[0]; 217 label = argv[1]; 218 } 219 220 UILib.setPlatformLookAndFeel(); 221 222 JFrame frame = new JFrame ("p r e f u s e | r a d i a l g r a p h v i e w"); 223 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 224 frame.setContentPane(demo(infile, label)); 225 frame.pack(); 226 frame.setVisible(true); 227 } 228 229 public static JPanel demo() { 230 return demo(DATA_FILE, "name"); 231 } 232 233 public static JPanel demo(String datafile, final String label) { 234 Graph g = null; 235 try { 236 g = new GraphMLReader().readGraph(datafile); 237 } catch ( Exception e ) { 238 e.printStackTrace(); 239 System.exit(1); 240 } 241 return demo(g, label); 242 } 243 244 public static JPanel demo(Graph g, final String label) { 245 final RadialGraphView gview = new RadialGraphView(g, label); 247 Visualization vis = gview.getVisualization(); 248 249 SearchQueryBinding sq = new SearchQueryBinding( 251 (Table)vis.getGroup(treeNodes), label, 252 (SearchTupleSet)vis.getGroup(Visualization.SEARCH_ITEMS)); 253 JSearchPanel search = sq.createSearchPanel(); 254 search.setShowResultCount(true); 255 search.setBorder(BorderFactory.createEmptyBorder(5,5,4,0)); 256 search.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 11)); 257 258 final JFastLabel title = new JFastLabel(" "); 259 title.setPreferredSize(new Dimension (350, 20)); 260 title.setVerticalAlignment(SwingConstants.BOTTOM); 261 title.setBorder(BorderFactory.createEmptyBorder(3,0,0,0)); 262 title.setFont(FontLib.getFont("Tahoma", Font.PLAIN, 16)); 263 264 gview.addControlListener(new ControlAdapter() { 265 public void itemEntered(VisualItem item, MouseEvent e) { 266 if ( item.canGetString(label) ) 267 title.setText(item.getString(label)); 268 } 269 public void itemExited(VisualItem item, MouseEvent e) { 270 title.setText(null); 271 } 272 }); 273 274 Box box = new Box (BoxLayout.X_AXIS); 275 box.add(Box.createHorizontalStrut(10)); 276 box.add(title); 277 box.add(Box.createHorizontalGlue()); 278 box.add(search); 279 box.add(Box.createHorizontalStrut(3)); 280 281 JPanel panel = new JPanel (new BorderLayout ()); 282 panel.add(gview, BorderLayout.CENTER); 283 panel.add(box, BorderLayout.SOUTH); 284 285 Color BACKGROUND = Color.WHITE; 286 Color FOREGROUND = Color.DARK_GRAY; 287 UILib.setColor(panel, BACKGROUND, FOREGROUND); 288 289 return panel; 290 } 291 292 294 298 public static class TreeRootAction extends GroupAction { 299 public TreeRootAction(String graphGroup) { 300 super(graphGroup); 301 } 302 public void run(double frac) { 303 TupleSet focus = m_vis.getGroup(Visualization.FOCUS_ITEMS); 304 if ( focus==null || focus.getTupleCount() == 0 ) return; 305 306 Graph g = (Graph)m_vis.getGroup(m_group); 307 Node f = null; 308 Iterator tuples = focus.tuples(); 309 while (tuples.hasNext() && !g.containsTuple(f=(Node)tuples.next())) 310 { 311 f = null; 312 } 313 if ( f == null ) return; 314 g.getSpanningTree(f); 315 } 316 } 317 318 321 public static class NodeColorAction extends ColorAction { 322 public NodeColorAction(String group) { 323 super(group, VisualItem.FILLCOLOR, ColorLib.rgba(255,255,255,0)); 324 add("_hover", ColorLib.gray(220,230)); 325 add("ingroup('_search_')", ColorLib.rgb(255,190,190)); 326 add("ingroup('_focus_')", ColorLib.rgb(198,229,229)); 327 } 328 329 } 331 334 public static class TextColorAction extends ColorAction { 335 public TextColorAction(String group) { 336 super(group, VisualItem.TEXTCOLOR, ColorLib.gray(0)); 337 add("_hover", ColorLib.rgb(255,0,0)); 338 } 339 } 341 342 } | Popular Tags |