9e6c57d6f56f6dc6e8d5d981fa097b6880787730
kent
  Wed Nov 24 14:09:51 2021 -0800
Adding support for filtering based on facets selected in the details/UI page.

diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c
index 05f5ec4..2ad067a 100644
--- src/hg/hgTracks/barChartTrack.c
+++ src/hg/hgTracks/barChartTrack.c
@@ -19,30 +19,32 @@
 // Could be a trackDb setting
 
 struct barChartTrack
 /* Track extras */
     {
     boolean noWhiteout;         /* Suppress whiteout of graph background (allow highlight, blue lines) */
     double maxMedian;           /* Maximum median across all categories */
     boolean doLogTransform;     /* Log10(x+1) */
     char *unit;                /* Units for category values (e.g. RPKM) */
     struct barChartCategory *categories; /* Category names, colors, etc. */
     int categCount;             /* Count of categories - derived from above */
     char **categNames;          /* Category names  - derived from above */
     char **categLabels;         /* Category labels  - derived from above */
     struct rgbColor *colors;    /* Colors  for all categories */
     struct hash *categoryFilter; /* NULL out excluded factors */
+    struct fieldedTable *statsTable;  /* Filled in if barChartStats setting is there */
+    struct facetedTable *facetsTable;  /* Filled in if barChartFacets setting is there */
     int maxViewLimit;
 
     // dimensions for drawing
     char *maxGraphSize;         /* optionally limit graph size (override semantic zoom)
                                      small, medium, or large (default) */
      int winMaxGraph;             /* Draw large graphs if window size smaller than this */
      int winMedGraph;             /* Draw medium graphs if window size greater than this 
                                         and smaller than winMaxGraph */
      int winSmallGraph;		/* Draw small graphs if windowSize between this and 
                                  * win medGraph, draw tiny if smaller */
 
     int squishHeight;           /* Height of item in squish mode (larger than typical) */
     int boxModelHeight;         /* Height of indicator box drawn under graph to show gene extent */
     int modelHeight;            /* Height of box drawn under graph with margin */
     int margin;			/* Added to pixel height to help separate things */
@@ -57,35 +59,30 @@
 struct barChartItem
 /* BED item plus computed values for display */
     {
     struct barChartItem *next;  /* Next in singly linked list */
     struct bed *bed;            /* Item coords, name, exp count and values */
     int height;                 /* Item height in pixels */
     };
 
 /***********************************************/
 /* Organize category info */
 
 struct barChartCategory *getCategories(struct track *tg)
 /* Get and cache category extras */
 {
 struct barChartTrack *extras;
-if (!tg->extraUiData)
-    {
-    AllocVar(extras);
-    tg->extraUiData = extras;
-    }
 extras = (struct barChartTrack *)tg->extraUiData;
 if (extras->categories == NULL)
     extras->categories = barChartUiGetCategories(database, tg->tdb);
 return extras->categories;
 }
 
 int getCategoryCount(struct track *tg)
 /* Get and cache the number of categories */
 {
 struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData;
 if (extras->categCount == 0)
     extras->categCount = slCount(getCategories(tg));
 return extras->categCount;
 }
 
@@ -136,44 +133,54 @@
 int count = slCount(categs);
 struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData;
 if (!extras->colors)
     {
     AllocArray(extras->colors, count);
     int i = 0;
     for (categ = categs; categ != NULL; categ = categ->next)
         {
         extras->colors[i] = (struct rgbColor){.r=COLOR_32_BLUE(categ->color), .g=COLOR_32_GREEN(categ->color), .b=COLOR_32_RED(categ->color)};
         i++;
         }
     }
 return extras->colors;
 }
 
+static void fillInTables(struct track *tg, struct barChartTrack *extras)
+/* Fill in statTable and facetsTable on extras */
+{
+char *barChartStatsUrl = trackDbSetting(tg->tdb, "barChartStatsUrl");
+if (barChartStatsUrl != NULL)
+    {
+    extras->statsTable = fieldedTableFromTabFile(barChartStatsUrl,
+	    barChartStatsUrl, NULL, 0);
+    char *barChartFacets = trackDbSetting(tg->tdb, "barChartFacets");
+    if (barChartFacets != NULL)
+	extras->facetsTable = facetedTableFromTable(extras->statsTable, tg->track, barChartFacets);
+    }
+}
+
 static void filterCategories(struct track *tg)
 /* Check cart for category selection.  NULL out unselected categorys in category list */
 {
 struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData;
 struct barChartCategory *categ = NULL;
 extras->categories = getCategories(tg);
 extras->categoryFilter = hashNew(0);
-char *barChartFacets = trackDbSetting(tg->tdb, "barChartFacets");
-char *barChartStatsUrl = trackDbSetting(tg->tdb, "barChartStatsUrl");
-if (barChartFacets != NULL && barChartStatsUrl != NULL)
+if (extras->facetsTable != NULL && extras->statsTable != NULL)
     {
-    struct fieldedTable *table = fieldedTableFromTabFile(barChartStatsUrl,
-	barChartStatsUrl, NULL, 0);
-    struct facetedTable *facTab = facetedTableFromTable(table, tg->track, barChartFacets);
+    struct facetedTable *facTab = extras->facetsTable;
     struct slInt *sel, *selList = facetedTableSelectOffsets(facTab, cart);
     for (sel = selList; sel != NULL; sel = sel->next)
         {
 	char numBuf[16];
 	safef(numBuf, sizeof(numBuf), "%d", sel->val);
 	char *numCopy = lmCloneString(extras->categoryFilter->lm, numBuf);
 	hashAdd(extras->categoryFilter, numCopy, numCopy);
 	}
     return;
     }
 else if (cartListVarExistsAnyLevel(cart, tg->tdb, FALSE, BAR_CHART_CATEGORY_SELECT))
     {
     struct slName *selectedValues = cartOptionalSlNameListClosestToHome(cart, tg->tdb, 
                                                         FALSE, BAR_CHART_CATEGORY_SELECT);
     if (selectedValues != NULL)
@@ -471,30 +478,31 @@
 
 /* Create itemInfo items with BED and geneModels */
 struct barChartItem *itemInfo = NULL, *list = NULL;
 struct bed *bed = (struct bed *)tg->items;
 
 /* Test that configuration matches data file */
 if (bed != NULL)
     {
     int categCount = getCategoryCount(tg);
     int expCount = bed->expCount;
     if (categCount != expCount)
         warn("Bar chart track: category count mismatch between trackDb (%d) and data file (%d)",
                             categCount, expCount);
     }
 
+fillInTables(tg, extras);
 filterCategories(tg);
 
 int barCount = filteredCategoryCount(extras);
 double scale = 1.0;
 if (barCount <= 20)
     scale = 2.5;
 else if (barCount <= 40)
     scale = 1.6;
 else if (barCount <= 60)
     scale = 1.0;
 else if (barCount <= 120)
     scale = 0.8;
 else if (barCount <= 200)
     scale = 0.6;
 else