/** * Computes relative measures of the angular widths of each * expanded subtree. Node diameters are taken into account * to improve space allocation for variable-sized nodes. * * This method also updates the base angle value for nodes * to ensure proper ordering of nodes. */ private double calcAngularWidth(NodeItem n, int d) { if ( d > m_maxDepth ) m_maxDepth = d; double aw = 0; Rectangle2D bounds = n.getBounds(); double w = bounds.getWidth(), h = bounds.getHeight(); double diameter = d==0 ? 0 : Math.sqrt(w*w+h*h) / d; if ( n.isExpanded() && n.getChildCount() > 0 ) { Iterator childIter = n.children(); while ( childIter.hasNext() ) { NodeItem c = (NodeItem)childIter.next(); aw += calcAngularWidth(c,d+1); } aw = Math.max(diameter, aw); } else { aw = diameter; } ((Params)n.get(PARAMS)).width = aw; return aw; }
private void arrangeChildVertically( NodeItem parent ) { double maxW = 0; for( int i = 0; i < parent.getChildCount(); i++ ) { NodeItem node = (NodeItem) parent.getChild( i ); Rectangle2D bounds = node.getBounds(); maxW = Math.max( maxW, bounds.getWidth() ); } for( int i = 0; i < parent.getChildCount(); i++ ) { NodeItem node = (NodeItem) parent.getChild( i ); Rectangle2D bounds = node.getBounds(); node.setBounds( bounds.getX(), bounds.getY(), maxW, bounds.getHeight() ); } }
private void highlightNodeAndNeighbors(NodeItem node, boolean state) { if (node == null) { return; } setNeighborHighlight(node, state); node.setHighlighted(state); }
private Point2D getPoint(NodeItem n, boolean start) { NodeItem p = (NodeItem)n.getParent(); if ( start ) for (; p!=null && !p.isStartVisible(); p=(NodeItem)p.getParent()); else for (; p!=null && !p.isEndVisible(); p=(NodeItem)p.getParent()); if ( p == null ) { m_point.setLocation(n.getX(), n.getY()); return m_point; double x = start ? p.getStartX() : p.getEndX(); double y = start ? p.getStartY() : p.getEndY(); Rectangle2D b = p.getBounds(); switch ( m_orientation ) { case Constants.ORIENT_LEFT_RIGHT:
private void layout( NodeItem node, double x, double y ) node.setBounds( x, y, minSize.width, minSize.height ); int depth = node.getDepth(); node.setBounds( x, y, 0, 0 ); node.setVisible( false ); node.setVisible( true ); double cy = y + minSize.height; Area area = new Area( node.getBounds() ); for( int i = 0; i < node.getChildCount(); i++ ) NodeItem child = (NodeItem) node.getChild( i ); area.add( new Area( child.getBounds() ) ); Rectangle2D nodeRect = child.getBounds(); if( depth == 0 ) node.setBounds( x, y, bounds.getWidth(), bounds.getHeight() );
private Iterator sortedChildren(final NodeItem n) { double base = 0; NodeItem p = (NodeItem)n.getParent(); if ( p != null ) { base = normalize(Math.atan2(p.getY()-n.getY(), p.getX()-n.getX())); int cc = n.getChildCount(); if ( cc == 0 ) return null; NodeItem c = (NodeItem)n.getFirstChild(); if ( !c.isStartVisible() ) { return n.children(); for ( int i=0; i<cc; ++i, c=(NodeItem)c.getNextSibling() ) { idx[i] = i; angle[i] = normalize(-base + Math.atan2(c.getY()-n.getY(), c.getX()-n.getX()));
while ( iter.hasNext() ) { NodeItem n = (NodeItem)iter.next(); n.setDouble(AREA, 0); NodeItem n = (NodeItem)iter.next(); double area = 0; if ( n.getChildCount() == 0 ) { area = n.getSize(); ++leafCount; } else if ( n.isExpanded() ) { NodeItem c = (NodeItem)n.getFirstChild(); for (; c!=null; c = (NodeItem)c.getNextSibling()) { area += c.getDouble(AREA); ++leafCount; n.setDouble(AREA, area); double scale = area/root.getDouble(AREA); iter = new TreeNodeIterator(root); while ( iter.hasNext() ) { NodeItem n = (NodeItem)iter.next(); n.setDouble(AREA, n.getDouble(AREA)*scale);
if ( m_prevRoot == null || !m_prevRoot.isValid() || r == m_prevRoot ) NodeItem pp = (NodeItem)p.getParent(); if ( pp == r ) { break; dt += ((Params)n.get(PARAMS)).width; double rw = ((Params)r.get(PARAMS)).width; double pw = ((Params)p.get(PARAMS)).width; dt = -MathLib.TWO_PI * (dt+pw/2)/rw; m_theta1 = dt + Math.atan2(p.getY()-r.getY(), p.getX()-r.getX()); m_theta2 = m_theta1 + MathLib.TWO_PI; m_prevRoot = r;
updateDepths(depth, n); boolean expanded = n.isExpanded(); if ( n.getChildCount() == 0 || !expanded ) // is leaf NodeItem l = (NodeItem)n.getPreviousSibling(); if ( l == null ) { np.prelim = 0; NodeItem leftMost = (NodeItem)n.getFirstChild(); NodeItem rightMost = (NodeItem)n.getLastChild(); NodeItem defaultAncestor = leftMost; NodeItem c = leftMost; for ( int i=0; c != null; ++i, c = (NodeItem)c.getNextSibling() ) (getParams(leftMost).prelim + getParams(rightMost).prelim); NodeItem left = (NodeItem)n.getPreviousSibling(); if ( left != null ) { np.prelim = getParams(left).prelim + spacing(left, n, true);
/** * Compute the layout. * @param n the root of the current subtree under consideration * @param r the radius, current distance from the center * @param theta1 the start (in radians) of this subtree's angular region * @param theta2 the end (in radians) of this subtree's angular region */ protected void layout(NodeItem n, double r, double theta1, double theta2) { double dtheta = (theta2-theta1); double dtheta2 = dtheta / 2.0; double width = ((Params)n.get(PARAMS)).width; double cfrac, nfrac = 0.0; Iterator childIter = sortedChildren(n); while ( childIter != null && childIter.hasNext() ) { NodeItem c = (NodeItem)childIter.next(); Params cp = (Params)c.get(PARAMS); cfrac = cp.width / width; if ( c.isExpanded() && c.getChildCount()>0 ) { layout(c, r+m_radiusInc, theta1 + nfrac*dtheta, theta1 + (nfrac+cfrac)*dtheta); } setPolarLocation(c, n, r, theta1 + nfrac*dtheta + cfrac*dtheta2); cp.angle = cfrac*dtheta; nfrac += cfrac; } }
return; Visualization vis = fileNode.getVisualization(); boolean isExpanded = fileNode.getBoolean(AnalysisConstants.IS_EXPANDED); fileNode.setBoolean(AnalysisConstants.IS_EXPANDED, !isExpanded); fileNode.getInt(AnalysisConstants.FILE_NODE_FILE_GROUP)); vis.setVisible(AnalysisConstants.GRAPH_GROUP, p, !isExpanded); Iterator outEdges = fileNode.outEdges(); while(outEdges.hasNext()){ EdgeItem edge = EdgeItem.class.cast(outEdges.next());
private void updateArea(NodeItem n, Rectangle2D r) { Rectangle2D b = n.getBounds(); if ( m_frame == 0.0 ) { double A = n.getDouble(AREA) - dA; Iterator childIter = n.children(); while ( childIter.hasNext() ) s += ((NodeItem)childIter.next()).getDouble(AREA); double t = A/s; childIter = n.children(); while ( childIter.hasNext() ) { NodeItem c = (NodeItem)childIter.next(); c.setDouble(AREA, c.getDouble(AREA)*t);
/** * Set the highlighted state of the neighbors of a node. * @param n the node under consideration * @param state the highlighting state to apply to neighbors */ protected void setNeighborHighlight(NodeItem n, boolean state) { Iterator iter = n.edges(); while ( iter.hasNext() ) { EdgeItem eItem = (EdgeItem)iter.next(); NodeItem nItem = eItem.getAdjacentItem(n); if (eItem.isVisible() || highlightWithInvisibleEdge) { eItem.setHighlighted(state); nItem.setHighlighted(state); } } if ( activity != null ) n.getVisualization().run(activity); }
/** * the graph nodes can represent XAM Components or * FileObjects * */ private Object getGraphNodeUserObject(NodeItem item ){ if (item == null){ return null; } FileObject fo = (FileObject) item.get(AnalysisConstants.FILE_OBJECT); if (fo != null) { return fo; } return item.get(AnalysisConstants.USER_OBJECT); } }
/** * Compute the tree map layout. */ private void layout(NodeItem p, Rectangle2D r) { // create sorted list of children Iterator childIter = p.children(); while ( childIter.hasNext() ) m_kids.add(childIter.next()); Collections.sort(m_kids, s_cmp); // do squarified layout of siblings double w = Math.min(r.getWidth(),r.getHeight()); squarify(m_kids, m_row, w, r); m_kids.clear(); // clear m_kids // recurse childIter = p.children(); while ( childIter.hasNext() ) { NodeItem c = (NodeItem)childIter.next(); if ( c.getChildCount() > 0 && c.getDouble(AREA) > 0 ) { updateArea(c,r); layout(c, r); } } }
private double spacing(NodeItem l, NodeItem r, boolean siblings) { boolean w = ( m_orientation == Constants.ORIENT_TOP_BOTTOM || m_orientation == Constants.ORIENT_BOTTOM_TOP ); return (siblings ? m_bspace : m_tspace) + 0.5 * ( w ? l.getBounds().getWidth() + r.getBounds().getWidth() : l.getBounds().getHeight() + r.getBounds().getHeight() ); }
public void calcRepulsion(Graph g, NodeItem n1) { Params np = getParams(n1); np.disp[0] = 0.0; np.disp[1] = 0.0; for (Iterator iter2 = g.nodes(); iter2.hasNext();) { NodeItem n2 = (NodeItem) iter2.next(); Params n2p = getParams(n2); if (n2.isFixed()) continue; if (n1 != n2) { double xDelta = np.loc[0] - n2p.loc[0]; double yDelta = np.loc[1] - n2p.loc[1]; double deltaLength = Math.max(EPSILON, Math.sqrt(xDelta*xDelta + yDelta*yDelta)); double force = (forceConstant*forceConstant) / deltaLength; if (Double.isNaN(force)) { System.err.println("Mathematical error..."); } np.disp[0] += (xDelta/deltaLength)*force; np.disp[1] += (yDelta/deltaLength)*force; } } }