From a323332f89e44b7a3b8b1aee27ce6e12c22f44ca Mon Sep 17 00:00:00 2001 From: Renia Correya Date: Fri, 11 Oct 2024 15:56:22 +0100 Subject: [PATCH] JAL-4435 Added coloured dashed lines for secondary structure providers. --- src/jalview/analysis/AlignmentUtils.java | 11 +++- src/jalview/gui/TreeCanvas.java | 100 +++++++++++++++++++++++------- src/jalview/util/Constants.java | 12 ++++ 3 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/jalview/analysis/AlignmentUtils.java b/src/jalview/analysis/AlignmentUtils.java index 41e491c..7b632d8 100644 --- a/src/jalview/analysis/AlignmentUtils.java +++ b/src/jalview/analysis/AlignmentUtils.java @@ -3205,7 +3205,7 @@ public class AlignmentUtils } // Method to get the key for a given provider value - public static String getProviderKey(String providerValue) { + public static String getSecondaryStructureProviderKey(String providerValue) { for (Map.Entry entry : Constants.STRUCTURE_PROVIDERS.entrySet()) { if (entry.getValue().equals(providerValue)) { return entry.getKey(); // Return the key (abbreviation) for the matching provider value @@ -3229,4 +3229,13 @@ public class AlignmentUtils return reducedLabel; // Return the reduced label if abbreviations were applied } + + public static Color getSecondaryStructureProviderColor(String label) { + + //return Constants.STRUCTURE_PROVIDERS_COLOR.getOrDefault(label, Color.BLACK); + Color c = Constants.STRUCTURE_PROVIDERS_COLOR.get(label.trim()); + if(c==null) + c = Color.BLACK; + return c; + } } \ No newline at end of file diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java index 49b569a..c42546c 100755 --- a/src/jalview/gui/TreeCanvas.java +++ b/src/jalview/gui/TreeCanvas.java @@ -20,6 +20,7 @@ */ package jalview.gui; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; @@ -85,6 +86,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, { /** DOCUMENT ME!! */ public static final String PLACEHOLDER = " * "; + + private static final int DASHED_LINE_Y_OFFSET = 5; TreeModel tree; @@ -445,32 +448,13 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, nodeLabel = nodeLabel + String.valueOf(node.bootstrap); } + if (node.hasLabel()) { - String label = node.getLabel(); - - if(label.length() > labelLengthThreshold) { - - //label = AlignmentUtils.reduceLabelLength(label); - } - - nodeLabel = label + " | " + nodeLabel; - - // Split the nodeLabel by "|" - String[] lines = nodeLabel.split("\\|"); - - // Iterate over the lines and draw each line 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(); - } - } + drawLinesAndLabelsForSecondaryStructureProvider(g, node, xstart, xend, ypos, nodeLabel); - int labelWidth = fm.stringWidth(longestLabelString); - int labelHeight = fm.getHeight() * (i-1); + int labelWidth = 20; + int labelHeight = fm.getHeight(); // Calculate the bounding box of the string int xLabelPos = xstart + 2; @@ -478,7 +462,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, 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); + labelBoundsMap.computeIfAbsent(node, k -> new ArrayList<>()).add(labelBounds); + } else if (!nodeLabel.equals("")) @@ -487,6 +472,73 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable, } } } + + + 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}; + g2d.setStroke(new BasicStroke( + 1.5f, + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_ROUND, + 0.0f, + dashPattern, + 0.0f)); + + String label = node.getLabel(); + String[] lines = label.split("\\|"); + + int mid = lines.length / 2; + + // Draw lines for the first half + int firstHalfLinesCount = mid; + + drawSecondaryStructureProviderLinesSection(g2d, + lines, 0, mid, xstart, xend, + ypos - DASHED_LINE_Y_OFFSET, + true); + drawVerticalLineAndLabel(g, xstart, ypos, firstHalfLinesCount, true, nodeLabel); + + // Draw lines for the second half + int secondHalfLinesCount = lines.length - mid; + drawSecondaryStructureProviderLinesSection(g2d, + lines, mid, lines.length, xstart, xend, + ypos + DASHED_LINE_Y_OFFSET, + false); + drawVerticalLineAndLabel(g, xstart, ypos, secondHalfLinesCount, false, nodeLabel); + + g2d.dispose(); +} + + 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++) { + int adjustedY = above + ? baseY - ((i - start) * DASHED_LINE_Y_OFFSET) + : baseY +((i - start) * DASHED_LINE_Y_OFFSET); + Color providerColor = AlignmentUtils.getSecondaryStructureProviderColor(lines[i]); + g2d.setColor(providerColor); + 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; + + // Draw vertical line + g.drawLine(xstart, ypos, xstart, adjustedY); + + // Draw label + if(above && !nodeLabel.equals("")) + g.drawString(nodeLabel, xstart + 2, adjustedY - 2); +} + /** * DOCUMENT ME! diff --git a/src/jalview/util/Constants.java b/src/jalview/util/Constants.java index b8afeeb..b24182c 100644 --- a/src/jalview/util/Constants.java +++ b/src/jalview/util/Constants.java @@ -20,6 +20,7 @@ */ package jalview.util; +import java.awt.Color; import java.util.HashMap; import java.util.Map; @@ -71,4 +72,15 @@ public class Constants STRUCTURE_PROVIDERS.put("JP", "JPred"); STRUCTURE_PROVIDERS.put("AFill", "AlphaFill"); } + + public static final Map STRUCTURE_PROVIDERS_COLOR = new HashMap<>(); + + static { + STRUCTURE_PROVIDERS_COLOR.put("No Secondary Structure", Color.GRAY); + STRUCTURE_PROVIDERS_COLOR.put("AlphaFold DB", new Color(255, 0, 0)); + STRUCTURE_PROVIDERS_COLOR.put("SWISS-MODEL", new Color(255, 165, 0)); + STRUCTURE_PROVIDERS_COLOR.put("PDB", new Color(0, 128, 0)); + STRUCTURE_PROVIDERS_COLOR.put("JPred", new Color(0, 0, 255)); + STRUCTURE_PROVIDERS_COLOR.put("AlphaFill", Color.CYAN); + } } -- 1.7.10.2