package org.phylowidget.render; import java.util.Collections; import java.util.List; import org.phylowidget.PhyloWidget; import org.phylowidget.tree.PhyloNode; import org.phylowidget.tree.RootedTree; import processing.core.PGraphics; public class LayoutDiagonal extends LayoutBase { int numLeaves; public void layoutImpl() { numLeaves = leaves.length; double index = 0; for (PhyloNode leaf : leaves) { // index+= getLayoutMult(leaf)/2; leafPosition(leaf,index); // index+= getLayoutMult(leaf)/2; index++; } branchPosition((PhyloNode)tree.getRoot()); } @Override public void drawLine(PGraphics canvas, PhyloNode p, PhyloNode c) { canvas.line(c.getX(), c.getY(), p.getX(),p.getY()); } protected float branchPosition(PhyloNode n) { setAngle(n,0); if (tree.isLeaf(n)) // If N is a leaf, then it's already been laid out. return 0; /* * Do the children first. */ List<PhyloNode> children = tree.getChildrenOf(n); for (int i=0; i < children.size(); i++) { PhyloNode child = children.get(i); // if (!tree.shouldKeep(child)) // { // children.remove(i); // i--; // } } for (int i = 0; i < children.size(); i++) { PhyloNode child = (PhyloNode) children.get(i); branchPosition(child); } Collections.sort(children); /* * Now, let's put on our thinking caps and try to lay ourselves out * correctly. */ PhyloNode loChild = (PhyloNode) Collections.min(children); PhyloNode hiChild = (PhyloNode) Collections.max(children); /* * Find the max depth of each child, and project where the "lower" child * would be in the y axis if it were at that higher depth. */ float stepSize = 1f / (numLeaves); float loLeaves = tree.getNumEnclosedLeaves(loChild); float hiLeaves = tree.getNumEnclosedLeaves(hiChild); // float loLeaves = getRealEnclosedLeaves(loChild); // float hiLeaves = getRealEnclosedLeaves(hiChild); float mLeaves = Math.max(loLeaves, hiLeaves); // System.out.println("md:" + mLeaves); float loChildNewY = loChild.getTargetY() + (mLeaves - loLeaves) * stepSize / 2; float hiChildNewY = hiChild.getTargetY() - (mLeaves - hiLeaves) * stepSize / 2; float unscaledY = (loChildNewY + hiChildNewY) / 2; float unscaledX = calcXPosition(n); setPosition(n,unscaledX, unscaledY); return 0; } protected int getRealEnclosedLeaves(PhyloNode n) { int numEnclosed = tree.getNumEnclosedLeaves(n); int orig = numEnclosed; List<PhyloNode> children = tree.getChildrenOf(n); // for (PhyloNode child : children) // { //// if (!tree.shouldKeep(child)) //// numEnclosed -= tree.getNumEnclosedLeaves(child); // } // System.out.println(n.getLabel()+" "+numEnclosed); return numEnclosed; } private void leafPosition(PhyloNode n, double index) { /** * Set the leaf position. */ float yPos = ((float) (index + .5f) / (float) (numLeaves)); float xPos = 1; // if (PhyloWidget.cfg.useBranchLengths) xPos = calcXPosition(n); setPosition(n,xPos, yPos); } protected float calcXPosition(PhyloNode n) { // System.out.println(n.getLabel()+" "+getRealEnclosedLeaves(n)); float a = xPosForNumEnclosedLeaves(getRealEnclosedLeaves(n)); // float b = (float) (tree.getBranchLength(n) / tree // .getMaxHeightToLeaf(tree.getRoot())); return a / 2; } float xPosForNumEnclosedLeaves(int numLeaves) { float asdf = 1 - (float) (numLeaves - 1) / (float) (leaves.length); return asdf; } }