0dac71e93e49ead4669cb420b3db13b87d6540d1
kate
  Mon Nov 16 12:43:09 2015 -0800
Start on variable height pack layout.

diff --git src/hg/hgTracks/gtexTracks.c src/hg/hgTracks/gtexTracks.c
index 63b921b..e8f65dc 100644
--- src/hg/hgTracks/gtexTracks.c
+++ src/hg/hgTracks/gtexTracks.c
@@ -354,31 +354,31 @@
 struct gtexGeneBed *geneBed = geneInfo->geneBed;
 int count = geneBed->expCount;
 int labelWidth = geneInfo->medians2 ? tl.mWidth : 0;
 return (barWidth * count) + (padding * (count-1)) + labelWidth + 2;
 }
 
 static int gtexGraphX(struct gtexGeneBed *gtex)
 /* Locate graph on X, relative to viewport. Return -1 if it won't fit */
 {
 int start = max(gtex->chromStart, winStart);
 double scale = scaleForWindow(insideWidth, winStart, winEnd);
 int x1 = round((start - winStart) * scale);
 return x1;
 }
 
-static int gtexGeneHeight()
+static int gtexGeneModelHeight()
 {
     return 8; 
 }
 
 static int gtexGeneMargin()
 {
     return 1;
 }
 
 static int valToHeight(double val, double maxVal, int maxHeight, boolean doLogTransform)
 /* Log-scale and convert a value from 0 to maxVal to 0 to maxHeight-1 */
 {
 if (val == 0.0)
     return 0;
 double scaled = 0.0;
@@ -451,53 +451,55 @@
 Color statusColor = getTranscriptStatusColor(hvg, geneBed);
 if (vis != tvFull && vis != tvPack)
     {
     bedDrawSimpleAt(tg, geneBed, hvg, xOff, y, scale, font, statusColor, vis);
     return;
     }
 
 int heightPer = tg->heightPer;
 int graphX = gtexGraphX(geneBed);
 if (graphX < 0)
     return;
 
 int topGraphHeight = gtexGeneGraphHeight(tg, geneInfo, doLogTransform, TRUE);
 if (geneInfo->medians2)
     topGraphHeight = max(topGraphHeight, tl.fontHeight);
+if (vis == tvPack)
+    topGraphHeight = gtexMaxGraphHeight();
 int yZero = topGraphHeight + y - 1;  // yZero is bottom of graph
 
 #ifndef MULTI_REGION
 int x1 = xOff + graphX;         // x1 is at left of graph
 int keepX = x1;                 // FIXME:  Too many X's!
 drawGraphBase(hvg, keepX, yZero+1, geneInfo);
 
 int startX = x1;
 struct rgbColor lineColor = {.r=0};
 int lineColorIx = hvGfxFindColorIx(hvg, lineColor.r, lineColor.g, lineColor.b);
 int barWidth = gtexBarWidth();
 int graphPadding = gtexGraphPadding();
 char *colorScheme = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, GTEX_COLORS, 
                         GTEX_COLORS_DEFAULT);
 Color labelColor = MG_GRAY;
 Color clipColor = MG_MAGENTA;
 
 // add labels to comparison graphs
 // TODO: generalize
 if (geneInfo->medians2)
     {
     hvGfxText(hvg, x1, yZero - tl.fontHeight, labelColor, font, "F");
-    hvGfxText(hvg, x1, yZero + gtexGeneHeight() + gtexGeneMargin(), labelColor, font, "M");
+    hvGfxText(hvg, x1, yZero + gtexGeneModelHeight() + gtexGeneMargin(), labelColor, font, "M");
     startX = startX + tl.mWidth+2;
     x1 = startX;
     }
 
 // draw bar graph
 // TODO: share this code with other graph
 double viewMax = (double)cartUsualIntClosestToHome(cart, tg->tdb, FALSE, 
                                 GTEX_MAX_LIMIT, GTEX_MAX_LIMIT_DEFAULT);
 double maxMedian = ((struct gtexGeneExtras *)tg->extraUiData)->maxMedian;
 int i;
 int expCount = geneBed->expCount;
 struct gtexGeneExtras *extras = (struct gtexGeneExtras *)tg->extraUiData;
 for (i=0; i<expCount; i++)
     {
     struct rgbColor fillColor = extras->colors[i];
@@ -511,43 +513,43 @@
     int height = valToClippedHeight(expScore, maxMedian, viewMax, 
                                         gtexMaxGraphHeight(), doLogTransform);
     if (graphPadding == 0 || sameString(colorScheme, GTEX_COLORS_GTEX))
         hvGfxBox(hvg, x1, yZero-height+1, barWidth, height, fillColorIx);
     else
         hvGfxOutlinedBox(hvg, x1, yZero-height+1, barWidth, height, fillColorIx, lineColorIx);
     // mark clipped bar with magenta tip
     if (!doLogTransform && expScore > viewMax)
         hvGfxBox(hvg, x1, yZero-height+1, barWidth, 1, clipColor);
     x1 = x1 + barWidth + graphPadding;
     }
 #endif
 
 // draw gene model
 int yGene = yZero + gtexGeneMargin() - 1;
-tg->heightPer = gtexGeneHeight()+1;
+tg->heightPer = gtexGeneModelHeight() + 1;
 struct linkedFeatures *lf = linkedFeaturesFromGenePred(tg, geneInfo->geneModel, FALSE);
 lf->filterColor = statusColor;
 linkedFeaturesDrawAt(tg, lf, hvg, xOff, yGene, scale, font, color, tvSquish);
 tg->heightPer = heightPer;
 
 if (!geneInfo->medians2)
     return;
 
 #ifndef MULTI_REGION
 // draw comparison bar graph (upside down)
 x1 = startX;
-yZero = yGene + gtexGeneHeight() + 1; // yZero is at top of graph
+yZero = yGene + gtexGeneModelHeight() + 1; // yZero is at top of graph
 drawGraphBase(hvg, keepX, yZero-1, geneInfo);
 
 for (i=0; i<expCount; i++)
     {
     struct rgbColor fillColor = extras->colors[i];
     if (barWidth == 1 && sameString(colorScheme, GTEX_COLORS_GTEX))
         {
         // brighten colors a bit so they'll be more visible at this scale
         struct hslColor hsl = mgRgbToHsl(fillColor);
         hsl.s = min(1000, hsl.s + 300);
         fillColor = mgHslToRgb(hsl);
         }
     int fillColorIx = hvGfxFindColorIx(hvg, fillColor.r, fillColor.g, fillColor.b);
     double expScore = geneInfo->medians2[i];
     int height = valToClippedHeight(expScore, maxMedian, viewMax, gtexMaxGraphHeight(), 
@@ -607,111 +609,131 @@
 int graphWidth = gtexGraphWidth(geneInfo);
 hvGfxBox(hvg, x1, yZero+1, graphWidth, 1, lightGray);
 
 int barWidth = gtexBarWidth();
 int graphPadding = gtexGraphPadding();
 
 char *colorScheme = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, GTEX_COLORS,
                         GTEX_COLORS_DEFAULT);
 Color labelColor = MG_GRAY;
 
 if (geneInfo->medians2)
     {
     // add labels to comparison graphs
     // TODO: generalize
     hvGfxText(hvg, x1, yZero-tl.fontHeight, labelColor, font, "F");
-    hvGfxText(hvg, x1, yZero + gtexGeneHeight() + gtexGeneMargin(), labelColor, font, "M");
+    hvGfxText(hvg, x1, yZero + gtexGeneModelHeight() + gtexGeneMargin(), labelColor, font, "M");
     startX = startX + tl.mWidth + 2;
     x1 = startX;
     }
 for (i=0; i<expCount; i++)
     {
     struct rgbColor fillColor = extras->colors[i];
     if (barWidth == 1 && sameString(colorScheme, GTEX_COLORS_GTEX))
         {
         // brighten colors a bit so they'll be more visible at this scale
         fillColor = gtexTissueBrightenColor(fillColor);
         }
     int fillColorIx = hvGfxFindColorIx(hvg, fillColor.r, fillColor.g, fillColor.b);
 
     double expScore = (geneInfo->medians1 ? geneInfo->medians1[i] : geneBed->expScores[i]);
     int height = valToHeight(expScore, maxMedian, gtexMaxGraphHeight(), doLogTransform);
     if (graphPadding == 0 || sameString(colorScheme, GTEX_COLORS_GTEX))
         hvGfxBox(hvg, x1, yZero-height, barWidth, height, fillColorIx);
     else
         hvGfxOutlinedBox(hvg, x1, yZero-height, barWidth, height, fillColorIx, lineColorIx);
     x1 = x1 + barWidth + graphPadding;
     }
 
 // mark gene extent
 int yGene = yZero + gtexGeneMargin() - 1;
 
 /* GALT NOT DONE HERE NOW
 // draw gene model
-tg->heightPer = gtexGeneHeight()+1;
+tg->heightPer = gtexGeneModelHeight()+1;
 struct linkedFeatures *lf = linkedFeaturesFromGenePred(tg, geneInfo->geneModel, FALSE);
 lf->filterColor = statusColor;
 // GALT linkedFeaturesDrawAt(tg, lf, hvg, xOff, yGene, scale, font, color, tvSquish);
 tg->heightPer = heightPer;
 */
 if (!geneInfo->medians2)
     return;
 // draw comparison graph (upside down)
 x1 = startX;
-yZero = yGene + gtexGeneHeight(); // yZero is at top of graph
+yZero = yGene + gtexGeneModelHeight(); // yZero is at top of graph
 for (i=0; i<expCount; i++)
     {
     struct rgbColor fillColor = extras->colors[i];
     if (barWidth == 1 && sameString(colorScheme, GTEX_COLORS_GTEX))
         {
         // brighten colors a bit so they'll be more visible at this scale
         struct hslColor hsl = mgRgbToHsl(fillColor);
         hsl.s = min(1000, hsl.s + 300);
         fillColor = mgHslToRgb(hsl);
         }
     int fillColorIx = hvGfxFindColorIx(hvg, fillColor.r, fillColor.g, fillColor.b);
     double expScore = geneInfo->medians2[i];
     int height = valToHeight(expScore, maxMedian, gtexMaxGraphHeight(), doLogTransform);
     if (graphPadding == 0 || sameString(colorScheme, GTEX_COLORS_GTEX))
         hvGfxBox(hvg, x1, yZero, barWidth, height, fillColorIx);
     else
         hvGfxOutlinedBox(hvg, x1, yZero, barWidth, height, fillColorIx, lineColorIx);
     x1 = x1 + barWidth + graphPadding;
     }
 }
 #endif
 
-static int gtexGeneItemHeight(struct track *tg, void *item)
+static int gtexGeneItemHeightOptionalMax(struct track *tg, void *item, boolean isMax)
 {
-if ((item == NULL) || (tg->visibility == tvSquish) || (tg->visibility == tvDense))
+if (tg->visibility == tvSquish || tg->visibility == tvDense)
+    return 0;
+if (isMax)
+    {
+    int extra = 0;
+    if (((struct gtexGeneExtras *)tg->extraUiData)->isComparison)
+        extra = gtexMaxGraphHeight() + 2;
+    return gtexMaxGraphHeight() + gtexGeneMargin() + gtexGeneModelHeight() + extra;
+    }
+if (item == NULL)
     return 0;
+struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
 boolean doLogTransform = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, GTEX_LOG_TRANSFORM, 
                                                 GTEX_LOG_TRANSFORM_DEFAULT);
-struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
 int topGraphHeight = gtexGeneGraphHeight(tg, geneInfo, doLogTransform, TRUE);
 int bottomGraphHeight = 0;
 boolean isComparison = ((struct gtexGeneExtras *)tg->extraUiData)->isComparison;
 if (isComparison)
     {
     topGraphHeight = max(topGraphHeight, tl.fontHeight);
     bottomGraphHeight = max(gtexGeneGraphHeight(tg, geneInfo, doLogTransform, FALSE),
                                 tl.fontHeight) + gtexGeneMargin();
     }
-int height = topGraphHeight + bottomGraphHeight + gtexGeneMargin() + gtexGeneHeight();
+int height = topGraphHeight + bottomGraphHeight + gtexGeneMargin() + gtexGeneModelHeight();
 return height;
 }
 
+static int gtexGeneMaxHeight(struct track *tg)
+/* Maximum height in pixels of a gene graph */
+{
+return gtexGeneItemHeightOptionalMax(tg, NULL, TRUE);
+}
+
+static int gtexGeneItemHeight(struct track *tg, void *item)
+{
+return gtexGeneItemHeightOptionalMax(tg, item, FALSE);
+}
+
 static void gtexGeneDrawItemsFull(struct track *tg, int seqStart, int seqEnd,
                                       struct hvGfx *hvg, int xOff, int yOff, int width,
                                       MgFont *font, Color color, enum trackVisibility vis)
 /* Draw GTEx gene graphs in full mode.  Special handling as they are variable height */
 {
 double scale = scaleForWindow(width, seqStart, seqEnd);
 struct slList *item;
 int y = yOff + 1;
 for (item = tg->items; item != NULL; item = item->next)
     {
     tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, color, vis);
     genericDrawNextItem(tg, item, hvg, xOff, y, scale, color, vis);
     int height = gtexGeneItemHeight(tg, item);
     y += height;
     }
@@ -754,81 +776,84 @@
 // x1 is at left of graph
 int x1 = insideX + graphX;
 
 if (geneInfo->medians2)
     {
     // skip over labels in comparison graphs
     x1 = x1 + tl.mWidth+ 2;
     }
 int i = 0;
 
 boolean doLogTransform = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, GTEX_LOG_TRANSFORM, 
                                                 GTEX_LOG_TRANSFORM_DEFAULT);
 int topGraphHeight = gtexGeneGraphHeight(tg, geneInfo, doLogTransform, TRUE);
 if (geneInfo->medians2)
     topGraphHeight = max(topGraphHeight, tl.fontHeight);        // label
+if (tg->visibility == tvPack)
+    topGraphHeight = gtexGeneMaxHeight(tg);
 int yZero = topGraphHeight + y - 1;  // yZero is bottom of (top) graph
 
 double viewMax = (double)cartUsualIntClosestToHome(cart, tg->tdb, FALSE, 
                                 GTEX_MAX_LIMIT, GTEX_MAX_LIMIT_DEFAULT);
 for (tissue = tissues; tissue != NULL; tissue = tissue->next, i++)
     {
     double expScore =  (geneInfo->medians1 ? geneInfo->medians1[i] : geneBed->expScores[i]);
     int height = valToClippedHeight(expScore, maxMedian, viewMax, 
                                         gtexMaxGraphHeight(), doLogTransform);
     mapBoxHc(hvg, start, end, x1, yZero-height, barWidth, height, tg->track, mapItemName, 
                 tissue->description);
     // add map box to comparison graph
     if (geneInfo->medians2)
         {
         double expScore = geneInfo->medians2[i];
         int height = valToClippedHeight(expScore, maxMedian, viewMax, 
                                         gtexMaxGraphHeight(), doLogTransform);
-        int y = yZero + gtexGeneHeight() + gtexGeneMargin();  // y is top of bottom graph
+        int y = yZero + gtexGeneModelHeight() + gtexGeneMargin();  // y is top of bottom graph
         mapBoxHc(hvg, start, end, x1, y, barWidth, height, tg->track, mapItemName, 
                         tissue->description);
         }
     x1 = x1 + barWidth + padding;
     }
 }
 
 static char *gtexGeneItemName(struct track *tg, void *item)
 /* Return gene name */
 {
 struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
 struct gtexGeneBed *geneBed = geneInfo->geneBed;
 return geneBed->name;
 }
 
 static int gtexGeneTotalHeight(struct track *tg, enum trackVisibility vis)
 /* Figure out total height of track. Set in track and also return it */
 {
 int height = 0;
 struct gtexGeneInfo *item;
 if (tg->visibility == tvSquish || tg->visibility == tvDense)
     {
     height = tgFixedTotalHeightOptionalOverflow(tg, vis, tl.fontHeight+1, tl.fontHeight, FALSE);
     }
 else if (tg->visibility == tvFull)
     {
     for (item = tg->items; item != NULL; item = item->next)
         height += gtexGeneItemHeight(tg, item);
     }
-else
+else if (tg->visibility == tvPack)
     {
-    for (item = tg->items; item != NULL; item = item->next)
-        height += gtexGeneItemHeight(tg, item);
+    // layout as fixed height
+    int maxHeight = gtexGeneMaxHeight(tg);
+    height = tgFixedTotalHeightOptionalOverflow(tg, vis, maxHeight, maxHeight, FALSE); // TODO: allow oflow ?
     }
 tg->height = height;
 return height;
 }
 
 static int gtexGeneItemStart(struct track *tg, void *item)
 /* Return end chromosome coordinate of item, including graph */
 {
 struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
 struct gtexGeneBed *geneBed = geneInfo->geneBed;
 return geneBed->chromStart;
 }
 
 static int gtexGeneItemEnd(struct track *tg, void *item)
 /* Return end chromosome coordinate of item, including graph */