1831801fae90a4dbda52bfc056ba230b0ffb07f3
kate
  Thu Oct 8 15:52:03 2015 -0700
A stab at adding axes and title to graph for GTEx details page. refs #15645

diff --git src/hg/hgc/gtexClick.c src/hg/hgc/gtexClick.c
index 1f0d8ec..643c710 100644
--- src/hg/hgc/gtexClick.c
+++ src/hg/hgc/gtexClick.c
@@ -11,43 +11,51 @@
 
 #include "rainbow.h"
 #include "hvGfx.h"
 #include "gtexUi.h"
 #include "gtexGeneBed.h"
 #include "gtexTissue.h"
 #include "gtexSampleData.h"
 
 /* Dimensions of image parts */
 int pad = 2;
 int margin = 1;
 //int graphHeight = 400;
 int graphHeight = 325;
 //int barWidth = 3;
 int barWidth = 12;
+int titleHeight = 30;
+
+int xAxisHeight = 100;
+int yAxisWidth = 50;
+int axisMargin = 5;
 
 /* Dimensions of image overall and our portion within it. */
 int imageWidth, imageHeight, innerWidth, innerHeight, innerXoff, innerYoff;
+int plotWidth, plotHeight;      /* just the plot */
 
 void setImageDims(int expCount)
 /* Set up image according to count */
 {
 innerHeight = graphHeight + 2*pad;
 innerWidth = pad + expCount*(pad + barWidth);
-imageWidth = innerWidth + 2*margin;
-imageHeight = innerHeight + 2*margin;
-innerXoff = margin;
-innerYoff = margin;
+plotWidth = innerWidth + 2*margin;
+plotHeight = innerHeight + 2*margin;
+imageWidth = plotWidth + yAxisWidth;
+imageHeight = plotHeight + xAxisHeight + titleHeight;
+innerXoff = yAxisWidth + margin;
+innerYoff = titleHeight + margin;
 }
 
 struct rgbColor rgbFromIntColor(int color)
 {
 return (struct rgbColor){.r=COLOR_32_BLUE(color), .g=COLOR_32_GREEN(color), .b=COLOR_32_RED(color)};
 }
 
 struct tissueSampleVals
 /* RPKM expression values for multiple samples */
     {
     struct tissueSampleVals *next;
     char *description;  /* GTEx tissue description */
     int color;          /* GTEx tissue color */
     int count;          /* number of samples */
     double *vals;       /* RPKM values */
@@ -177,33 +185,35 @@
     sr = sqlGetResult(conn, query);
     row = sqlNextRow(sr);
     if (row != NULL)
         {
         gtexGene = gtexGeneBedLoad(row);
         expCount = gtexGene->expCount;
         }
     sqlFreeResult(&sr);
     }
 hFreeConn(&conn);
 
 genericHeader(tdb, item);
 
 if (gtexGene != NULL)
     {
-    printf("<b>Gene name:</b> %s<br>\n", gtexGene->name);
-    printf("<b>Ensembl gene:</b> %s<br>\n", gtexGene->geneId);
-    printf("<b>Ensembl transcript:</b> %s<br>\n", gtexGene->transcriptId);
+    // TODO: link to UCSC gene
+    printf("<b>Gene:</b> %s</a></br>", gtexGene->name);
+    printf("<b>Ensembl ID:</b> %s<br>\n", gtexGene->geneId);
+    printf("<a target='_blank' href='http://www.gtexportal.org/home/gene/%s'>View at GTEx portal</a><br>\n", gtexGene->geneId);
+    puts("<p>");
     }
 
 // Get full sample data for this gene
 char *sampleDataTable = "gtexSampleData";
 conn = hAllocConn("hgFixed");
 assert(sqlTableExists(conn, sampleDataTable));
 sqlSafef(query, sizeof(query), "select * from %s where geneId='%s'", 
                 sampleDataTable, gtexGene->geneId);
 sr = sqlGetResult(conn, query);
 struct hash *tsHash = hashNew(0);
 struct tissueSampleVals *tsv;
 struct hashEl *hel;
 struct slDouble *val;
 double maxVal = 0;
 struct gtexSampleData *sd = NULL;
@@ -240,53 +250,67 @@
     double *vals = AllocArray(tsv->vals, count);
     for (i=0; i<count; i++)
         {
         val = slPopHead(&tsv->valList);
         if (doLogTransform)
             vals[i] = log10(val->val+1.0);
         else
             vals[i] = val->val;
         }
     doubleBoxWhiskerCalc(tsv->count, tsv->vals, 
                                 &tsv->min, &tsv->q1, &tsv->median, &tsv->q3, &tsv->max);
     slAddHead(&tsList, tsv);
     }
 
 // Tissue list is now sorted by GTEx tissue ordering.  
-// TODO: Option to sort by score descending.
+// Sort by score descending.
 slSort(&tsList, cmpTissueSampleValsMedianScore);
 slReverse(&tsList);
 
 // Initialize graphics for Box-and-whiskers plot
 setImageDims(slCount(tsList));
 struct tempName pngTn;
 trashDirFile(&pngTn, "hgc", "gtexGene", ".png");
 //uglyf("Trash file: %s\n", pngTn.forCgi);
 
 struct hvGfx *hvg = hvGfxOpenPng(imageWidth, imageHeight, pngTn.forCgi, FALSE);
 //hvGfxSetClip(hvg, 0, 0, imageWidth, imageHeight); // needed ?
 
 int x=innerXoff + pad, y = innerYoff + pad;
 for (tsv = tsList; tsv != NULL; tsv = tsv->next)
     {
     struct rgbColor fillColor = rgbFromIntColor(tsv->color);
     int fillColorIx = hvGfxFindColorIx(hvg, fillColor.r, fillColor.g, fillColor.b);
     drawBoxAndWhiskers(hvg, fillColorIx, x, y, tsv, maxVal);
     x += barWidth + pad;
     }
-
 //hvGfxUnclip(hvg);
+
+/* Draw title */
+int blackColorIx = hvGfxFindColorIx(hvg, 0,0,0);
+char title[256];
+safef(title, sizeof(title), "GTEx V4 Tissue Expression in %s", gtexGene->name);
+hvGfxTextCentered(hvg, 0, innerYoff, imageWidth, titleHeight, blackColorIx, mgMediumFont(), title);
+
+/* Draw axes */
+x = innerXoff - margin;
+// Y axis
+hvGfxLine(hvg, x, innerYoff, x, plotHeight, blackColorIx);
+// X axis
+y = innerYoff + plotHeight;
+hvGfxLine(hvg, innerXoff, y, plotWidth, y, blackColorIx);
+
 hvGfxClose(&hvg);
 printf("<IMG SRC = \"%s\" BORDER=1><BR>\n", pngTn.forHtml);
 /*printf("<IMG SRC = \"%s\" BORDER=1 WIDTH=%d HEIGHT=%d><BR>\n",
                 pngTn.forHtml, imageWidth, imageHeight);
 */
 //cloneString(gifTn.forHtml);
 
 // Track description
 printTrackHtml(tdb);
 
 // Print out tissue table with color assignments
 #ifdef DEBUG
 conn = hAllocConn("hgFixed");
 char *tissueTable = "gtexTissue";
 if (sqlTableExists(conn, tissueTable))