1 package prefuse.action.filter; 2 3 import java.util.Iterator ; 4 5 import prefuse.Constants; 6 import prefuse.Visualization; 7 import prefuse.action.GroupAction; 8 import prefuse.data.Graph; 9 import prefuse.data.Tree; 10 import prefuse.data.expression.Predicate; 11 import prefuse.util.PrefuseLib; 12 import prefuse.visual.EdgeItem; 13 import prefuse.visual.NodeItem; 14 import prefuse.visual.VisualItem; 15 import prefuse.visual.expression.InGroupPredicate; 16 17 37 public class FisheyeTreeFilter extends GroupAction { 38 39 private String m_sources; 40 private Predicate m_groupP; 41 42 private int m_threshold; 43 44 private NodeItem m_root; 45 private double m_divisor; 46 47 53 public FisheyeTreeFilter(String group) { 54 this(group, 1); 55 } 56 57 65 public FisheyeTreeFilter(String group, int distance) { 66 this(group, Visualization.FOCUS_ITEMS, distance); 67 } 68 69 79 public FisheyeTreeFilter(String group, String sources, int distance) 80 { 81 super(group); 82 m_sources = sources; 83 m_threshold = -distance; 84 m_groupP = new InGroupPredicate( 85 PrefuseLib.getGroupName(group, Graph.NODES)); 86 } 87 88 94 public int getDistance() { 95 return -m_threshold; 96 } 97 98 104 public void setDistance(int distance) { 105 m_threshold = -distance; 106 } 107 108 114 public String getSources() { 115 return m_sources; 116 } 117 118 124 public void setSources(String sources) { 125 m_sources = sources; 126 } 127 128 131 public void run(double frac) { 132 Tree tree = ((Graph)m_vis.getGroup(m_group)).getSpanningTree(); 133 m_divisor = tree.getNodeCount(); 134 m_root = (NodeItem)tree.getRoot(); 135 136 Iterator items = m_vis.visibleItems(m_group); 138 while ( items.hasNext() ) { 139 VisualItem item = (VisualItem)items.next(); 140 item.setDOI(Constants.MINIMUM_DOI); 141 item.setExpanded(false); 142 } 143 144 Iterator iter = m_vis.items(m_sources, m_groupP); 146 while ( iter.hasNext() ) 147 visitFocus((NodeItem)iter.next(), null); 148 visitFocus(m_root, null); 149 150 items = m_vis.visibleItems(m_group); 152 while ( items.hasNext() ) { 153 VisualItem item = (VisualItem)items.next(); 154 if ( item.getDOI() == Constants.MINIMUM_DOI ) 155 PrefuseLib.updateVisible(item, false); 156 } 157 } 158 159 162 private void visitFocus(NodeItem n, NodeItem c) { 163 if ( n.getDOI() <= -1 ) { 164 visit(n, c, 0, 0); 165 if ( m_threshold < 0 ) 166 visitDescendants(n, c); 167 visitAncestors(n); 168 } 169 } 170 171 174 private void visit(NodeItem n, NodeItem c, int doi, int ldist) { 175 PrefuseLib.updateVisible(n, true); 176 double localDOI = -ldist / Math.min(1000.0, m_divisor); 177 n.setDOI(doi+localDOI); 178 179 if ( c != null ) { 180 EdgeItem e = (EdgeItem)c.getParentEdge(); 181 e.setDOI(c.getDOI()); 182 PrefuseLib.updateVisible(e, true); 183 } 184 } 185 186 189 private void visitAncestors(NodeItem n) { 190 if ( n == m_root ) return; 191 visitFocus((NodeItem)n.getParent(), n); 192 } 193 194 197 private void visitDescendants(NodeItem p, NodeItem skip) { 198 int lidx = ( skip == null ? 0 : p.getChildIndex(skip) ); 199 200 Iterator children = p.children(); 201 202 p.setExpanded(children.hasNext()); 203 204 for ( int i=0; children.hasNext(); ++i ) { 205 NodeItem c = (NodeItem)children.next(); 206 if ( c == skip ) { continue; } 207 208 int doi = (int)(p.getDOI()-1); 209 visit(c, c, doi, Math.abs(lidx-i)); 210 if ( doi > m_threshold ) 211 visitDescendants(c, null); 212 } 213 } 214 215 } | Popular Tags |