dab44418c480b8c931d0b86af916bbb3bf64ffe3
kent
  Fri Jan 1 08:06:26 2021 -0800
Adding barChartStatsUrl tag.  Right now it is ignored by the browser if barChartMatrixUrl is present. It points to a tab separated file with a label row and a few required fields.

diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c
index 4852218..72bc3df 100644
--- src/hg/hgc/barChartClick.c
+++ src/hg/hgc/barChartClick.c
@@ -3,30 +3,31 @@
 /* Copyright (C) 2015 The Regents of the University of California 
  * See README in this or parent directory for licensing information. */
 
 #include "common.h"
 #include "hash.h"
 #include "hdb.h"
 #include "hvGfx.h"
 #include "trashDir.h"
 #include "hCommon.h"
 #include "hui.h"
 #include "asParse.h"
 #include "hgc.h"
 #include "trackHub.h"
 #include "memgfx.h"
 #include "hgColors.h"
+#include "fieldedTable.h"
 
 #include "barChartBed.h"
 #include "barChartCategory.h"
 #include "barChartData.h"
 #include "barChartSample.h"
 #include "barChartUi.h"
 
 #define EXTRA_FIELDS_SIZE 256
 
 struct barChartItemData
 /* Measured value for a sample and the sample category at a locus.
  * Used for barChart track details (boxplot) */
     {
     struct barChartItemData *next;  /* Next in singly linked list. */
     char *sample;	/* Sample identifier */
@@ -390,80 +391,104 @@
 
 
 static void printBarChart(struct barChartBed *chart, struct trackDb *tdb, double maxVal, char *metric)
 /* Plot bar chart without quartiles or anything fancy just using SVG */
 {
 /* Load up input labels, color, and data */
 struct barChartCategory *categs = barChartUiGetCategories(database, tdb);
 int categCount = slCount(categs);
 if (categCount != chart->expCount)
     {
     warn("Problem in %s barchart track. There are %d categories in trackDb and %d in data",
 	tdb->track, categCount, chart->expCount);
     return;
     }
 
+char *statsFile = trackDbSetting(tdb, "barChartStatsUrl");
+struct hash *statsHash = NULL;
+int countStatIx = 0;
+double statsSize = 0.0;
+if (statsFile != NULL)
+    {
+    char *required[] = {"cluster", "count", "total"};
+    struct fieldedTable *ft = fieldedTableFromTabFile(
+	statsFile, statsFile, required, ArraySize(required));
+    statsHash = fieldedTableIndex(ft, "cluster");
+    countStatIx = fieldedTableFindFieldIx(ft, "count");
+    statsSize = 8*(fieldedTableMaxColChars(ft, countStatIx)+1);
+    }
+
 /* Some constants that control layout */
 double heightPer=18.0;
 double totalWidth=1250.0;
 double borderSize = 1.0;
 
-
 double headerHeight = heightPer + 2*borderSize;
 double innerHeight=heightPer-borderSize;
 double labelWidth = longestLabelSize(categs) + 9;  // Add some because size is just estimate
 if (labelWidth > totalWidth/2) labelWidth = totalWidth/2;  // Don't let labels take up more than half
 double patchWidth = heightPer;
 double labelOffset = patchWidth + 2*borderSize;
-double barOffset = labelOffset + labelWidth;
+double statsOffset = labelOffset + labelWidth;
+double barOffset = statsOffset + statsSize;
 double barMaxWidth = totalWidth-barOffset - 45;	    // The 45 is to leave room for ~6 digit number at end.
 double totalHeight = headerHeight + heightPer * categCount + borderSize;
 
 printf("<svg width=\"%g\" height=\"%g\">\n", totalWidth, totalHeight);
 
 /* Draw header */
 printf("<rect width=\"%g\" height=\"%g\" style=\"fill:#%s\"/>\n", totalWidth, headerHeight, HG_COL_HEADER);
 printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%s</text>\n", 
     labelOffset, innerHeight-1, innerHeight-1, "Sample");
+if (statsSize > 0.0)
+    printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%s</text>\n", 
+	statsOffset, innerHeight-1, innerHeight-1, "N");
 printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%s %s</text>\n", 
     barOffset, innerHeight-1, innerHeight-1, metric, "Value");
 
 /* Set up clipping path for the pesky labels, which may be too long */
 printf("<clipPath id=\"labelClip\"><rect x=\"%g\" y=\"0\" width=\"%g\" height=\"%g\"/></clipPath>\n",
     labelOffset, barOffset-labelOffset, totalHeight);
 
 double yPos = headerHeight;
 struct barChartCategory *categ;
 int i;
 for (i=0, categ=categs; i<categCount; ++i , categ=categ->next, yPos += heightPer)
     {
     double score = chart->expScores[i];
     double barWidth = 0;
     if (maxVal > 0.0)
 	barWidth = barMaxWidth * score/maxVal;
     replaceChar(categ->label, '_', ' ');
     printf("<rect x=\"0\" y=\"%g\" width=\"15\" height=\"%g\" style=\"fill:#%06X\"/>\n",
 	yPos, innerHeight, categ->color);
     printf("<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:#%06X\"/>\n",
 	barOffset, yPos, barWidth, innerHeight, categ->color);
     if (i&1)  // every other time
 	printf("<rect x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" style=\"fill:#%06X\"/>\n",
-	    labelOffset, yPos, labelWidth, innerHeight, 0xFFFFFF);
-    printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\" clip-path=\"url(#labelClip)\"\">%s</text>\n", 
- 	labelOffset, yPos+innerHeight-1, innerHeight-1, categ->label);
+	    labelOffset, yPos, labelWidth+statsSize, innerHeight, 0xFFFFFF);
     printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\" clip-path=\"url(#labelClip)\"\">%s</text>\n", 
  	labelOffset, yPos+innerHeight-1, innerHeight-1, categ->label);
+    if (statsSize > 0.0)
+	{
+	struct fieldedRow *fr = hashFindVal(statsHash, categ->label);
+	if (fr != NULL)
+	    {
+	    printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%s</text>\n", 
+		statsOffset, yPos+innerHeight-1, innerHeight-1, fr->row[countStatIx]);
+	    }
+	}
     printf("<text x=\"%g\" y=\"%g\" font-size=\"%g\">%5.3f</text>\n", 
 	barOffset+barWidth+2, yPos+innerHeight-1, innerHeight-1, score);
     }
 printf("<svg>");
 }
 
 
 struct asColumn *asFindColByIx(struct asObject *as, int ix)
 /* Find AS column by index */
 {
 struct asColumn *asCol;
 int i;
 for (i=0, asCol = as->columnList; asCol != NULL && i<ix; asCol = asCol->next, i++);
     return asCol;
 }