JAL-3049 JAL-2069 colour icon tooltip including by attribute
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 29 Jun 2018 11:31:50 +0000 (12:31 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 29 Jun 2018 11:31:50 +0000 (12:31 +0100)
src/jalview/api/FeatureColourI.java
src/jalview/gui/FeatureSettings.java
src/jalview/schemes/FeatureColour.java
test/jalview/gui/FeatureSettingsTest.java
test/jalview/schemes/FeatureColourTest.java

index 4dbb1bb..0e45675 100644 (file)
@@ -192,4 +192,12 @@ public interface FeatureColourI
    * @return
    */
   void setAttributeName(String... name);
+
+  /**
+   * Answers a human-readable text description of the colour, suitable for
+   * display as a tooltip, possibly internationalised for the user's locale.
+   * 
+   * @return
+   */
+  String getDescription();
 }
index 01a7310..14e37af 100644 (file)
@@ -1336,32 +1336,25 @@ public class FeatureSettings extends JPanel
   /**
    * Answers a suitable tooltip to show on the colour cell of the table
    * 
-   * @param gcol
+   * @param fcol
    * @return
    */
-  public String getColorTooltip(FeatureColourI gcol)
+  public static String getColorTooltip(FeatureColourI fcol)
   {
-    if (gcol.isSimpleColour())
-    {
-      return BASE_TOOLTIP;
-    }
-    StringBuilder tt = new StringBuilder();
-    if (gcol.isAboveThreshold())
-    {
-      tt.append("Thresholded (Above ").append(gcol.getThreshold())
-              .append(")");
-    }
-    else if (gcol.isBelowThreshold())
+    if (fcol == null)
     {
-      tt.append("Thresholded (Below ").append(gcol.getThreshold())
-              .append(")");
+      return null;
     }
-    else if (gcol.isColourByLabel())
+    if (fcol.isSimpleColour())
     {
-      tt.insert(0, "Coloured by label text ");
+      return BASE_TOOLTIP;
     }
-    tt.append("; ").append(BASE_TOOLTIP);
-    return tt.toString();
+    String description = fcol.getDescription();
+    description = description.replaceAll("<", "&lt;");
+    description = description.replaceAll(">", "&gt;");
+    StringBuilder tt = new StringBuilder(description);
+    tt.append("<br>").append(BASE_TOOLTIP).append("</br>");
+    return JvSwingUtils.wrapTooltip(true, tt.toString());
   }
 
   public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol,
index 7d14662..e683c87 100644 (file)
@@ -25,6 +25,7 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.features.FeatureMatcher;
 import jalview.util.ColorUtils;
 import jalview.util.Format;
+import jalview.util.MessageManager;
 
 import java.awt.Color;
 import java.util.StringTokenizer;
@@ -50,6 +51,12 @@ import java.util.StringTokenizer;
  */
 public class FeatureColour implements FeatureColourI
 {
+  private static final String I18N_LABEL = MessageManager
+          .getString("label.label");
+
+  private static final String I18N_SCORE = MessageManager
+          .getString("label.score");
+
   private static final String ABSOLUTE = "abso";
 
   private static final String ABOVE = "above";
@@ -890,4 +897,50 @@ public class FeatureColour implements FeatureColourI
     attributeName = name;
   }
 
+  @Override
+  public String getDescription()
+  {
+    if (isSimpleColour())
+    {
+      return "r=" + colour.getRed() + ",g=" + colour.getGreen() + ",b="
+              + colour.getBlue();
+    }
+    StringBuilder tt = new StringBuilder();
+    String by = null;
+
+    if (getAttributeName() != null)
+    {
+      by = FeatureMatcher.toAttributeDisplayName(getAttributeName());
+    }
+    else if (isColourByLabel())
+    {
+      by = I18N_LABEL;
+    }
+    else
+    {
+      by = I18N_SCORE;
+    }
+    tt.append(MessageManager.formatMessage("action.by_title_param", by));
+
+    /*
+     * add threshold if any
+     */
+    if (isAboveThreshold() || isBelowThreshold())
+    {
+      tt.append(" (");
+      if (isColourByLabel())
+      {
+        /*
+         * Jalview features file supports the combination of 
+         * colour by label or attribute text with score threshold
+         */
+        tt.append(I18N_SCORE).append(" ");
+      }
+      tt.append(isAboveThreshold() ? "> " : "< ");
+      tt.append(getThreshold()).append(")");
+    }
+
+    return tt.toString();
+  }
+
 }
index 6ddebf8..db37733 100644 (file)
@@ -13,6 +13,7 @@ import jalview.datamodel.features.FeatureMatcherSetI;
 import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
 import jalview.schemes.FeatureColour;
+import jalview.schemes.FeatureColourTest;
 import jalview.util.matcher.Condition;
 
 import java.awt.Color;
@@ -188,4 +189,42 @@ public class FeatureSettingsTest
     });
     seq.addSequenceFeature(sf);
   }
+
+  /**
+   * @see FeatureColourTest#testGetDescription()
+   * @throws IOException
+   */
+  @Test(groups = "Functional")
+  public void testGetColorTooltip() throws IOException
+  {
+    assertNull(FeatureSettings.getColorTooltip(null));
+
+    /*
+     * simple colour
+     */
+    FeatureColourI fc = new FeatureColour(Color.black);
+    String simpleTooltip = "Click to edit, right-click for menu";
+    assertEquals(FeatureSettings.getColorTooltip(fc), simpleTooltip);
+
+    /*
+     * graduated colour tooltip includes description of colour
+     */
+    fc.setColourByLabel(true);
+    assertEquals(FeatureSettings.getColorTooltip(fc),
+            "<html>By Label<br>" + simpleTooltip + "</br></html>");
+
+    /*
+     * graduated colour with threshold is html-encoded
+     */
+    fc = new FeatureColour(Color.red, Color.blue, 2f, 10f);
+    fc.setBelowThreshold(true);
+    fc.setThreshold(4f);
+    assertEquals(FeatureSettings.getColorTooltip(fc),
+            "<html>By Score (&lt; 4.0)<br>" + simpleTooltip
+                    + "</br></html>");
+    fc.setAboveThreshold(true);
+    assertEquals(FeatureSettings.getColorTooltip(fc),
+            "<html>By Score (&gt; 4.0)<br>" + simpleTooltip
+                    + "</br></html>");
+  }
 }
index 2eb718b..754e077 100644 (file)
@@ -663,4 +663,101 @@ public class FeatureColourTest
     Color expected = new Color(70, 120, 170);
     assertEquals(expected, fc.getColor(sf));
   }
+
+  /**
+   * Test description of feature colour suitable for a tooltip
+   */
+  @Test(groups = { "Functional" })
+  public void testGetDescription()
+  {
+    /*
+     * plain colour
+     */
+    FeatureColour fc = new FeatureColour(Color.RED);
+    assertEquals(
+            String.format("r=%d,g=%d,b=%d", Color.RED.getRed(),
+                    Color.red.getGreen(), Color.red.getBlue()),
+            fc.getDescription());
+  
+    /*
+     * colour by label (no threshold)
+     */
+    fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    assertEquals("By Label", fc.getDescription());
+  
+    /*
+     * colour by attribute text (no threshold)
+     */
+    fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    fc.setAttributeName("CLIN_SIG");
+    assertEquals("By CLIN_SIG", fc.getDescription());
+  
+    /*
+     * colour by label (above score threshold) 
+     */
+    fc = new FeatureColour();
+    fc.setColourByLabel(true);
+    fc.setAutoScaled(false);
+    fc.setThreshold(12.5f);
+    fc.setAboveThreshold(true);
+    assertEquals("By Label (Score > 12.5)",
+            fc.getDescription());
+  
+    /*
+     * colour by label (below score threshold)
+     */
+    fc.setBelowThreshold(true);
+    assertEquals("By Label (Score < 12.5)",
+            fc.getDescription());
+  
+    /*
+     * colour by attributes text (below score threshold)
+     */
+    fc.setBelowThreshold(true);
+    fc.setAttributeName("CSQ", "Consequence");
+    assertEquals(
+            "By CSQ:Consequence (Score < 12.5)",
+            fc.getDescription());
+  
+    /*
+     * graduated colour by score, no threshold
+     */
+    fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
+    assertEquals("By Score", fc.getDescription());
+  
+    /*
+     * graduated colour by score, below threshold
+     */
+    fc.setThreshold(12.5f);
+    fc.setBelowThreshold(true);
+    assertEquals("By Score (< 12.5)",
+            fc.getDescription());
+  
+    /*
+     * graduated colour by score, above threshold
+     */
+    fc.setThreshold(12.5f);
+    fc.setAboveThreshold(true);
+    fc.setAutoScaled(false);
+    assertEquals("By Score (> 12.5)",
+            fc.getDescription());
+
+    /*
+     * graduated colour by attribute, no threshold
+     */
+    fc.setAttributeName("CSQ", "AF");
+    fc.setAboveThreshold(false);
+    fc.setAutoScaled(false);
+    assertEquals("By CSQ:AF", fc.getDescription());
+  
+    /*
+     * graduated colour by attribute, above threshold
+     */
+    fc.setAboveThreshold(true);
+    fc.setAutoScaled(false);
+    assertEquals("By CSQ:AF (> 12.5)",
+            fc.getDescription());
+  }
 }