import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
+import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
+import org.jcolorbrewer.ColorBrewer;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/** DOCUMENT ME!! */
public static final String PLACEHOLDER = " * ";
- private static final int DASHED_LINE_Y_OFFSET = 5;
+ private static final int DASHED_LINE_Y_OFFSET = 6;
TreeModel tree;
boolean fitToWindow = true;
boolean showDistances = false;
-
- boolean showSecondaryStructureProvider = false;
+
+ boolean showStructureProviderLabels = false;
+
+ boolean showStructureProviderColouredLines = false;
boolean showBootstrap = false;
return;
}
+ Vector<BinaryNode> leaves = tree.findLeaves(node);
+ gatherLabelsTo(node, leaves);
+
if ((node.left() == null) && (node.right() == null))
{
+ Color originalColor, translucentColor = Color.WHITE;
// Drawing leaf node
double height = node.height;
double dist = node.dist;
}
else
{
- g.setColor(av.getSequenceColour(seq).darker());
+ originalColor = av.getSequenceColour(seq);
+ translucentColor = new Color(originalColor.getRed(), originalColor.getGreen(), originalColor.getBlue(), 128); // 128 for 50% transparency
+ g.setColor(Color.black);
}
}
else
g.setColor(Color.black);
}
- // Draw horizontal line
+ // horizontal line
g.drawLine(xstart, ypos, xend, ypos);
String nodeLabel = "";
nodeLabel = nodeLabel + String.valueOf(node.bootstrap);
}
+ if(node.hasLabel() && showStructureProviderColouredLines) {
- if (!nodeLabel.equals(""))
+ drawLinesAndLabelsForSecondaryStructureProvider(g, node, xstart, xend, ypos, nodeLabel);
+
+ Rectangle labelBounds = new Rectangle(xstart, ypos, xend, ypos + DASHED_LINE_Y_OFFSET);
+
+ // Add the bounding box to the map for this node
+ labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds);
+
+ }
+ else if (!nodeLabel.equals(""))
{
g.drawString(nodeLabel, xstart + 2, ypos - 2);
}
charWidth, charHeight);
nameHash.put(node, rect);
-
+
+ g.setColor(translucentColor);
+ g.fillRect(xend + 10, ypos - charHeight / 2, charWidth, charHeight);
+ //g.fillRect(xstart - 2, ypos - 10, (xend + 20 + charWidth) - xstart, 20);
+
+ g.setColor(Color.black);
+
// Colour selected leaves differently
boolean isSelected = false;
if (tp.isColumnWise())
int xend = (int) (height * wscale) + offx;
int ypos = (int) (node.ycount * chunk) + offy;
- g.setColor(node.color.darker());
+ //g.setColor(node.color.darker());
+
+ g.setColor(Color.black);
+
// Draw horizontal line
g.drawLine(xstart, ypos, xend, ypos);
if (node == highlightNode)
}
- boolean showColouredLinesForSSProviders = true;
-
- //Display secondary structure providers as labels only if:
+ //Display secondary structure providers only if:
// ~ node has Label assigned (Secondary structure providers)
- // ~ node count is greater than 3
- // ~ showSecondaryStructureProvider option is set to true by the user
- if ( node.hasLabel() && showSecondaryStructureProvider && showColouredLinesForSSProviders)
- {
-
- drawLinesAndLabelsForSecondaryStructureProvider(g, node, xstart, xend, ypos, nodeLabel);
-
- int labelWidth = 20;
- int labelHeight = fm.getHeight();
-
- // Calculate the bounding box of the string
- int xLabelPos = xstart + 2;
- int yLabelPos = ypos - 2;
- Rectangle labelBounds = new Rectangle(xLabelPos, yLabelPos - labelHeight, labelWidth, labelHeight);
-
- // Add the bounding box to the map for this node (list allows multiple bounding boxes)
- labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds);
-
- }
- else if ( node.hasLabel() && showSecondaryStructureProvider && node.count > 3)
- {
-
- String label = node.getLabel();
+ // ~ either label or coloured lines option is selected by the user
+ boolean labelHandled = false;
+ if(node.hasLabel()) {
- if(label.length() > labelLengthThreshold) {
+ if (showStructureProviderColouredLines)
+ {
+ drawLinesAndLabelsForSecondaryStructureProvider(g, node, xstart, xend, ypos, nodeLabel);
+
+ Rectangle labelBounds = new Rectangle(xstart, ypos, xend, ypos + DASHED_LINE_Y_OFFSET);
+
+ // Add the bounding box to the map for this node (list allows multiple bounding boxes)
+ labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds);
+ labelHandled = true;
- //label = AlignmentUtils.reduceLabelLength(label);
}
- nodeLabel = label + " | " + nodeLabel;
-
- // Split the nodeLabel by "|"
- String[] lines = nodeLabel.split("\\|");
-
- // Iterate over the lines and draw each string separately
- String longestLabelString = "";
- int i = 0;
- for (i = 0; i < lines.length; i++) {
- g.drawString(lines[i].trim(), xstart + 2, ypos - 2 - (i * fm.getHeight()));
- if(longestLabelString.length() < lines[i].trim().length()) {
- longestLabelString = lines[i].trim();
- }
+ if (showStructureProviderLabels && node.count > 3)
+ {
+
+ String label = node.getLabel();
+
+ if(label.length() > labelLengthThreshold) {
+
+ //label = AlignmentUtils.reduceLabelLength(label);
+ }
+
+ nodeLabel = label + " | " + nodeLabel;
+
+ // Split the nodeLabel by "|"
+ String[] lines = nodeLabel.split("\\|");
+
+ // Draw each string separately
+ String longestLabelString = "";
+ int i = 0;
+ for (i = 0; i < lines.length; i++) {
+ g.drawString(lines[i].trim(), xstart + 2, ypos - 2 - (i * fm.getHeight()));
+ if(longestLabelString.length() < lines[i].trim().length()) {
+ longestLabelString = lines[i].trim();
+ }
+ }
+
+ int labelWidth = fm.stringWidth(longestLabelString);
+ int labelHeight = fm.getHeight() * (i-1);
+
+ // Bounding box of the string
+ int xLabelPos = xstart + 2;
+ int yLabelPos = ypos - 2;
+ Rectangle labelBounds = new Rectangle(xLabelPos, yLabelPos - labelHeight, labelWidth, labelHeight);
+
+ // Add the bounding box to the map for the node
+ labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds);
+
+ labelHandled = true;
}
-
- int labelWidth = fm.stringWidth(longestLabelString);
- int labelHeight = fm.getHeight() * (i-1);
-
- // Calculate the bounding box of the string
- int xLabelPos = xstart + 2;
- int yLabelPos = ypos - 2;
- Rectangle labelBounds = new Rectangle(xLabelPos, yLabelPos - labelHeight, labelWidth, labelHeight);
-
- // Add the bounding box to the map for this node (list allows multiple bounding boxes)
- labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds);
}
- else if (!nodeLabel.equals(""))
+
+ if (!nodeLabel.equals("") && !labelHandled)
{
g.drawString(nodeLabel, xstart + 2, ypos - 2);
}
private void drawLinesAndLabelsForSecondaryStructureProvider(Graphics g, BinaryNode node,
int xstart, int xend, int ypos, String nodeLabel) {
- // Cast the Graphics object to Graphics2D
+
Graphics2D g2d = (Graphics2D) g.create();
// Set dash pattern
- float[] dashPattern = {2, 3};
+// float[] dashPattern = {2, 2};
+// g2d.setStroke(new BasicStroke(
+// 2.5f,
+// BasicStroke.CAP_BUTT,
+// BasicStroke.JOIN_ROUND,
+// 0.0f,
+// dashPattern,
+// 0.0f));
+
g2d.setStroke(new BasicStroke(
- 1.5f,
- BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_ROUND,
- 0.0f,
- dashPattern,
- 0.0f));
+ 4.0f,
+ BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_ROUND
+ ));
String label = node.getLabel();
String[] lines = label.split("\\|");
int secondHalfLinesCount = lines.length - mid;
drawSecondaryStructureProviderLinesSection(g2d,
lines, mid, lines.length, xstart, xend,
- ypos + DASHED_LINE_Y_OFFSET,
+ ypos,
false);
drawVerticalLineAndLabel(g, xstart, ypos, secondHalfLinesCount, false, nodeLabel);
}
private void drawSecondaryStructureProviderLinesSection(Graphics2D g2d, String[] lines, int start, int end, int xstart, int xend, int baseY, boolean above) {
- for (int i = start; i < end; i++) {
+
+ for (int i = start, j=0; i < end; i++, j++) {
int adjustedY = above
? baseY - ((i - start) * DASHED_LINE_Y_OFFSET)
: baseY +((i - start) * DASHED_LINE_Y_OFFSET);
- Color providerColor = AlignmentUtils.getSecondaryStructureProviderColor(lines[i]);
+ //Color providerColor = AlignmentUtils.getSecondaryStructureProviderColor(lines[i]);
+
+ Map<String, Color> secondaryStructureProviderColorMap = tp.getSecondaryStructureProviderColorMap();
+ Color providerColor = secondaryStructureProviderColorMap.getOrDefault(lines[i].toUpperCase().trim(), Color.BLACK);
g2d.setColor(providerColor);
- g2d.drawLine(xstart, adjustedY, xend, adjustedY);
+ if(i==start && !above) {
+ g2d.drawLine(xstart, adjustedY, xend-3, adjustedY);
+ }
+ else
+ {
+ g2d.drawLine(xstart, adjustedY, xend, adjustedY);
+ }
}
}
private void drawVerticalLineAndLabel(Graphics g, int xstart, int ypos,
- int linesCount, boolean above, String nodeLabel) {
- int adjustedY = above
- ? ypos - (linesCount) * DASHED_LINE_Y_OFFSET
- : ypos + (linesCount) * DASHED_LINE_Y_OFFSET;
+ int linesCount, boolean above, String nodeLabel) {
+
+ int adjustment = (linesCount * DASHED_LINE_Y_OFFSET) + (DASHED_LINE_Y_OFFSET / 3);
+ int adjustedY = ypos + (above ? -adjustment : adjustment - DASHED_LINE_Y_OFFSET);
- // Draw vertical line
+ // draw vertical line
g.drawLine(xstart, ypos, xstart, adjustedY);
- // Draw label
+ // draw label
if(above && !nodeLabel.equals(""))
g.drawString(nodeLabel, xstart + 2, adjustedY - 2);
}
setColor(groups.get(i), col.brighter());
Vector<BinaryNode> l = tree.findLeaves(groups.get(i));
- gatherLabelsTo(groups.get(i), l);
+ //gatherLabelsTo(groups.get(i), l);
if (!tp.isColumnWise())
{
createSeqGroupFor(aps, l, col, groups.get(i).getLabel());
repaint();
}
- /**
- * DOCUMENT ME!
- *
- * @param state
- * DOCUMENT ME!
- */
- public void setShowSecondaryStructureProvider(boolean state)
+ public void hideStructureProviders(boolean state)
+ {
+ if(state) {
+ this.showStructureProviderColouredLines = false;
+ this.showStructureProviderLabels = false;
+ repaint();
+ }
+ }
+
+ public void setShowStructureProviderColouredLines(boolean state)
{
- this.showSecondaryStructureProvider = state;
+ this.showStructureProviderColouredLines = state;
+ if(state) {
+ this.showStructureProviderLabels = false;
+ }
+ repaint();
+ }
+
+ public void setShowStructureProviderLabels(boolean state)
+ {
+ this.showStructureProviderLabels = state;
+ if(state) {
+ this.showStructureProviderColouredLines = false;
+ }
repaint();
}
package jalview.gui;
import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
+import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import org.jibble.epsgraphics.EpsGraphics2D;
import jalview.analysis.AlignmentSorter;
+import jalview.analysis.AlignmentUtils;
import jalview.analysis.AverageDistanceTree;
import jalview.analysis.NJTree;
import jalview.analysis.TreeBuilder;
// New JLabel for subtitle
private JLabel subtitleLabel;
+
+ private Map<String, Color> secondaryStructureProviderColorMap;
/**
* Creates a new TreePanel object.
// @Mungo - Why don't we return our own viewport ???
return getTreeCanvas().getViewport();
}
+
+
+ public Map<String, Color> getSecondaryStructureProviderColorMap()
+ {
+ return secondaryStructureProviderColorMap;
+ }
private void addSubtitlePanel(String subTitle)
{
TreeBuilder njtree = treeType.equals(TreeBuilder.NEIGHBOUR_JOINING)
? new NJTree(av, sm, similarityParams)
: new AverageDistanceTree(av, sm, similarityParams);
+ List<String> labels = njtree.getLabels();
+ if(labels != null && labels.size()>0) {
+ secondaryStructureProviderColorMap = new HashMap<String, Color>();
+ AlignmentUtils.assignSecondaryStructureProviderColor(secondaryStructureProviderColorMap, labels);
+ }
tree = new TreeModel(njtree);
// don't display distances for columnwise trees
}
treeCanvas.setShowDistances(distanceMenu.isSelected());
}
- /**
- * DOCUMENT ME!
- *
- * @param e
- * DOCUMENT ME!
- */
@Override
- public void showSecondaryStructureProviderMenu_actionPerformed(ActionEvent e)
+ public void hideStructureProviders_actionPerformed(ActionEvent e)
+ {
+ treeCanvas.hideStructureProviders(hideStructureProviders.isSelected());
+ }
+
+ @Override
+ public void showStructureProviderColouredLines_actionPerformed(ActionEvent e)
+ {
+ treeCanvas.setShowStructureProviderColouredLines(showStructureProviderColouredLines.isSelected());
+ }
+
+ @Override
+ public void showStructureProviderLabels_actionPerformed(ActionEvent e)
{
- treeCanvas.setShowSecondaryStructureProvider(showSecondaryStructureProviderMenu.isSelected());
+ treeCanvas.setShowStructureProviderLabels(showStructureProviderLabels.isSelected());
}
/**
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
//Menu option for the user to select their preference in
//displaying secondary structure providers as labels.
//Visible only for secondary structure similarity.
- public JCheckBoxMenuItem showSecondaryStructureProviderMenu = new JCheckBoxMenuItem();
+
+ public JMenu showSecondaryStructureProviderMenu = new JMenu();
+
+ ButtonGroup showSecondaryStructureProviderButtonGroup = new ButtonGroup();
+
+ public JRadioButtonMenuItem hideStructureProviders = new JRadioButtonMenuItem();
+
+ public JRadioButtonMenuItem showStructureProviderLabels = new JRadioButtonMenuItem();
+
+ public JRadioButtonMenuItem showStructureProviderColouredLines = new JRadioButtonMenuItem();
public JCheckBoxMenuItem fitToWindow = new JCheckBoxMenuItem();
distanceMenu_actionPerformed(e);
}
});
+
+ showSecondaryStructureProviderButtonGroup.add(hideStructureProviders);
+ showSecondaryStructureProviderButtonGroup.add(showStructureProviderLabels);
+ showSecondaryStructureProviderButtonGroup.add(showStructureProviderColouredLines);
showSecondaryStructureProviderMenu.setText(MessageManager.getString("label.show_secondary_structure_provider"));
- showSecondaryStructureProviderMenu.addActionListener(new java.awt.event.ActionListener()
+ hideStructureProviders.setText(MessageManager.getString("label.hide_structure_provider"));
+ hideStructureProviders.setSelected(true);
+ hideStructureProviders.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- showSecondaryStructureProviderMenu_actionPerformed(e);
+ hideStructureProviders_actionPerformed(e);
}
});
+
+ showStructureProviderLabels.setText(MessageManager.getString("label.show_structure_provider_as_labels"));
+ showStructureProviderLabels.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showStructureProviderLabels_actionPerformed(e);
+ }
+ });
+
+ showStructureProviderColouredLines.setText(MessageManager.getString("label.show_structure_provider_as_coloured_lines"));
+ showStructureProviderColouredLines.addActionListener(new java.awt.event.ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ showStructureProviderColouredLines_actionPerformed(e);
+ }
+
+ });
+
fitToWindow.setSelected(true);
fitToWindow.setText(MessageManager.getString("label.fit_to_window"));
fitToWindow.addActionListener(new java.awt.event.ActionListener()
viewMenu.add(fitToWindow);
viewMenu.add(font);
viewMenu.add(distanceMenu);
- viewMenu.add(showSecondaryStructureProviderMenu);
+ viewMenu.add(showSecondaryStructureProviderMenu);
viewMenu.add(bootstrapMenu);
viewMenu.add(placeholdersMenu);
viewMenu.add(sortAssocViews);
saveAsMenu.add(saveAsNewick);
saveAsMenu.add(epsTree);
saveAsMenu.add(pngTree);
+ showSecondaryStructureProviderMenu.add(hideStructureProviders);
+ showSecondaryStructureProviderMenu.add(showStructureProviderLabels);
+ showSecondaryStructureProviderMenu.add(showStructureProviderColouredLines);
+
}
public void printMenu_actionPerformed(ActionEvent e)
public void showSecondaryStructureProviderMenu_actionPerformed(ActionEvent e)
{
}
+
+ public void hideStructureProviders_actionPerformed(ActionEvent e)
+ {
+ }
+
+ public void showStructureProviderColouredLines_actionPerformed(ActionEvent e)
+ {
+ }
+
+ public void showStructureProviderLabels_actionPerformed(ActionEvent e)
+ {
+ }
public void bootstrapMenu_actionPerformed(ActionEvent e)
{