1 package prefuse; 2 3 import java.awt.geom.Rectangle2D ; 4 import java.util.ArrayList ; 5 import java.util.Collections ; 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.LinkedHashMap ; 9 import java.util.Map ; 10 11 import prefuse.action.Action; 12 import prefuse.activity.Activity; 13 import prefuse.activity.ActivityMap; 14 import prefuse.data.Graph; 15 import prefuse.data.Node; 16 import prefuse.data.Schema; 17 import prefuse.data.Table; 18 import prefuse.data.Tree; 19 import prefuse.data.Tuple; 20 import prefuse.data.expression.Expression; 21 import prefuse.data.expression.Predicate; 22 import prefuse.data.expression.parser.ExpressionParser; 23 import prefuse.data.tuple.CompositeTupleSet; 24 import prefuse.data.tuple.DefaultTupleSet; 25 import prefuse.data.tuple.TupleManager; 26 import prefuse.data.tuple.TupleSet; 27 import prefuse.render.DefaultRendererFactory; 28 import prefuse.render.Renderer; 29 import prefuse.render.RendererFactory; 30 import prefuse.util.PrefuseConfig; 31 import prefuse.util.PrefuseLib; 32 import prefuse.util.collections.CompositeIterator; 33 import prefuse.visual.AggregateTable; 34 import prefuse.visual.VisualGraph; 35 import prefuse.visual.VisualItem; 36 import prefuse.visual.VisualTable; 37 import prefuse.visual.VisualTree; 38 import prefuse.visual.VisualTupleSet; 39 import prefuse.visual.expression.ValidatedPredicate; 40 import prefuse.visual.expression.VisiblePredicate; 41 import prefuse.visual.tuple.TableDecoratorItem; 42 import prefuse.visual.tuple.TableEdgeItem; 43 import prefuse.visual.tuple.TableNodeItem; 44 45 158 public class Visualization { 159 160 161 public static final String ALL_ITEMS 162 = PrefuseConfig.get("visualization.allItems"); 163 164 public static final String FOCUS_ITEMS 165 = PrefuseConfig.get("visualization.focusItems"); 166 167 public static final String SELECTED_ITEMS 168 = PrefuseConfig.get("visualization.selectedItems"); 169 170 public static final String SEARCH_ITEMS 171 = PrefuseConfig.get("visualization.searchItems"); 172 173 private Map m_visual; 176 private Map m_source; 177 private Map m_focus; 178 179 private ActivityMap m_actions; 181 182 private RendererFactory m_renderers; 184 185 private ArrayList m_displays; 187 188 191 194 public Visualization() { 195 m_actions = new ActivityMap(); 196 m_renderers = new DefaultRendererFactory(); 197 m_visual = new LinkedHashMap (); 198 m_source = new HashMap (); 199 m_focus = new HashMap (); 200 m_displays = new ArrayList (); 201 202 addFocusGroup(Visualization.FOCUS_ITEMS, new DefaultTupleSet()); 203 addFocusGroup(Visualization.SELECTED_ITEMS, new DefaultTupleSet()); 204 } 205 206 209 219 public synchronized VisualTupleSet add(String group, TupleSet data) { 220 return add(group, data, null); 221 } 222 223 235 public synchronized VisualTupleSet add( 236 String group, TupleSet data, Predicate filter) 237 { 238 if ( data instanceof Table ) { 239 return addTable(group, (Table)data, filter); 240 } else if ( data instanceof Tree ) { 241 return addTree(group, (Tree)data, filter); 242 } else if ( data instanceof Graph ) { 243 return addGraph(group, (Graph)data, filter); 244 } else { 245 throw new IllegalArgumentException ("Unsupported TupleSet type."); 246 } 247 } 248 249 protected void checkGroupExists(String group) { 250 if ( m_visual.containsKey(group) || m_focus.containsKey(group) ) { 251 throw new IllegalArgumentException ( 252 "Group name \'"+group+"\' already in use"); 253 } 254 } 255 256 protected void addDataGroup(String group, VisualTupleSet ts, TupleSet src) { 257 checkGroupExists(group); 258 m_visual.put(group, ts); 259 if ( src != null ) 260 m_source.put(group, src); 261 } 262 263 265 274 public synchronized VisualTable addTable(String group) { 275 VisualTable vt = new VisualTable(this, group); 276 addDataGroup(group, vt, null); 277 return vt; 278 } 279 280 290 public synchronized VisualTable addTable(String group, Schema schema) { 291 VisualTable vt = new VisualTable(this, group, schema); 292 addDataGroup(group, vt, null); 293 return vt; 294 } 295 296 304 public synchronized VisualTable addTable(String group, Table table) { 305 return addTable(group, table, (Predicate)null); 306 } 307 308 318 public synchronized VisualTable addTable( 319 String group, Table table, Predicate filter) 320 { 321 VisualTable vt = new VisualTable(table, this, group, filter); 322 addDataGroup(group, vt, table); 323 return vt; 324 } 325 326 335 public synchronized VisualTable addTable( 336 String group, Table table, Schema schema) 337 { 338 return addTable(group, table, null, schema); 339 } 340 341 352 public synchronized VisualTable addTable( 353 String group, Table table, Predicate filter, Schema schema) 354 { 355 VisualTable vt = new VisualTable(table, this, group, filter, schema); 356 addDataGroup(group, vt, table); 357 return vt; 358 } 359 360 371 public synchronized VisualTable addTable(VisualTable table) { 372 addDataGroup(table.getGroup(), table, table.getParentTable()); 373 table.setVisualization(this); 374 return table; 375 } 376 377 379 389 public synchronized VisualGraph addGraph(String group, Graph graph) { 390 return addGraph(group, graph, null); 391 } 392 393 405 public synchronized VisualGraph addGraph( 406 String group, Graph graph, Predicate filter) 407 { 408 return addGraph(group, graph, filter, VisualItem.SCHEMA, VisualItem.SCHEMA); 409 } 410 411 425 public synchronized VisualGraph addGraph(String group, Graph graph, 426 Predicate filter, Schema nodeSchema, Schema edgeSchema) 427 { 428 checkGroupExists(group); String ngroup = PrefuseLib.getGroupName(group, Graph.NODES); 430 String egroup = PrefuseLib.getGroupName(group, Graph.EDGES); 431 432 VisualTable nt, et; 433 nt = addTable(ngroup, graph.getNodeTable(), filter, nodeSchema); 434 et = addTable(egroup, graph.getEdgeTable(), filter, edgeSchema); 435 436 VisualGraph vg = new VisualGraph(nt, et, 437 graph.isDirected(), graph.getNodeKeyField(), 438 graph.getEdgeSourceField(), graph.getEdgeTargetField()); 439 vg.setVisualization(this); 440 vg.setGroup(group); 441 442 addDataGroup(group, vg, graph); 443 444 TupleManager ntm = new TupleManager(nt, vg, TableNodeItem.class); 445 TupleManager etm = new TupleManager(et, vg, TableEdgeItem.class); 446 nt.setTupleManager(ntm); 447 et.setTupleManager(etm); 448 vg.setTupleManagers(ntm, etm); 449 450 return vg; 451 } 452 453 463 public synchronized VisualTree addTree(String group, Tree tree) { 464 return addTree(group, tree, null); 465 } 466 467 479 public synchronized VisualTree addTree( 480 String group, Tree tree, Predicate filter) 481 { 482 return addTree(group, tree, filter, VisualItem.SCHEMA, VisualItem.SCHEMA); 483 } 484 485 499 public synchronized VisualTree addTree(String group, Tree tree, 500 Predicate filter, Schema nodeSchema, Schema edgeSchema) 501 { 502 checkGroupExists(group); String ngroup = PrefuseLib.getGroupName(group, Graph.NODES); 504 String egroup = PrefuseLib.getGroupName(group, Graph.EDGES); 505 506 VisualTable nt, et; 507 nt = addTable(ngroup, tree.getNodeTable(), filter, nodeSchema); 508 et = addTable(egroup, tree.getEdgeTable(), filter, edgeSchema); 509 510 VisualTree vt = new VisualTree(nt, et, tree.getNodeKeyField(), 511 tree.getEdgeSourceField(), tree.getEdgeTargetField()); 512 vt.setVisualization(this); 513 vt.setGroup(group); 514 515 addDataGroup(group, vt, tree); 516 517 TupleManager ntm = new TupleManager(nt, vt, TableNodeItem.class); 518 TupleManager etm = new TupleManager(et, vt, TableEdgeItem.class); 519 nt.setTupleManager(ntm); 520 et.setTupleManager(etm); 521 vt.setTupleManagers(ntm, etm); 522 523 return vt; 524 } 525 526 528 535 public synchronized AggregateTable addAggregates(String group) { 536 return addAggregates(group, VisualItem.SCHEMA); 537 } 538 539 547 public synchronized AggregateTable addAggregates(String group, 548 Schema schema) 549 { 550 AggregateTable vat = new AggregateTable(this, group, schema); 551 addDataGroup(group, vat, null); 552 return vat; 553 } 554 555 557 572 public synchronized VisualTable addDerivedTable( 573 String group, String source, Predicate filter, Schema override) 574 { 575 VisualTable src = (VisualTable)getGroup(source); 576 VisualTable vt = new VisualTable(src, this, group, filter, override); 577 578 addDataGroup(group, vt, getSourceData(source)); 579 return vt; 580 } 581 582 595 public synchronized VisualTable addDecorators(String group,String source) { 596 return addDecorators(group, source, (Predicate)null); 597 } 598 599 613 public synchronized VisualTable addDecorators( 614 String group, String source, Schema schema) 615 { 616 return addDecorators(group, source, null, schema); 617 } 618 619 632 public synchronized VisualTable addDecorators( 633 String group, String source, Predicate filter) 634 { 635 VisualTable t = addDerivedTable(group,source,filter,VisualItem.SCHEMA); 636 t.setTupleManager(new TupleManager(t, null, TableDecoratorItem.class)); 637 return t; 638 } 639 640 656 public synchronized VisualTable addDecorators( 657 String group, String source, Predicate filter, Schema schema) 658 { 659 VisualTable t = addDerivedTable(group, source, filter, schema); 660 t.setTupleManager(new TupleManager(t, null, TableDecoratorItem.class)); 661 return t; 662 } 663 664 666 676 public synchronized boolean removeGroup(String group) { 677 TupleSet ts = getFocusGroup(group); 679 if ( ts != null ) { 680 for ( Iterator items = ts.tuples(ValidatedPredicate.TRUE); 682 items.hasNext(); ) 683 { 684 ((VisualItem)items.next()).setValidated(false); 685 } 686 ts.clear(); m_focus.remove(group); 688 return true; 689 } 690 691 ts = getVisualGroup(group); 693 if ( ts == null ) { 694 return false; 696 } 697 TupleSet[] focus = new TupleSet[m_focus.size()]; 699 m_focus.values().toArray(focus); 700 for ( Iterator items = ts.tuples(); items.hasNext(); ) { 701 VisualItem item = (VisualItem)items.next(); 702 for ( int j=0; j<focus.length; ++j ) { 703 focus[j].removeTuple(item); 704 } 705 item.setValidated(false); 706 } 707 if ( ts instanceof CompositeTupleSet ) { 709 CompositeTupleSet cts = (CompositeTupleSet)ts; 710 for ( Iterator names = cts.setNames(); names.hasNext(); ) { 711 String name = (String )names.next(); 712 String subgroup = PrefuseLib.getGroupName(group,name); 713 m_visual.remove(subgroup); 714 m_source.remove(subgroup); 715 } 716 } 717 m_visual.remove(group); 718 m_source.remove(group); 719 return true; 720 } 721 722 729 public synchronized void reset() { 730 Iterator iter = m_focus.entrySet().iterator(); 732 while ( iter.hasNext() ) { 733 Map.Entry entry = (Map.Entry )iter.next(); 734 TupleSet ts = (TupleSet)entry.getValue(); 735 ts.clear(); 736 } 737 m_visual.clear(); 739 m_source.clear(); 740 } 741 742 745 750 public TupleSet getSourceData(String group) { 751 return (TupleSet)m_source.get(group); 752 } 753 754 759 public TupleSet getSourceData(VisualTupleSet ts) { 760 return (TupleSet)m_source.get(ts.getGroup()); 761 } 762 763 770 public Tuple getSourceTuple(VisualItem item) { 771 String group = item.getGroup(); 773 TupleSet source = getSourceData(group); 774 if ( source == null ) return null; 775 776 int row = item.getRow(); 778 Table t = item.getTable(); 779 while ( t instanceof VisualTable ) { 780 VisualTable vt = (VisualTable)t; 781 row = vt.getParentRow(row); 782 t = vt.getParentTable(); 783 } 784 785 String cgroup = PrefuseLib.getChildGroup(group); 788 if ( cgroup != null ) { 789 String pgroup = PrefuseLib.getParentGroup(group); 790 Graph g = (Graph)getSourceData(pgroup); 791 if ( t == g.getNodeTable() ) { 792 return g.getNode(row); 793 } else { 794 return g.getEdge(row); 795 } 796 } else { 797 return t.getTuple(row); 798 } 799 } 800 801 809 public VisualItem getVisualItem(String group, Tuple t) { 810 TupleSet ts = getVisualGroup(group); 811 VisualTable vt; 812 if ( ts instanceof VisualTable ) { 813 vt = (VisualTable)ts; 814 } else if ( ts instanceof Graph ) { 815 Graph g = (Graph)ts; 816 vt = (VisualTable)(t instanceof Node ? g.getNodeTable() 817 : g.getEdgeTable()); 818 } else { 819 return null; 820 } 821 int pr = t.getRow(); 822 int cr = vt.getChildRow(pr); 823 return cr<0 ? null : vt.getItem(cr); 824 } 825 826 828 833 public TupleSet getGroup(String group) { 834 TupleSet ts = getVisualGroup(group); 835 if ( ts == null ) 836 ts = getFocusGroup(group); 837 return ts; 838 } 839 840 847 public boolean isInGroup(VisualItem item, String group) { 848 if ( ALL_ITEMS.equals(group) ) 849 return true; 850 if ( item.getGroup() == group ) 851 return true; 852 853 TupleSet tset = getGroup(group); 854 return ( tset==null ? false : tset.containsTuple(item) ); 855 } 856 857 863 public void addFocusGroup(String group) { 864 checkGroupExists(group); 865 m_focus.put(group, new DefaultTupleSet()); 866 } 867 868 873 public void addFocusGroup(String group, TupleSet tset) { 874 checkGroupExists(group); 875 m_focus.put(group, tset); 876 } 877 878 881 886 public int size(String group) { 887 TupleSet tset = getGroup(group); 888 return ( tset==null ? 0 : tset.getTupleCount() ); 889 } 890 891 897 public TupleSet getVisualGroup(String group) { 898 return (TupleSet)m_visual.get(group); 899 } 900 901 907 public TupleSet getFocusGroup(String group) { 908 return (TupleSet)m_focus.get(group); 909 } 910 911 917 public void invalidate(String group) { 918 Iterator items = items(ValidatedPredicate.TRUE); 919 while ( items.hasNext() ) { 920 VisualItem item = (VisualItem)items.next(); 921 item.setValidated(false); 922 } 923 } 924 925 930 public void invalidateAll() { 931 invalidate(ALL_ITEMS); 932 } 933 934 938 public Iterator visibleItems() { 939 return items(VisiblePredicate.TRUE); 940 } 941 942 947 public Iterator visibleItems(String group) { 948 return items(group, VisiblePredicate.TRUE); 949 } 950 951 955 public Iterator items() { 956 return items((Predicate)null); 957 } 958 959 966 public Iterator items(Predicate filter) { 967 int size = m_visual.size(); 968 if ( size == 0 ) { 969 return Collections.EMPTY_LIST.iterator(); 970 } else if ( size == 1 ) { 971 Iterator it = m_visual.keySet().iterator(); 972 return items((String )it.next(), filter); 973 } else { 974 CompositeIterator iter = new CompositeIterator(m_visual.size()); 975 Iterator it = m_visual.keySet().iterator(); 976 for ( int i=0; it.hasNext(); ) { 977 String group = (String )it.next(); 978 if ( !PrefuseLib.isChildGroup(group) ) 979 iter.setIterator(i++, items(group, filter)); 980 } 981 return iter; 982 } 983 } 984 985 990 public Iterator items(String group) { 991 return items(group, (Predicate)null); 992 } 993 994 1005 public Iterator items(String group, String expr) { 1006 Expression e = ExpressionParser.parse(expr); 1007 if ( !(e instanceof Predicate) || ExpressionParser.getError()!=null ) 1008 return Collections.EMPTY_LIST.iterator(); 1009 return items(group, (Predicate)e); 1010 } 1011 1012 1020 public Iterator items(String group, Predicate filter) { 1021 if ( ALL_ITEMS.equals(group) ) 1022 return items(filter); 1023 1024 TupleSet t = getGroup(group); 1025 return ( t==null ? Collections.EMPTY_LIST.iterator() 1026 : t.tuples(filter) ); 1027 } 1028 1029 1032 1040 public void setValue(String group, Predicate p, String field, Object val) { 1041 Iterator items = items(group, p); 1042 while ( items.hasNext() ) { 1043 VisualItem item = (VisualItem)items.next(); 1044 item.set(field, val); 1045 } 1046 } 1047 1048 1055 public void setVisible(String group, Predicate p, boolean value) { 1056 Iterator items = items(group, p); 1057 while ( items.hasNext() ) { 1058 VisualItem item = (VisualItem)items.next(); 1059 item.setVisible(value); 1060 } 1061 } 1062 1063 1070 public void setInteractive(String group, Predicate p, boolean value) { 1071 Iterator items = items(group, p); 1072 while ( items.hasNext() ) { 1073 VisualItem item = (VisualItem)items.next(); 1074 item.setInteractive(value); 1075 } 1076 } 1077 1078 1081 1087 public Action putAction(String name, Action action) { 1088 action.setVisualization(this); 1089 m_actions.put(name, action); 1090 return action; 1091 } 1092 1093 1098 public Action getAction(String name) { 1099 return (Action)m_actions.get(name); 1100 } 1101 1102 1110 public Activity run(String action) { 1111 return m_actions.run(action); 1112 } 1113 1114 1124 public Activity runAfter(String action, long delay) { 1125 return m_actions.runAt(action, System.currentTimeMillis()+delay); 1126 } 1127 1128 1138 public Activity runAt(String action, long startTime) { 1139 return m_actions.runAt(action, startTime); 1140 } 1141 1142 1153 public Activity runAfter(String before, String after) { 1154 return m_actions.runAfter(before, after); 1155 } 1156 1157 1166 public Activity alwaysRunAfter(String before, String after) { 1167 return m_actions.alwaysRunAfter(before, after); 1168 } 1169 1170 1175 public Activity cancel(String action) { 1176 return m_actions.cancel(action); 1177 } 1178 1179 1182 1188 public void setRendererFactory(RendererFactory rf) { 1189 invalidateAll(); 1190 m_renderers = rf; 1191 } 1192 1193 1197 public RendererFactory getRendererFactory() { 1198 return m_renderers; 1199 } 1200 1201 1208 public Renderer getRenderer(VisualItem item) { 1209 if ( item.getVisualization() != this ) { 1210 throw new IllegalArgumentException ( 1211 "Input item not a member of this visualization."); 1212 } 1213 return m_renderers.getRenderer(item); 1214 } 1215 1216 1220 public synchronized void repaint() { 1221 Iterator items = items(ValidatedPredicate.FALSE); 1222 while ( items.hasNext() ) { 1223 ((VisualItem)items.next()).validateBounds(); 1224 } 1225 for ( int i=0; i<m_displays.size(); ++i ) { 1226 getDisplay(i).repaint(); 1227 } 1228 } 1229 1230 1235 public Rectangle2D getBounds(String group) { 1236 return getBounds(group, new Rectangle2D.Double ()); 1237 } 1238 1239 1246 public Rectangle2D getBounds(String group, Rectangle2D r) { 1247 Iterator iter = visibleItems(group); 1248 if ( iter.hasNext() ) { 1249 VisualItem item = (VisualItem)iter.next(); 1250 r.setRect(item.getBounds()); 1251 } 1252 while ( iter.hasNext() ) { 1253 VisualItem item = (VisualItem)iter.next(); 1254 Rectangle2D.union(item.getBounds(), r, r); 1255 } 1256 return r; 1257 } 1258 1259 1262 1266 public int getDisplayCount() { 1267 return m_displays.size(); 1268 } 1269 1270 1275 void addDisplay(Display display) { 1276 m_displays.add(display); 1277 } 1278 1279 1285 public Display getDisplay(int idx) { 1286 return (Display)m_displays.get(idx); 1287 } 1288 1289 1294 boolean removeDisplay(Display display) { 1295 return m_displays.remove(display); 1296 } 1297 1298 1304 public void damageReport(VisualItem item, Rectangle2D region) { 1305 for ( int i=0; i<m_displays.size(); ++i ) { 1306 Display d = getDisplay(i); 1307 if ( d.getPredicate().getBoolean(item) ) { 1308 d.damageReport(region); 1309 } 1310 } 1311 } 1312 1313} | Popular Tags |