/** * Lays out the ribbons in a bundled style. Basically, this means doing a series of phased * depth-first traversals on each of the top-level category nodes. * * @param minX The left bound of the display space. * @param maxX The right bound of the display space. */ public void doLayoutBundled(int minX, int maxX, BarState currentState) { root.setWidth(maxX - minX); // Set all the layout and completeness flags to false. resetForBundling(root); // If there are no connections, return. if (!root.getChildren().isEmpty()) { // While the root is not set to complete... while (!root.isComplete()) { // Iterate through each of the invisible nodes, each of // which represents a top-level category bar. At each // step, lay out the leftmost incomplete branch of the // top-level node. for (VisualConnection invisible : root.getChildren()) { if (!invisible.isComplete()) layoutBranch(invisible, currentState, (maxX - minX)); // If this node is complete and is the last of the root's // children, then we're done. else if (invisible == root.getChildren().get(root.getChildren().size() - 1)) root.setComplete(true); } } } setColors(root); }
/** * Lay out the leftmost incomplete branch of this connection node. * * @param connectionNode */ public boolean layoutBranch( VisualConnection connectionNode, BarState currentState, int totalWidth) { // If this node isn't laid out already, lay it out. if (!connectionNode.isLaidOut()) { connectionNode.layout(connectionNode.getParent().getWidth()); connectionNode.setLaidOut(true); // If this is a leaf, this node is completed. if (connectionNode.getChildren().isEmpty()) { connectionNode.setComplete(true); return true; } } // If this is not a leaf, call layoutBranch on this node's // leftmost incomplete child. for (VisualConnection child : connectionNode.getChildren()) if (!child.isComplete()) if (layoutBranch(child, currentState, totalWidth) == false) return false; // If all of the children are complete, this node is // completed. connectionNode.setComplete(true); return true; }