7b7d273fd3aeee222d5ee8540298ac6dee662605
kate
  Wed Sep 13 11:45:23 2017 -0700
Add UI setting to toggle display of tissue color patches (for single-tissue eQTL's.  It can be distracting in large regions. refs #15646

diff --git src/hg/hgTracks/gtexEqtlClusterTrack.c src/hg/hgTracks/gtexEqtlClusterTrack.c
index 422bfad..bbdf2a8 100644
--- src/hg/hgTracks/gtexEqtlClusterTrack.c
+++ src/hg/hgTracks/gtexEqtlClusterTrack.c
@@ -4,30 +4,31 @@
  * See README in this or parent directory for licensing information. */
 
 #include "common.h"
 #include "dystring.h"
 #include "hgTracks.h"
 #include "gtexInfo.h"
 #include "gtexTissue.h"
 #include "gtexUi.h"
 #include "gtexEqtlCluster.h"
 
 struct gtexEqtlClusterTrack
 /* Track info for filtering (maybe later for draw, map) */
 {
     struct gtexTissue *tissues; /*  Tissue names, descriptions */
     struct hash *tissueHash;    /* Tissue info, keyed by UCSC name, filtered by UI */
+    boolean doTissueColor;      /* Display tissue color (for single-tissue eQTL's) */
     double minEffect;           /* Effect size filter (abs value) */
     double minProb;             /* Probability filter */
 };
 
 /* Utility functions */
 
 static struct gtexEqtlCluster *loadOne(char **row)
 /* Load up gtexEqtlCluster from array of strings. */
 {
 return gtexEqtlClusterLoad(row);
 }
 
 static boolean filterTissuesFromCart(struct track *track, struct gtexEqtlClusterTrack *extras)
 /* Check cart for tissue selection. Populate track tissues hash */
 {
@@ -150,48 +151,52 @@
     }
 struct dyString *ds = dyStringNew(0);
 dyStringPrintf(ds, "%d tissues", ct);
 return dyStringCannibalize(&ds);
 }
 
 /* Track methods */
 
 static void gtexEqtlClusterLoadItems(struct track *track)
 /* Load items in window and prune those that don't pass filter */
 {
 /* initialize track info */
 struct gtexEqtlClusterTrack *extras;
 AllocVar(extras);
 track->extraUiData = extras;
+char cartVar[64];
+
+// UI settings
+safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_TISSUE_COLOR);
+extras->doTissueColor = cartUsualBoolean(cart, cartVar, GTEX_EQTL_TISSUE_COLOR_DEFAULT);
 
 // filter by gene via SQL
-char cartVar[64];
 safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_GENE);
 char *gene = cartNonemptyString(cart, cartVar);
 char *where = NULL;
 if (gene)
     {
     struct dyString *ds = dyStringNew(0);
     sqlDyStringPrintfFrag(ds, "%s = '%s'", GTEX_EQTL_GENE_FIELD, gene); 
     where = dyStringCannibalize(&ds);
     }
 bedLoadItemWhere(track, track->table, where, (ItemLoader)loadOne);
 
 safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_EFFECT);
 extras->minEffect = fabs(cartUsualDouble(cart, cartVar, GTEX_EFFECT_MIN_DEFAULT));
 safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_PROBABILITY);
-extras->minProb = cartUsualDouble(cart, cartVar, 0.0);
+extras->minProb = cartUsualDouble(cart, cartVar, GTEX_EQTL_PROBABILITY_DEFAULT);
 boolean hasTissueFilter = filterTissuesFromCart(track, extras);
 if (!hasTissueFilter && extras->minEffect == 0.0 && extras->minProb == 0.0)
     return;
 
 // more filtering
 filterItems(track, eqtlIncludeFilter, "include");
 }
 
 static char *gtexEqtlClusterItemName(struct track *track, void *item)
 /* Left label is gene name */
 {
 struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
 return eqtl->target;
 }
 
@@ -213,68 +218,72 @@
 if (maxEffect < 0.0)
     {
     /* down-regulation displayed as blue */
     if (maxEffect < 0.0 - cutoff)
         return MG_CYAN;
     return MG_BLUE;
     }
 /* up-regulation displayed as red */
 if (maxEffect > cutoff)
     return MG_MAGENTA;
 return MG_RED;
 }
 
 /* Helper macros */
 
-#define tissueColorPatchSpacer()        (tl.nWidth/4)
+#define tissueColorPatchSpacer()        (max(2, tl.nWidth/4))
 
-#define tissueColorPatchWidth()         (tl.nWidth)
+//#define tissueColorPatchWidth()         (tl.nWidth)
+//#define tissueColorPatchWidth()         (tl.mWidth/2)
+//#define tissueColorPatchWidth()         (tl.mWidth * .75)
+#define tissueColorPatchWidth()         (tl.nWidth * .8)
 
 static int gtexEqtlClusterItemRightPixels(struct track *track, void *item)
 /* Return number of pixels we need to the right of an item (for sources label). */
 {
 struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
 int ret = mgFontStringWidth(tl.font, eqtlSourcesLabel(eqtl));
 if (eqtlTissueCount(eqtl) == 1)
     ret += tissueColorPatchWidth() + tissueColorPatchSpacer();
 return ret;
 }
 
 static void gtexEqtlClusterDrawItemAt(struct track *track, void *item, 
 	struct hvGfx *hvg, int xOff, int y, 
 	double scale, MgFont *font, Color color, enum trackVisibility vis)
 /* Draw GTEx eQTL cluster with right label indicating source(s) */
 {
 bedDrawSimpleAt(track, item, hvg, xOff, y, scale, font, color, vis);
 if (vis != tvFull && vis != tvPack)
     return;
 
 /* Draw text to the right */
 struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
+struct gtexEqtlClusterTrack *extras = (struct gtexEqtlClusterTrack *)track->extraUiData;
 int x2 = round((double)((int)eqtl->chromEnd-winStart)*scale) + xOff;
 int x = x2 + tl.mWidth/2;
 char *label = eqtlSourcesLabel(eqtl);
 int w = mgFontStringWidth(font, label);
 hvGfxTextCentered(hvg, x, y, w, track->heightPer, MG_BLACK, font, label);
-if (eqtlTissueCount(eqtl) == 1)
+if (eqtlTissueCount(eqtl) == 1 && extras->doTissueColor)
     {
     // tissue color patch (box)
     x += w;
     int h = w = tissueColorPatchWidth();
     struct rgbColor tisColor = eqtlTissueColor(track, eqtl);
     int ix = hvGfxFindColorIx(hvg, tisColor.r, tisColor.g, tisColor.b);
-    hvGfxBox(hvg, x + tissueColorPatchSpacer(), y + (tl.fontHeight - h)/2 + tl.fontHeight/8, w, h, ix);
+    hvGfxBox(hvg, x + tissueColorPatchSpacer(), y + (tl.fontHeight - h)/2 + tl.fontHeight/10, w, h, ix);
     }
 }
 
 static void gtexEqtlClusterMapItem(struct track *track, struct hvGfx *hvg, void *item, 
                                 char *itemName, char *mapItemName, int start, int end, 
                                 int x, int y, int width, int height)
 /* Create a map box on item and label with list of tissues with colors and effect size */
 {
 char *title = itemName;
 if (track->limitedVis != tvDense)
     {
     struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
     // Experiment: construct list of tissues with colors and effect sizes for mouseover
     //struct gtexEqtlClusterTrack *extras = (struct gtexEqtlClusterTrack *)track->extraUiData;
     //struct hash *tissueHash = extras->tissueHash;