1 5 package prefuse.demos; 6 7 import java.awt.Cursor ; 8 import java.awt.event.MouseEvent ; 9 import java.awt.geom.Point2D ; 10 import java.awt.geom.Rectangle2D ; 11 import java.util.Iterator ; 12 13 import javax.swing.JFrame ; 14 import javax.swing.SwingUtilities ; 15 16 import prefuse.Constants; 17 import prefuse.Display; 18 import prefuse.Visualization; 19 import prefuse.action.ActionList; 20 import prefuse.action.RepaintAction; 21 import prefuse.action.assignment.ColorAction; 22 import prefuse.action.assignment.DataColorAction; 23 import prefuse.action.layout.Layout; 24 import prefuse.action.layout.graph.ForceDirectedLayout; 25 import prefuse.activity.Activity; 26 import prefuse.controls.ControlAdapter; 27 import prefuse.controls.PanControl; 28 import prefuse.controls.ZoomControl; 29 import prefuse.data.Graph; 30 import prefuse.data.Node; 31 import prefuse.render.DefaultRendererFactory; 32 import prefuse.render.PolygonRenderer; 33 import prefuse.render.Renderer; 34 import prefuse.render.ShapeRenderer; 35 import prefuse.util.ColorLib; 36 import prefuse.util.GraphicsLib; 37 import prefuse.visual.AggregateItem; 38 import prefuse.visual.AggregateTable; 39 import prefuse.visual.VisualGraph; 40 import prefuse.visual.VisualItem; 41 42 43 53 public class AggregateDemo extends Display { 54 55 public static final String GRAPH = "graph"; 56 public static final String NODES = "graph.nodes"; 57 public static final String EDGES = "graph.edges"; 58 public static final String AGGR = "aggregates"; 59 60 public AggregateDemo() { 61 super(new Visualization()); 63 initDataGroups(); 64 65 Renderer nodeR = new ShapeRenderer(20); 68 Renderer polyR = new PolygonRenderer(Constants.POLY_TYPE_CURVE); 70 ((PolygonRenderer)polyR).setCurveSlack(0.15f); 71 72 DefaultRendererFactory drf = new DefaultRendererFactory(); 73 drf.setDefaultRenderer(nodeR); 74 drf.add("ingroup('aggregates')", polyR); 75 m_vis.setRendererFactory(drf); 76 77 ColorAction nStroke = new ColorAction(NODES, VisualItem.STROKECOLOR); 80 nStroke.setDefaultColor(ColorLib.gray(100)); 81 nStroke.add("_hover", ColorLib.gray(50)); 82 83 ColorAction nFill = new ColorAction(NODES, VisualItem.FILLCOLOR); 84 nFill.setDefaultColor(ColorLib.gray(255)); 85 nFill.add("_hover", ColorLib.gray(200)); 86 87 ColorAction nEdges = new ColorAction(EDGES, VisualItem.STROKECOLOR); 88 nEdges.setDefaultColor(ColorLib.gray(100)); 89 90 ColorAction aStroke = new ColorAction(AGGR, VisualItem.STROKECOLOR); 91 aStroke.setDefaultColor(ColorLib.gray(200)); 92 aStroke.add("_hover", ColorLib.rgb(255,100,100)); 93 94 int[] palette = new int[] { 95 ColorLib.rgba(255,200,200,150), 96 ColorLib.rgba(200,255,200,150), 97 ColorLib.rgba(200,200,255,150) 98 }; 99 ColorAction aFill = new DataColorAction(AGGR, "id", 100 Constants.NOMINAL, VisualItem.FILLCOLOR, palette); 101 102 ActionList colors = new ActionList(); 104 colors.add(nStroke); 105 colors.add(nFill); 106 colors.add(nEdges); 107 colors.add(aStroke); 108 colors.add(aFill); 109 110 ActionList layout = new ActionList(Activity.INFINITY); 112 layout.add(colors); 113 layout.add(new ForceDirectedLayout(GRAPH, true)); 114 layout.add(new AggregateLayout(AGGR)); 115 layout.add(new RepaintAction()); 116 m_vis.putAction("layout", layout); 117 118 setSize(500,500); 120 pan(250, 250); 121 setHighQuality(true); 122 addControlListener(new AggregateDragControl()); 123 addControlListener(new ZoomControl()); 124 addControlListener(new PanControl()); 125 126 m_vis.run("layout"); 128 } 129 130 private void initDataGroups() { 131 Graph g = new Graph(); 134 for ( int i=0; i<3; ++i ) { 135 Node n1 = g.addNode(); 136 Node n2 = g.addNode(); 137 Node n3 = g.addNode(); 138 g.addEdge(n1, n2); 139 g.addEdge(n1, n3); 140 g.addEdge(n2, n3); 141 } 142 g.addEdge(0, 3); 143 g.addEdge(3, 6); 144 g.addEdge(6, 0); 145 146 VisualGraph vg = m_vis.addGraph(GRAPH, g); 148 m_vis.setInteractive(EDGES, null, false); 149 m_vis.setValue(NODES, null, VisualItem.SHAPE, 150 new Integer (Constants.SHAPE_ELLIPSE)); 151 152 AggregateTable at = m_vis.addAggregates(AGGR); 153 at.addColumn(VisualItem.POLYGON, float[].class); 154 at.addColumn("id", int.class); 155 156 Iterator nodes = vg.nodes(); 159 for ( int i=0; i<3; ++i ) { 160 AggregateItem aitem = (AggregateItem)at.addItem(); 161 aitem.setInt("id", i); 162 for ( int j=0; j<3; ++j ) { 163 aitem.addItem((VisualItem)nodes.next()); 164 } 165 } 166 } 167 168 public static void main(String [] argv) { 169 JFrame frame = demo(); 170 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 171 frame.setVisible(true); 172 } 173 174 public static JFrame demo() { 175 AggregateDemo ad = new AggregateDemo(); 176 JFrame frame = new JFrame ("p r e f u s e | a g g r e g a t e d"); 177 frame.getContentPane().add(ad); 178 frame.pack(); 179 return frame; 180 } 181 182 } 184 185 189 class AggregateLayout extends Layout { 190 191 private int m_margin = 5; private double[] m_pts; 194 public AggregateLayout(String aggrGroup) { 195 super(aggrGroup); 196 } 197 198 201 public void run(double frac) { 202 203 AggregateTable aggr = (AggregateTable)m_vis.getGroup(m_group); 204 int num = aggr.getTupleCount(); 206 if ( num == 0 ) return; 207 208 int maxsz = 0; 210 for ( Iterator aggrs = aggr.tuples(); aggrs.hasNext(); ) 211 maxsz = Math.max(maxsz, 4*2* 212 ((AggregateItem)aggrs.next()).getAggregateSize()); 213 if ( m_pts == null || maxsz > m_pts.length ) { 214 m_pts = new double[maxsz]; 215 } 216 217 Iterator aggrs = m_vis.visibleItems(m_group); 219 while ( aggrs.hasNext() ) { 220 AggregateItem aitem = (AggregateItem)aggrs.next(); 221 222 int idx = 0; 223 if ( aitem.getAggregateSize() == 0 ) continue; 224 VisualItem item = null; 225 Iterator iter = aitem.items(); 226 while ( iter.hasNext() ) { 227 item = (VisualItem)iter.next(); 228 if ( item.isVisible() ) { 229 addPoint(m_pts, idx, item, m_margin); 230 idx += 2*4; 231 } 232 } 233 if ( idx == 0 ) continue; 235 236 double[] nhull = GraphicsLib.convexHull(m_pts, idx); 238 239 float[] fhull = (float[])aitem.get(VisualItem.POLYGON); 241 if ( fhull == null || fhull.length < nhull.length ) 242 fhull = new float[nhull.length]; 243 else if ( fhull.length > nhull.length ) 244 fhull[nhull.length] = Float.NaN; 245 246 for ( int j=0; j<nhull.length; j++ ) 248 fhull[j] = (float)nhull[j]; 249 aitem.set(VisualItem.POLYGON, fhull); 250 aitem.setValidated(false); } 252 } 253 254 private static void addPoint(double[] pts, int idx, 255 VisualItem item, int growth) 256 { 257 Rectangle2D b = item.getBounds(); 258 double minX = (b.getMinX())-growth, minY = (b.getMinY())-growth; 259 double maxX = (b.getMaxX())+growth, maxY = (b.getMaxY())+growth; 260 pts[idx] = minX; pts[idx+1] = minY; 261 pts[idx+2] = minX; pts[idx+3] = maxY; 262 pts[idx+4] = maxX; pts[idx+5] = minY; 263 pts[idx+6] = maxX; pts[idx+7] = maxY; 264 } 265 266 } 268 269 272 class AggregateDragControl extends ControlAdapter { 273 274 private VisualItem activeItem; 275 protected Point2D down = new Point2D.Double (); 276 protected Point2D temp = new Point2D.Double (); 277 protected boolean dragged; 278 279 283 public AggregateDragControl() { 284 } 285 286 289 public void itemEntered(VisualItem item, MouseEvent e) { 290 Display d = (Display)e.getSource(); 291 d.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 292 activeItem = item; 293 if ( !(item instanceof AggregateItem) ) 294 setFixed(item, true); 295 } 296 297 300 public void itemExited(VisualItem item, MouseEvent e) { 301 if ( activeItem == item ) { 302 activeItem = null; 303 setFixed(item, false); 304 } 305 Display d = (Display)e.getSource(); 306 d.setCursor(Cursor.getDefaultCursor()); 307 } 308 309 312 public void itemPressed(VisualItem item, MouseEvent e) { 313 if (!SwingUtilities.isLeftMouseButton(e)) return; 314 dragged = false; 315 Display d = (Display)e.getComponent(); 316 d.getAbsoluteCoordinate(e.getPoint(), down); 317 if ( item instanceof AggregateItem ) 318 setFixed(item, true); 319 } 320 321 324 public void itemReleased(VisualItem item, MouseEvent e) { 325 if (!SwingUtilities.isLeftMouseButton(e)) return; 326 if ( dragged ) { 327 activeItem = null; 328 setFixed(item, false); 329 dragged = false; 330 } 331 } 332 333 336 public void itemDragged(VisualItem item, MouseEvent e) { 337 if (!SwingUtilities.isLeftMouseButton(e)) return; 338 dragged = true; 339 Display d = (Display)e.getComponent(); 340 d.getAbsoluteCoordinate(e.getPoint(), temp); 341 double dx = temp.getX()-down.getX(); 342 double dy = temp.getY()-down.getY(); 343 344 move(item, dx, dy); 345 346 down.setLocation(temp); 347 } 348 349 protected static void setFixed(VisualItem item, boolean fixed) { 350 if ( item instanceof AggregateItem ) { 351 Iterator items = ((AggregateItem)item).items(); 352 while ( items.hasNext() ) { 353 setFixed((VisualItem)items.next(), fixed); 354 } 355 } else { 356 item.setFixed(fixed); 357 } 358 } 359 360 protected static void move(VisualItem item, double dx, double dy) { 361 if ( item instanceof AggregateItem ) { 362 Iterator items = ((AggregateItem)item).items(); 363 while ( items.hasNext() ) { 364 move((VisualItem)items.next(), dx, dy); 365 } 366 } else { 367 double x = item.getX(); 368 double y = item.getY(); 369 item.setStartX(x); item.setStartY(y); 370 item.setX(x+dx); item.setY(y+dy); 371 item.setEndX(x+dx); item.setEndY(y+dy); 372 } 373 } 374 375 } | Popular Tags |