0301e7107474990ca5b3328ad5f622b018fb481c
kate
  Thu Jul 6 13:14:00 2017 -0700
Split label into left (gene) and right (tissues). refs #15646

diff --git src/hg/hgTracks/gtexEqtlClusterTrack.c src/hg/hgTracks/gtexEqtlClusterTrack.c
index 3d8b872..a2b800b 100644
--- src/hg/hgTracks/gtexEqtlClusterTrack.c
+++ src/hg/hgTracks/gtexEqtlClusterTrack.c
@@ -117,102 +117,132 @@
 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);
 boolean hasTissueFilter = filterTissues(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)
-/* Load all items (and motifs if table is present) in window */
+/* Left label is gene name */
 {
 struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
-struct dyString *ds = dyStringNew(0);
-if (eqtl->expCount == 1)
-    {
-    dyStringPrintf(ds, "%s in %s", eqtl->target, eqtl->expNames[0]);
+return eqtl->target;
 }
-else
+
+static char *gtexEqtlClusterSourcesLabel(struct track *track, void *item)
+/* Right label is tissue (or number of tissues if >1) */
 {
+struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
 int i, included;
 for (i=0, included=0; i<eqtl->expCount; i++)
     if (!isExcludedTissue(eqtl, i))
         included++;
-    dyStringPrintf(ds, "%s in %d tissues", eqtl->target, included);
-    }
+if (included == 1)
+    return eqtl->expNames[i-1];
+struct dyString *ds = dyStringNew(0);
+dyStringPrintf(ds, "%d tissues", included);
 return dyStringCannibalize(&ds);
 }
 
+static int gtexEqtlClusterItemRightPixels(struct track *track, void *item)
+/* Return number of pixels we need to the right of an item (for sources label). */
+{
+return mgFontStringWidth(tl.font, gtexEqtlClusterSourcesLabel(track, item));
+}
+
 static Color gtexEqtlClusterItemColor(struct track *track, void *item, struct hvGfx *hvg)
 /* Color by highest effect in list (blue -, red +), with brighter for higher effect (teal, fuschia) */
 {
 struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item;
 double maxEffect = 0.0;
 int i;
 for (i=0; i<eqtl->expCount; i++)
     {
     if (isExcludedTissue(eqtl, i))
         continue;
     double effect = eqtl->expScores[i];
     if (fabs(effect) > fabs(maxEffect))
         maxEffect = effect;
     }
 double cutoff = 2.0;
 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;
 }
 
-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)
+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) */
+{
+bedPlusLabelDrawAt(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;
+int x2 = round((double)((int)eqtl->chromEnd-winStart)*scale) + xOff;
+int x = x2 + tl.mWidth/2;
+char *label = gtexEqtlClusterSourcesLabel(track, item);
+int w = mgFontStringWidth(font, label);
+hvGfxTextCentered(hvg, x, y, w, track->heightPer, MG_BLACK, font, label);
+}
+
+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;
     struct dyString *ds = dyStringNew(0);
     dyStringPrintf(ds, "%s/%s: ", eqtl->name, eqtl->target);
     int i;
     for (i=0; i<eqtl->expCount; i++)
         {
         if (isExcludedTissue(eqtl, i))
             continue;
         double effect= eqtl->expScores[i];
         dyStringPrintf(ds, "%s(%s%0.2f)%s", eqtl->expNames[i], effect < 0 ? "" : "+", effect, 
                         i < eqtl->expCount - 1 ? ", " : "");
         //struct gtexTissue *tis = (struct gtexTissue *)hashFindVal(tissueHash, eqtl->expNames[i]);
         //unsigned color = tis ? tis->color : 0;       // BLACK
         //char *name = tis ? tis->name : "unknown";
         //#dyStringPrintf(ds,"<tr><td style='color: #%06X;'>*</td><td>%s</td><td>%s%0.2f</td></tr>\n", 
                                 //color, name, effect < 0 ? "" : "+", effect); 
         }
     title = dyStringCannibalize(&ds);
     }
-genericMapItem(track, hvg, item, title, itemName, start, end, x, y, width, height);
+int w = width + gtexEqtlClusterItemRightPixels(track, item);
+genericMapItem(track, hvg, item, title, itemName, start, end, x, y, w, height);
 }
 
 void gtexEqtlClusterMethods(struct track *track)
 /* BED5+5 with target, expNames,expScores, expProbs */
 {
 track->loadItems = gtexEqtlClusterLoadItems;
 track->itemName  = gtexEqtlClusterItemName;
 track->itemColor = gtexEqtlClusterItemColor;
+track->itemRightPixels = gtexEqtlClusterItemRightPixels;
+track->drawItemAt = gtexEqtlClusterDrawItemAt;
 track->mapItem = gtexEqtlClusterMapItem;
 }