package viz; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Stroke; import java.text.DecimalFormat; public class CladeDrawer { DensiTree m_dt; public Font m_font; public Color m_color; public int m_nSignificantDigits = 3; public boolean m_bDrawMean = false; public boolean m_bDrawSupport = true; public boolean m_bDraw95HPD = false; public boolean m_bTextMean = false; public boolean m_bTextSupport = false; public boolean m_bText95HPD = false; public boolean m_bSelectedOnly = false; CladeDrawer(DensiTree dt) { m_dt = dt; m_font = Font.getFont("default"); m_color = Color.black; } /** show all clades **/ void viewClades(Graphics g) { float fScaleX = m_dt.m_fScaleX; float fScaleY = m_dt.m_fScaleY; g.setFont(m_font); g.setColor(m_color); if (m_dt.m_bUseLogScale) { if (m_dt.m_treeDrawer.m_bRootAtTop) { fScaleY *= m_dt.m_fHeight / (float) Math.log(m_dt.m_fHeight + 1.0); } else { fScaleX *= m_dt.m_fHeight / (float) Math.log(m_dt.m_fHeight + 1.0); } } int x = 0; int y = 0; Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); ((Graphics2D) g).setStroke(stroke); ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); int h = m_dt.m_rotate.getHeight(null); int w = m_dt.m_rotate.getWidth(null); boolean bUpdatePoints = false; if (m_dt.m_Panel.m_rotationPoints == null) { m_dt.m_Panel.m_rotationPoints = new RotationPoint[m_dt.m_cladeHeight.size()]; bUpdatePoints = true; } String format = (m_nSignificantDigits > 0 ? "##.": "##"); for (int i = 0; i < m_nSignificantDigits; i++) { format += "#"; } DecimalFormat formatter = new DecimalFormat(format); formatter.setMinimumFractionDigits(m_nSignificantDigits); formatter.setMaximumFractionDigits(m_nSignificantDigits); DecimalFormat supportFormatter = new DecimalFormat(format);//"##.#"); for (int i = 0/* m_dt.m_sLabels.size() */; i < m_dt.m_cladeHeight.size(); i++) { if (m_dt.m_cladeWeight.get(i) > m_dt.m_smallestCladeSupport && ( (m_dt.m_Xmode == 1 && (m_dt.m_clades.get(i).length > 1 || m_dt.m_bLeafCladeSelection)) || (m_dt.m_Xmode == 2 && m_dt.m_clades.get(i).length == 1))) { if (!m_dt.m_treeDrawer.m_bRootAtTop) { x = (int) ((m_dt.m_cladeHeight.get(i) - m_dt.m_fTreeOffset) * fScaleX * m_dt.m_fTreeScale); y = (int) (m_dt.m_cladePosition[i] * fScaleY); if (m_bDrawMean && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawLine(x, y- 3, x, y+6); } if (m_bTextMean && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(formatter.format((m_dt.m_gridDrawer.m_fGridOrigin + m_dt.m_fHeight - m_dt.m_cladeHeight.get(i)) * m_dt.m_fUserScale), x, y - 1); } if (m_bTextSupport && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(supportFormatter.format(100*m_dt.m_cladeWeight.get(i)), x, y + g.getFont().getSize() + 1); } } else { x = (int) (m_dt.m_cladePosition[i] * fScaleX); y = /*nHeight -*/ (int) ((m_dt.m_cladeHeight.get(i) - m_dt.m_fTreeOffset) * fScaleY * m_dt.m_fTreeScale); if (m_bDrawMean && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawLine(x -3, y, x + 3, y); } if (m_bTextMean && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(formatter.format((m_dt.m_gridDrawer.m_fGridOrigin + m_dt.m_fHeight - m_dt.m_cladeHeight.get(i)) * m_dt.m_fUserScale), x, y - 1); } if (m_bTextSupport && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(supportFormatter.format(100*m_dt.m_cladeWeight.get(i)), x, y + g.getFont().getSize() + 1); } } } else { x = -100; y = -100; } w = (int)(10 + m_dt.m_cladeWeight.get(i)*10); h = w; if (m_bDrawSupport && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawOval(x- w / 2, y- h / 2, w, h); } //g.drawImage(m_dt.m_rotate, x - w / 2, y - h / 2, x + h / 2, y + w / 2, 0, 0, h, w, null); if (bUpdatePoints) { m_dt.m_Panel.m_rotationPoints[i] = new RotationPoint(x, y); } if (!m_dt.m_treeDrawer.m_bRootAtTop) { x = (int) ((m_dt.m_cladeHeight95HPDdown.get(i) - m_dt.m_fTreeOffset) * fScaleX * m_dt.m_fTreeScale); //y = (int) (m_dt.m_cladePosition[i] * fScaleY); w = - x + (int) ((m_dt.m_cladeHeight95HPDup.get(i) - m_dt.m_fTreeOffset) * fScaleX * m_dt.m_fTreeScale); h = 3; if (m_bText95HPD && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(formatter.format((m_dt.m_cladeHeight95HPDup.get(i) - m_dt.m_cladeHeight95HPDdown.get(i)) * m_dt.m_fUserScale), x, y- 1); } } else { //x = (int) (m_dt.m_cladePosition[i] * fScaleX); y = (int) ((m_dt.m_cladeHeight95HPDdown.get(i) - m_dt.m_fTreeOffset) * fScaleY * m_dt.m_fTreeScale); w = 3; h = - y + (int) ((m_dt.m_cladeHeight95HPDup.get(i) - m_dt.m_fTreeOffset) * fScaleY * m_dt.m_fTreeScale); if (m_bText95HPD && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawString(formatter.format((m_dt.m_cladeHeight95HPDup.get(i) - m_dt.m_cladeHeight95HPDdown.get(i)) * m_dt.m_fUserScale), x, y- 1); } } if (m_bDraw95HPD && (!m_bSelectedOnly || m_dt.m_cladeSelection.contains(i))) { g.drawRect(x, y, w, h); } } // draw selection if (!m_bSelectedOnly) { stroke = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); ((Graphics2D) g).setStroke(stroke); ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); for (int i : m_dt.m_cladeSelection) { if (!m_dt.m_treeDrawer.m_bRootAtTop) { x = (int) ((m_dt.m_cladeHeight.get(i) - m_dt.m_fTreeOffset) * fScaleX * m_dt.m_fTreeScale); y = (int) (m_dt.m_cladePosition[i] * fScaleY); } else { x = (int) (m_dt.m_cladePosition[i] * fScaleX); y = /*nHeight -*/ (int) ((m_dt.m_cladeHeight.get(i) - m_dt.m_fTreeOffset) * fScaleY * m_dt.m_fTreeScale); } w = (int)(10 + m_dt.m_cladeWeight.get(i)*10); h = w; g.drawOval(x- w / 2, y- h / 2, w, h); } } } }