KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > picocontainer > gems > monitors > prefuse > AggregateDemoHacks


1 package org.picocontainer.gems.monitors.prefuse;
2
3 import java.awt.Cursor JavaDoc;
4 import java.awt.event.MouseEvent JavaDoc;
5 import java.awt.geom.Point2D JavaDoc;
6 import java.awt.geom.Rectangle2D JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Iterator JavaDoc;
10 import java.util.Map JavaDoc;
11
12 import javax.swing.JFrame JavaDoc;
13 import javax.swing.SwingUtilities JavaDoc;
14
15 import prefuse.Constants;
16 import prefuse.Display;
17 import prefuse.Visualization;
18 import prefuse.action.ActionList;
19 import prefuse.action.RepaintAction;
20 import prefuse.action.assignment.ColorAction;
21 import prefuse.action.assignment.DataColorAction;
22 import prefuse.action.layout.Layout;
23 import prefuse.action.layout.graph.ForceDirectedLayout;
24 import prefuse.activity.Activity;
25 import prefuse.controls.ControlAdapter;
26 import prefuse.controls.PanControl;
27 import prefuse.controls.ZoomControl;
28 import prefuse.data.Graph;
29 import prefuse.render.DefaultRendererFactory;
30 import prefuse.render.EdgeRenderer;
31 import prefuse.render.LabelRenderer;
32 import prefuse.render.PolygonRenderer;
33 import prefuse.render.Renderer;
34 import prefuse.util.ColorLib;
35 import prefuse.util.GraphicsLib;
36 import prefuse.visual.AggregateItem;
37 import prefuse.visual.AggregateTable;
38 import prefuse.visual.EdgeItem;
39 import prefuse.visual.VisualGraph;
40 import prefuse.visual.VisualItem;
41
42 /**
43  * Demo application showcasing the use of AggregateItems to visualize groupings
44  * of nodes with in a graph visualization.
45  *
46  * This class uses the AggregateLayout class to compute bounding polygons for
47  * each aggregate and the AggregateDragControl to enable drags of both nodes and
48  * node aggregates.
49  *
50  * @author <a HREF="http://jheer.org">jeffrey heer</a>
51  */

52 public class AggregateDemoHacks extends Display {
53     private static final int LIGHT_BLUE = ColorLib.rgba(200, 200, 255, 150);
54
55     private static final int LIGHT_GREEN = ColorLib.rgba(200, 255, 200, 150);
56
57     private static final int LIGHT_RED = ColorLib.rgba(255, 200, 200, 150);
58
59     private static final int WHITE = ColorLib.gray(255);
60
61     private static final String JavaDoc GRAPH = "graph";
62
63     private static final String JavaDoc NODES = "graph.nodes";
64
65     private static final String JavaDoc EDGES = "graph.edges";
66
67     private static final String JavaDoc EDGE_HEADS = "graph.edges.arrowheads";
68
69     private static final String JavaDoc AGGR = "aggregates";
70
71     private final int BLACK = ColorLib.gray(0);
72
73     public AggregateDemoHacks(Graph g) throws IOException JavaDoc {
74
75         super(new Visualization());
76         initDataGroups(g);
77
78         Renderer polyR = new PolygonRenderer(Constants.POLY_TYPE_CURVE);
79         ((PolygonRenderer) polyR).setCurveSlack(0.15f);
80
81         LabelRenderer labelRenderer = new LabelRenderer("type");
82         labelRenderer.setRoundedCorner(8, 8);
83
84         EdgeRenderer edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_LINE);
85
86         DefaultRendererFactory drf = new DefaultRendererFactory(labelRenderer);
87         drf.add("ingroup('aggregates')", polyR);
88         drf.add("ingroup('aggregates')", labelRenderer);
89         drf.setDefaultEdgeRenderer(edgeRenderer);
90         m_vis.setRendererFactory(drf);
91
92         ActionList layout = buildActionList();
93         m_vis.putAction("layout", layout);
94
95         setSize(500, 500);
96         pan(250, 250);
97         setHighQuality(true);
98         addControlListener(new AggregateDragControl());
99         addControlListener(new ZoomControl());
100         addControlListener(new PanControl());
101
102         m_vis.run("layout");
103     }
104
105     private ActionList buildColorActionList() {
106         ColorAction nStroke = new ColorAction(NODES, VisualItem.STROKECOLOR);
107         nStroke.setDefaultColor(ColorLib.gray(100));
108         nStroke.add("_hover", ColorLib.gray(50));
109
110         ColorAction nFill = new ColorAction(NODES, VisualItem.FILLCOLOR);
111         nFill.setDefaultColor(WHITE);
112         nFill.add("_hover", ColorLib.gray(200));
113
114         ColorAction nEdges = new ColorAction(EDGES, VisualItem.STROKECOLOR);
115         nEdges.setDefaultColor(ColorLib.gray(100));
116         ColorAction nEdgesHeads = new ColorAction(EDGES, VisualItem.FILLCOLOR);
117         nEdgesHeads.setDefaultColor(ColorLib.gray(100));
118
119         ColorAction classNames = new ColorAction(NODES, VisualItem.TEXTCOLOR);
120         classNames.setDefaultColor(BLACK);
121
122         ColorAction aStroke = new ColorAction(AGGR, VisualItem.STROKECOLOR);
123         aStroke.setDefaultColor(ColorLib.gray(200));
124         aStroke.add("_hover", ColorLib.rgb(255, 100, 100));
125
126         int[] palette = new int[] { LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE };
127         ColorAction aFill = new DataColorAction(AGGR, "type", Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
128
129         // bundle the color actions
130
ActionList colors = new ActionList();
131         colors.add(classNames);
132         colors.add(nStroke);
133         colors.add(nFill);
134         colors.add(nEdges);
135         colors.add(nEdgesHeads);
136         colors.add(aStroke);
137         colors.add(aFill);
138         return colors;
139     }
140
141     private ActionList buildActionList() {
142         ActionList colors = buildColorActionList();
143         ActionList all = new ActionList(Activity.INFINITY);
144         all.add(colors);
145         all.add(new ForceDirectedLayout(GRAPH) {
146             protected float getSpringLength(EdgeItem e) {
147                 return -0.3f;
148             }
149
150             protected float getMassValue(VisualItem n) {
151                 return 5.0f;
152             }
153         });
154
155         all.add(new AggregateLayout(AGGR));
156         all.add(new RepaintAction());
157         return all;
158     }
159
160     private void initDataGroups(Graph graph) throws IOException JavaDoc {
161         Graph g = graph;
162
163         VisualGraph vg = m_vis.addGraph(GRAPH, g);
164         m_vis.setInteractive(EDGES, null, false);
165         m_vis.setValue(NODES, null, VisualItem.SHAPE, new Integer JavaDoc(Constants.SHAPE_ELLIPSE));
166
167         AggregateTable at = m_vis.addAggregates(AGGR);
168         at.addColumn(VisualItem.POLYGON, float[].class);
169         at.addColumn("type", String JavaDoc.class);
170
171         System.out.println("Aggregating...");
172         Map JavaDoc aggregates = new HashMap JavaDoc();
173         Iterator JavaDoc nodes = vg.nodes();
174         while (nodes.hasNext()) {
175             VisualItem node = (VisualItem) nodes.next();
176             String JavaDoc pkg = node.getString("type");
177             System.out.println(pkg);
178             if (!aggregates.containsKey(pkg)) {
179                 AggregateItem aggregate = (AggregateItem) at.addItem();
180                 aggregate.setString("type", pkg);
181                 aggregates.put(pkg, aggregate);
182             }
183             AggregateItem aggregate = (AggregateItem) aggregates.get(pkg);
184             aggregate.addItem(node);
185         }
186         System.out.println("done!");
187     }
188
189     public static JFrame JavaDoc demo(Graph graph) throws IOException JavaDoc {
190         AggregateDemoHacks ad = new AggregateDemoHacks(graph);
191         JFrame JavaDoc frame = new JFrame JavaDoc("p r e f u s e | a g g r e g a t e d");
192         frame.getContentPane().add(ad);
193         frame.pack();
194         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
195         frame.setVisible(true);
196         return frame;
197     }
198
199 } // end of class AggregateDemo
200

201 /**
202  * Layout algorithm that computes a convex hull surrounding aggregate items and
203  * saves it in the "_polygon" field.
204  */

205 class AggregateLayout extends Layout {
206
207     private int m_margin = 5; // convex hull pixel margin
208

209     private double[] m_pts; // buffer for computing convex hulls
210

211     public AggregateLayout(String JavaDoc aggrGroup) {
212         super(aggrGroup);
213     }
214
215     /**
216      * @see edu.berkeley.guir.prefuse.action.Action#run(edu.berkeley.guir.prefuse.ItemRegistry,
217      * double)
218      */

219     public void run(double frac) {
220
221         AggregateTable aggr = (AggregateTable) m_vis.getGroup(m_group);
222         // do we have any to process?
223
int num = aggr.getTupleCount();
224         if (num == 0)
225             return;
226
227         // update buffers
228
int maxsz = 0;
229         for (Iterator JavaDoc aggrs = aggr.tuples(); aggrs.hasNext();)
230             maxsz = Math.max(maxsz, 4 * 2 * ((AggregateItem) aggrs.next()).getAggregateSize());
231         if (m_pts == null || maxsz > m_pts.length) {
232             m_pts = new double[maxsz];
233         }
234
235         // compute and assign convex hull for each aggregate
236
Iterator JavaDoc aggrs = m_vis.visibleItems(m_group);
237         while (aggrs.hasNext()) {
238             AggregateItem aitem = (AggregateItem) aggrs.next();
239
240             int idx = 0;
241             if (aitem.getAggregateSize() == 0)
242                 continue;
243             VisualItem item = null;
244             Iterator JavaDoc iter = aitem.items();
245             while (iter.hasNext()) {
246                 item = (VisualItem) iter.next();
247                 if (item.isVisible()) {
248                     addPoint(m_pts, idx, item, m_margin);
249                     idx += 2 * 4;
250                 }
251             }
252             // if no aggregates are visible, do nothing
253
if (idx == 0)
254                 continue;
255
256             // compute convex hull
257
double[] nhull = GraphicsLib.convexHull(m_pts, idx);
258
259             // prepare viz attribute array
260
float[] fhull = (float[]) aitem.get(VisualItem.POLYGON);
261             if (fhull == null || fhull.length < nhull.length)
262                 fhull = new float[nhull.length];
263             else if (fhull.length > nhull.length)
264                 fhull[nhull.length] = Float.NaN;
265
266             // copy hull values
267
for (int j = 0; j < nhull.length; j++)
268                 fhull[j] = (float) nhull[j];
269             aitem.set(VisualItem.POLYGON, fhull);
270             aitem.setValidated(false); // force invalidation
271
}
272     }
273
274     private static void addPoint(double[] pts, int idx, VisualItem item, int growth) {
275         Rectangle2D JavaDoc b = item.getBounds();
276         double minX = (b.getMinX()) - growth, minY = (b.getMinY()) - growth;
277         double maxX = (b.getMaxX()) + growth, maxY = (b.getMaxY()) + growth;
278         pts[idx] = minX;
279         pts[idx + 1] = minY;
280         pts[idx + 2] = minX;
281         pts[idx + 3] = maxY;
282         pts[idx + 4] = maxX;
283         pts[idx + 5] = minY;
284         pts[idx + 6] = maxX;
285         pts[idx + 7] = maxY;
286     }
287
288 } // end of class AggregateLayout
289

290 /**
291  * Interactive drag control that is "aggregate-aware"
292  */

293 class AggregateDragControl extends ControlAdapter {
294
295     private VisualItem activeItem;
296
297     protected Point2D JavaDoc down = new Point2D.Double JavaDoc();
298
299     protected Point2D JavaDoc temp = new Point2D.Double JavaDoc();
300
301     protected boolean dragged;
302
303     /**
304      * Creates a new drag control that issues repaint requests as an item is
305      * dragged.
306      */

307     public AggregateDragControl() {
308     }
309
310     /**
311      * @see prefuse.controls.Control#itemEntered(prefuse.visual.VisualItem,
312      * java.awt.event.MouseEvent)
313      */

314     public void itemEntered(VisualItem item, MouseEvent JavaDoc e) {
315         Display d = (Display) e.getSource();
316         d.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
317         activeItem = item;
318         if (!(item instanceof AggregateItem))
319             setFixed(item, true);
320     }
321
322     /**
323      * @see prefuse.controls.Control#itemExited(prefuse.visual.VisualItem,
324      * java.awt.event.MouseEvent)
325      */

326     public void itemExited(VisualItem item, MouseEvent JavaDoc e) {
327         if (activeItem == item) {
328             activeItem = null;
329             setFixed(item, false);
330         }
331         Display d = (Display) e.getSource();
332         d.setCursor(Cursor.getDefaultCursor());
333     }
334
335     /**
336      * @see prefuse.controls.Control#itemPressed(prefuse.visual.VisualItem,
337      * java.awt.event.MouseEvent)
338      */

339     public void itemPressed(VisualItem item, MouseEvent JavaDoc e) {
340         if (!SwingUtilities.isLeftMouseButton(e))
341             return;
342         dragged = false;
343         Display d = (Display) e.getComponent();
344         d.getAbsoluteCoordinate(e.getPoint(), down);
345         if (item instanceof AggregateItem)
346             setFixed(item, true);
347     }
348
349     /**
350      * @see prefuse.controls.Control#itemReleased(prefuse.visual.VisualItem,
351      * java.awt.event.MouseEvent)
352      */

353     public void itemReleased(VisualItem item, MouseEvent JavaDoc e) {
354         if (!SwingUtilities.isLeftMouseButton(e))
355             return;
356         if (dragged) {
357             activeItem = null;
358             setFixed(item, false);
359             dragged = false;
360         }
361     }
362
363     /**
364      * @see prefuse.controls.Control#itemDragged(prefuse.visual.VisualItem,
365      * java.awt.event.MouseEvent)
366      */

367     public void itemDragged(VisualItem item, MouseEvent JavaDoc e) {
368         if (!SwingUtilities.isLeftMouseButton(e))
369             return;
370         dragged = true;
371         Display d = (Display) e.getComponent();
372         d.getAbsoluteCoordinate(e.getPoint(), temp);
373         double dx = temp.getX() - down.getX();
374         double dy = temp.getY() - down.getY();
375
376         move(item, dx, dy);
377
378         down.setLocation(temp);
379     }
380
381     protected static void setFixed(VisualItem item, boolean fixed) {
382         if (item instanceof AggregateItem) {
383             Iterator JavaDoc items = ((AggregateItem) item).items();
384             while (items.hasNext()) {
385                 setFixed((VisualItem) items.next(), fixed);
386             }
387         } else {
388             item.setFixed(fixed);
389         }
390     }
391
392     protected static void move(VisualItem item, double dx, double dy) {
393         if (item instanceof AggregateItem) {
394             Iterator JavaDoc items = ((AggregateItem) item).items();
395             while (items.hasNext()) {
396                 move((VisualItem) items.next(), dx, dy);
397             }
398         } else {
399             double x = item.getX();
400             double y = item.getY();
401             item.setStartX(x);
402             item.setStartY(y);
403             item.setX(x + dx);
404             item.setY(y + dy);
405             item.setEndX(x + dx);
406             item.setEndY(y + dy);
407         }
408     }
409
410 } // end of class AggregateDragControl
411
Popular Tags