KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > demos > GraphView


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.event.ActionEvent JavaDoc;
8 import java.awt.event.ActionListener JavaDoc;
9 import java.awt.event.WindowAdapter JavaDoc;
10 import java.awt.event.WindowEvent JavaDoc;
11 import java.awt.geom.Rectangle2D JavaDoc;
12
13 import javax.swing.AbstractAction JavaDoc;
14 import javax.swing.BorderFactory JavaDoc;
15 import javax.swing.Box JavaDoc;
16 import javax.swing.BoxLayout JavaDoc;
17 import javax.swing.JButton JavaDoc;
18 import javax.swing.JDialog JavaDoc;
19 import javax.swing.JFrame JavaDoc;
20 import javax.swing.JLabel JavaDoc;
21 import javax.swing.JList JavaDoc;
22 import javax.swing.JMenu JavaDoc;
23 import javax.swing.JMenuBar JavaDoc;
24 import javax.swing.JPanel JavaDoc;
25 import javax.swing.JScrollPane JavaDoc;
26 import javax.swing.JSplitPane JavaDoc;
27 import javax.swing.KeyStroke JavaDoc;
28 import javax.swing.ListSelectionModel JavaDoc;
29 import javax.swing.event.ChangeEvent JavaDoc;
30 import javax.swing.event.ChangeListener JavaDoc;
31 import javax.swing.event.ListSelectionEvent JavaDoc;
32 import javax.swing.event.ListSelectionListener JavaDoc;
33
34 import prefuse.Display;
35 import prefuse.Visualization;
36 import prefuse.action.ActionList;
37 import prefuse.action.RepaintAction;
38 import prefuse.action.assignment.ColorAction;
39 import prefuse.action.filter.GraphDistanceFilter;
40 import prefuse.action.layout.graph.ForceDirectedLayout;
41 import prefuse.activity.Activity;
42 import prefuse.controls.DragControl;
43 import prefuse.controls.FocusControl;
44 import prefuse.controls.NeighborHighlightControl;
45 import prefuse.controls.PanControl;
46 import prefuse.controls.WheelZoomControl;
47 import prefuse.controls.ZoomControl;
48 import prefuse.controls.ZoomToFitControl;
49 import prefuse.data.Graph;
50 import prefuse.data.Table;
51 import prefuse.data.Tuple;
52 import prefuse.data.event.TupleSetListener;
53 import prefuse.data.io.GraphMLReader;
54 import prefuse.data.tuple.TupleSet;
55 import prefuse.render.DefaultRendererFactory;
56 import prefuse.render.LabelRenderer;
57 import prefuse.util.ColorLib;
58 import prefuse.util.GraphLib;
59 import prefuse.util.GraphicsLib;
60 import prefuse.util.display.DisplayLib;
61 import prefuse.util.display.ItemBoundsListener;
62 import prefuse.util.force.ForceSimulator;
63 import prefuse.util.io.IOLib;
64 import prefuse.util.ui.JForcePanel;
65 import prefuse.util.ui.JValueSlider;
66 import prefuse.util.ui.UILib;
67 import prefuse.visual.VisualGraph;
68 import prefuse.visual.VisualItem;
69
70 /**
71  * @author <a HREF="http://jheer.org">jeffrey heer</a>
72  */

73 public class GraphView extends JPanel JavaDoc {
74
75     private static final String JavaDoc graph = "graph";
76     private static final String JavaDoc nodes = "graph.nodes";
77     private static final String JavaDoc edges = "graph.edges";
78
79     private Visualization m_vis;
80     
81     public GraphView(Graph g, String JavaDoc label) {
82         
83         // create a new, empty visualization for our data
84
m_vis = new Visualization();
85         
86         // --------------------------------------------------------------------
87
// set up the renderers
88

89         LabelRenderer tr = new LabelRenderer();
90         tr.setRoundedCorner(8, 8);
91         m_vis.setRendererFactory(new DefaultRendererFactory(tr));
92
93         // --------------------------------------------------------------------
94
// register the data with a visualization
95

96         // adds graph to visualization and sets renderer label field
97
setGraph(g, label);
98         
99         // fix selected focus nodes
100
TupleSet focusGroup = m_vis.getGroup(Visualization.FOCUS_ITEMS);
101         focusGroup.addTupleSetListener(new TupleSetListener() {
102             public void tupleSetChanged(TupleSet ts, Tuple[] add, Tuple[] rem)
103             {
104                 for ( int i=0; i<rem.length; ++i )
105                     ((VisualItem)rem[i]).setFixed(false);
106                 for ( int i=0; i<add.length; ++i ) {
107                     ((VisualItem)add[i]).setFixed(false);
108                     ((VisualItem)add[i]).setFixed(true);
109                 }
110                 if ( ts.getTupleCount() == 0 ) {
111                     ts.addTuple(rem[0]);
112                     ((VisualItem)rem[0]).setFixed(false);
113                 }
114                 m_vis.run("draw");
115             }
116         });
117         
118         
119         
120         // --------------------------------------------------------------------
121
// create actions to process the visual data
122

123         int hops = 30;
124         final GraphDistanceFilter filter = new GraphDistanceFilter(graph, hops);
125
126         ColorAction fill = new ColorAction(nodes,
127                 VisualItem.FILLCOLOR, ColorLib.rgb(200,200,255));
128         fill.add(VisualItem.FIXED, ColorLib.rgb(255,100,100));
129         fill.add(VisualItem.HIGHLIGHT, ColorLib.rgb(255,200,125));
130         
131         ActionList draw = new ActionList();
132         draw.add(filter);
133         draw.add(fill);
134         draw.add(new ColorAction(nodes, VisualItem.STROKECOLOR, 0));
135         draw.add(new ColorAction(nodes, VisualItem.TEXTCOLOR, ColorLib.rgb(0,0,0)));
136         draw.add(new ColorAction(edges, VisualItem.FILLCOLOR, ColorLib.gray(200)));
137         draw.add(new ColorAction(edges, VisualItem.STROKECOLOR, ColorLib.gray(200)));
138         
139         ActionList animate = new ActionList(Activity.INFINITY);
140         animate.add(new ForceDirectedLayout(graph));
141         animate.add(fill);
142         animate.add(new RepaintAction());
143         
144         // finally, we register our ActionList with the Visualization.
145
// we can later execute our Actions by invoking a method on our
146
// Visualization, using the name we've chosen below.
147
m_vis.putAction("draw", draw);
148         m_vis.putAction("layout", animate);
149
150         m_vis.runAfter("draw", "layout");
151         
152         
153         // --------------------------------------------------------------------
154
// set up a display to show the visualization
155

156         Display display = new Display(m_vis);
157         display.setSize(700,700);
158         display.pan(350, 350);
159         display.setForeground(Color.GRAY);
160         display.setBackground(Color.WHITE);
161         
162         // main display controls
163
display.addControlListener(new FocusControl(1));
164         display.addControlListener(new DragControl());
165         display.addControlListener(new PanControl());
166         display.addControlListener(new ZoomControl());
167         display.addControlListener(new WheelZoomControl());
168         display.addControlListener(new ZoomToFitControl());
169         display.addControlListener(new NeighborHighlightControl());
170
171         // overview display
172
// Display overview = new Display(vis);
173
// overview.setSize(290,290);
174
// overview.addItemBoundsListener(new FitOverviewListener());
175

176         display.setForeground(Color.GRAY);
177         display.setBackground(Color.WHITE);
178         
179         // --------------------------------------------------------------------
180
// launch the visualization
181

182         // create a panel for editing force values
183
ForceSimulator fsim = ((ForceDirectedLayout)animate.get(0)).getForceSimulator();
184         JForcePanel fpanel = new JForcePanel(fsim);
185         
186 // JPanel opanel = new JPanel();
187
// opanel.setBorder(BorderFactory.createTitledBorder("Overview"));
188
// opanel.setBackground(Color.WHITE);
189
// opanel.add(overview);
190

191         final JValueSlider slider = new JValueSlider("Distance", 0, hops, hops);
192         slider.addChangeListener(new ChangeListener JavaDoc() {
193             public void stateChanged(ChangeEvent JavaDoc e) {
194                 filter.setDistance(slider.getValue().intValue());
195                 m_vis.run("draw");
196             }
197         });
198         slider.setBackground(Color.WHITE);
199         slider.setPreferredSize(new Dimension JavaDoc(300,30));
200         slider.setMaximumSize(new Dimension JavaDoc(300,30));
201         
202         Box JavaDoc cf = new Box JavaDoc(BoxLayout.Y_AXIS);
203         cf.add(slider);
204         cf.setBorder(BorderFactory.createTitledBorder("Connectivity Filter"));
205         fpanel.add(cf);
206
207         //fpanel.add(opanel);
208

209         fpanel.add(Box.createVerticalGlue());
210         
211         // create a new JSplitPane to present the interface
212
JSplitPane JavaDoc split = new JSplitPane JavaDoc();
213         split.setLeftComponent(display);
214         split.setRightComponent(fpanel);
215         split.setOneTouchExpandable(true);
216         split.setContinuousLayout(false);
217         split.setDividerLocation(700);
218         
219         // now we run our action list
220
m_vis.run("draw");
221         
222         add(split);
223     }
224     
225     public void setGraph(Graph g, String JavaDoc label) {
226         // update labeling
227
DefaultRendererFactory drf = (DefaultRendererFactory)
228                                                 m_vis.getRendererFactory();
229         ((LabelRenderer)drf.getDefaultRenderer()).setTextField(label);
230         
231         // update graph
232
m_vis.removeGroup(graph);
233         VisualGraph vg = m_vis.addGraph(graph, g);
234         m_vis.setValue(edges, null, VisualItem.INTERACTIVE, Boolean.FALSE);
235         VisualItem f = (VisualItem)vg.getNode(0);
236         m_vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(f);
237         f.setFixed(false);
238     }
239     
240     // ------------------------------------------------------------------------
241
// Main and demo methods
242

243     public static void main(String JavaDoc[] args) {
244         UILib.setPlatformLookAndFeel();
245         
246         // create graphview
247
String JavaDoc datafile = null;
248         String JavaDoc label = "label";
249         if ( args.length > 1 ) {
250             datafile = args[0];
251             label = args[1];
252         }
253         
254         JFrame JavaDoc frame = demo(datafile, label);
255         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
256     }
257     
258     public static JFrame JavaDoc demo() {
259         return demo((String JavaDoc)null, "label");
260     }
261     
262     public static JFrame JavaDoc demo(String JavaDoc datafile, String JavaDoc label) {
263         Graph g = null;
264         if ( datafile == null ) {
265             g = GraphLib.getGrid(15,15);
266             label = "label";
267         } else {
268             try {
269                 g = new GraphMLReader().readGraph(datafile);
270             } catch ( Exception JavaDoc e ) {
271                 e.printStackTrace();
272                 System.exit(1);
273             }
274         }
275         return demo(g, label);
276     }
277     
278     public static JFrame JavaDoc demo(Graph g, String JavaDoc label) {
279         final GraphView view = new GraphView(g, label);
280         
281         // set up menu
282
JMenu JavaDoc dataMenu = new JMenu JavaDoc("Data");
283         dataMenu.add(new OpenGraphAction(view));
284         dataMenu.add(new GraphMenuAction("Grid","ctrl 1",view) {
285             protected Graph getGraph() {
286                 return GraphLib.getGrid(15,15);
287             }
288         });
289         dataMenu.add(new GraphMenuAction("Clique","ctrl 2",view) {
290             protected Graph getGraph() {
291                 return GraphLib.getClique(10);
292             }
293         });
294         dataMenu.add(new GraphMenuAction("Honeycomb","ctrl 3",view) {
295             protected Graph getGraph() {
296                 return GraphLib.getHoneycomb(5);
297             }
298         });
299         dataMenu.add(new GraphMenuAction("Balanced Tree","ctrl 4",view) {
300             protected Graph getGraph() {
301                 return GraphLib.getBalancedTree(3,5);
302             }
303         });
304         dataMenu.add(new GraphMenuAction("Diamond Tree","ctrl 5",view) {
305             protected Graph getGraph() {
306                 return GraphLib.getDiamondTree(3,3,3);
307             }
308         });
309         JMenuBar JavaDoc menubar = new JMenuBar JavaDoc();
310         menubar.add(dataMenu);
311         
312         // launch window
313
JFrame JavaDoc frame = new JFrame JavaDoc("p r e f u s e | g r a p h v i e w");
314         frame.setJMenuBar(menubar);
315         frame.setContentPane(view);
316         frame.pack();
317         frame.setVisible(true);
318         
319         frame.addWindowListener(new WindowAdapter JavaDoc() {
320             public void windowActivated(WindowEvent JavaDoc e) {
321                 view.m_vis.run("layout");
322             }
323             public void windowDeactivated(WindowEvent JavaDoc e) {
324                 view.m_vis.cancel("layout");
325             }
326         });
327         
328         return frame;
329     }
330     
331     
332     // ------------------------------------------------------------------------
333

334     /**
335      * Swing menu action that loads a graph into the graph viewer.
336      */

337     public abstract static class GraphMenuAction extends AbstractAction JavaDoc {
338         private GraphView m_view;
339         public GraphMenuAction(String JavaDoc name, String JavaDoc accel, GraphView view) {
340             m_view = view;
341             this.putValue(AbstractAction.NAME, name);
342             this.putValue(AbstractAction.ACCELERATOR_KEY,
343                           KeyStroke.getKeyStroke(accel));
344         }
345         public void actionPerformed(ActionEvent JavaDoc e) {
346             m_view.setGraph(getGraph(), "label");
347         }
348         protected abstract Graph getGraph();
349     }
350     
351     public static class OpenGraphAction extends AbstractAction JavaDoc {
352         private GraphView m_view;
353
354         public OpenGraphAction(GraphView view) {
355             m_view = view;
356             this.putValue(AbstractAction.NAME, "Open File...");
357             this.putValue(AbstractAction.ACCELERATOR_KEY,
358                           KeyStroke.getKeyStroke("ctrl O"));
359         }
360         public void actionPerformed(ActionEvent JavaDoc e) {
361             Graph g = IOLib.getGraphFile(m_view);
362             if ( g == null ) return;
363             String JavaDoc label = getLabel(m_view, g);
364             if ( label != null ) {
365                 m_view.setGraph(g, label);
366             }
367         }
368         public static String JavaDoc getLabel(Component JavaDoc c, Graph g) {
369             // get the column names
370
Table t = g.getNodeTable();
371             int cc = t.getColumnCount();
372             String JavaDoc[] names = new String JavaDoc[cc];
373             for ( int i=0; i<cc; ++i )
374                 names[i] = t.getColumnName(i);
375             
376             // where to store the result
377
final String JavaDoc[] label = new String JavaDoc[1];
378
379             // -- build the dialog -----
380
// we need to get the enclosing frame first
381
while ( c != null && !(c instanceof JFrame JavaDoc) ) {
382                 c = c.getParent();
383             }
384             final JDialog JavaDoc dialog = new JDialog JavaDoc(
385                     (JFrame JavaDoc)c, "Choose Label Field", true);
386             
387             // create the ok/cancel buttons
388
final JButton JavaDoc ok = new JButton JavaDoc("OK");
389             ok.setEnabled(false);
390             ok.addActionListener(new ActionListener JavaDoc() {
391                public void actionPerformed(ActionEvent JavaDoc e) {
392                    dialog.setVisible(false);
393                }
394             });
395             JButton JavaDoc cancel = new JButton JavaDoc("Cancel");
396             cancel.addActionListener(new ActionListener JavaDoc() {
397                 public void actionPerformed(ActionEvent JavaDoc e) {
398                     label[0] = null;
399                     dialog.setVisible(false);
400                 }
401             });
402             
403             // build the selection list
404
final JList JavaDoc list = new JList JavaDoc(names);
405             list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
406             list.getSelectionModel().addListSelectionListener(
407             new ListSelectionListener JavaDoc() {
408                 public void valueChanged(ListSelectionEvent JavaDoc e) {
409                     int sel = list.getSelectedIndex();
410                     if ( sel >= 0 ) {
411                         ok.setEnabled(true);
412                         label[0] = (String JavaDoc)list.getModel().getElementAt(sel);
413                     } else {
414                         ok.setEnabled(false);
415                         label[0] = null;
416                     }
417                 }
418             });
419             JScrollPane JavaDoc scrollList = new JScrollPane JavaDoc(list);
420             
421             JLabel JavaDoc title = new JLabel JavaDoc("Choose a field to use for node labels:");
422             
423             // layout the buttons
424
Box JavaDoc bbox = new Box JavaDoc(BoxLayout.X_AXIS);
425             bbox.add(Box.createHorizontalStrut(5));
426             bbox.add(Box.createHorizontalGlue());
427             bbox.add(ok);
428             bbox.add(Box.createHorizontalStrut(5));
429             bbox.add(cancel);
430             bbox.add(Box.createHorizontalStrut(5));
431             
432             // put everything into a panel
433
JPanel JavaDoc panel = new JPanel JavaDoc(new BorderLayout JavaDoc());
434             panel.add(title, BorderLayout.NORTH);
435             panel.add(scrollList, BorderLayout.CENTER);
436             panel.add(bbox, BorderLayout.SOUTH);
437             panel.setBorder(BorderFactory.createEmptyBorder(5,2,2,2));
438             
439             // show the dialog
440
dialog.setContentPane(panel);
441             dialog.pack();
442             dialog.setLocationRelativeTo(c);
443             dialog.setVisible(true);
444             dialog.dispose();
445             
446             // return the label field selection
447
return label[0];
448         }
449     }
450     
451     public static class FitOverviewListener implements ItemBoundsListener {
452         private Rectangle2D JavaDoc m_bounds = new Rectangle2D.Double JavaDoc();
453         private Rectangle2D JavaDoc m_temp = new Rectangle2D.Double JavaDoc();
454         private double m_d = 15;
455         public void itemBoundsChanged(Display d) {
456             d.getItemBounds(m_temp);
457             GraphicsLib.expand(m_temp, 25/d.getScale());
458             
459             double dd = m_d/d.getScale();
460             double xd = Math.abs(m_temp.getMinX()-m_bounds.getMinX());
461             double yd = Math.abs(m_temp.getMinY()-m_bounds.getMinY());
462             double wd = Math.abs(m_temp.getWidth()-m_bounds.getWidth());
463             double hd = Math.abs(m_temp.getHeight()-m_bounds.getHeight());
464             if ( xd>dd || yd>dd || wd>dd || hd>dd ) {
465                 m_bounds.setFrame(m_temp);
466                 DisplayLib.fitViewToBounds(d, m_bounds, 0);
467             }
468         }
469     }
470     
471 } // end of class GraphView
472
Popular Tags