d3f9b9ecf2a6d30bd8f97566f72e5650982c308d
kent
  Mon Dec 13 15:22:03 2021 -0800
Adding hgTracks display of merged bar charts.

diff --git src/hg/lib/barChartUi.c src/hg/lib/barChartUi.c
index 46e8094..c1b0fa3 100644
--- src/hg/lib/barChartUi.c
+++ src/hg/lib/barChartUi.c
@@ -256,30 +256,44 @@
             errAbort("barChart track %s category file %s expecting %d words, got %d",
                         track, categUrl, cols, wordCount);
         }
     else
         {
         cols = wordCount;
         }
     slAddHead(&labels, slNameNew(words[0]));
     if (wordCount == 2)
         slAddHead(&colors, slNameNew(words[1]));
     }
 slReverse(&labels);
 slReverse(&colors);
 }
 
+static void getCategsFromMergeList(struct facetedTableMergedOffset *mergeList,
+                                        struct slName **labels, struct slName **colors)
+/* Given merged list, return separate list of labels and colors */
+{
+struct facetedTableMergedOffset *tmo;
+for (tmo = mergeList; tmo != NULL; tmo = tmo->next)
+    {
+    slNameAddHead(labels, tmo->name);
+    slNameAddHead(colors, tmo->color);
+    }
+slReverse(labels);
+slReverse(colors);
+}
+
 static struct barChartCategory *createCategs(char *track, 
                                                 struct slName *labels, struct slName *colors)
 /* Populate category structs from label and color lists.  Assign rainbow if no color list */
 {
 struct barChartCategory *categs = NULL, *categ = NULL;
 int count = slCount(labels);
 struct rgbColor *rainbow = NULL;
 if (!colors)
     {
     rainbow = getRainbow(&saturatedRainbowAtPos, count);
     }
 int i;
 char buf[6];
 for (i=0 ; i<count && labels; i++)
     {
@@ -317,93 +331,99 @@
                             track, color, slNameListToString(htmlColorNames(),','));
                     }
                 }
             }
         categ->color = rgb;
         }
     slAddHead(&categs, categ);
     labels = labels->next;
     if (colors)
         colors = colors->next;
     }
 slReverse(&categs);
 return categs;
 }
 
-struct barChartCategory *barChartUiGetCategories(char *database, struct trackDb *tdb)
-/* Get category colors and descriptive labels.
-   Use labels in tab-sep file specified by barChartCategoryUrl setting, o/w in barChartBars setting.
+struct barChartCategory *barChartUiGetCategories(char *database, struct trackDb *tdb,
+    struct facetedTableMergedOffset *mergeList)
+/* Get category colors and descriptive labels.  If mergeList is non-NULL gets it from there,else
+   use labels in tab-sep file specified by barChartCategoryUrl setting, o/w in barChartBars setting.
    If colors are not specified via barChartColors setting or second column in category file,
    assign rainbow colors.  Colors are specified as #fffff or r,g,b  or html color name) */
 {
 struct slName *labels = NULL, *colors = NULL;
 char *categUrl = trackDbSetting(tdb, BAR_CHART_CATEGORY_URL);
-if (isNotEmpty(categUrl))
+if (mergeList != NULL)
+    {
+    getCategsFromMergeList(mergeList, &labels, &colors);
+    }
+else if (isNotEmpty(categUrl))
     getCategsFromFile(tdb->track, categUrl, &labels, &colors);
 else
     {
     char *labelSetting = trackDbSetting(tdb, BAR_CHART_CATEGORY_LABELS);
     char *colorSetting = trackDbSetting(tdb, BAR_CHART_CATEGORY_COLORS);
     getCategsFromSettings(tdb->track, labelSetting, colorSetting, &labels, &colors);
     }
 return createCategs(tdb->track, labels, colors);
 }
 
 struct barChartCategory *barChartUiGetCategoryById(int id, char *database, 
-                                                        struct trackDb *tdb)
+			       struct trackDb *tdb, struct facetedTableMergedOffset *mergeList)
 /* Get category info by id */
 {
 struct barChartCategory *categ;
-struct barChartCategory *categs = barChartUiGetCategories(database, tdb);
+struct barChartCategory *categs = barChartUiGetCategories(database, tdb, mergeList);
 for (categ = categs; categ != NULL; categ = categ->next)
     if (categ->id == id)
         return categ;
 return NULL;
 }
 
-char *barChartUiGetCategoryLabelById(int id, char *database, struct trackDb *tdb)
+char *barChartUiGetCategoryLabelById(int id, char *database, 
+			       struct trackDb *tdb, struct facetedTableMergedOffset *mergeList)
 /* Get label for a category id */
 {
-struct barChartCategory *categ = barChartUiGetCategoryById(id, database, tdb);
+struct barChartCategory *categ = barChartUiGetCategoryById(id, database, tdb, mergeList);
 if (categ == NULL)
     return "Unknown";
 return categ->label;
 }
 
-void barChartCfgUiSelectEachBar(char *database, struct cart *cart, struct trackDb *tdb, char *track, 
-                        char *title, boolean boxed)
+void barChartCfgUiSelectEachBar(char *database, struct cart *cart, struct trackDb *tdb, 
+	char *track, char *title, boolean boxed)
 /* Bar chart track type */
 {
 printf("\n<table id=barChartControls style='font-size:%d%%' %s>\n<tr><td>", 
         isPopup ? 75 : 100, boxed ?" width='100%'":"");
 
 /* Data transform. When selected, the next control (view limits max) is disabled */
 
 puts("<div>");
 barChartUiLogTransform(cart, track, tdb);
 
 /* Viewing limits max.  This control is disabled if log transform is selected */
 // construct class so JS can toggle
 puts("&nbsp;&nbsp;");
 barChartUiViewLimits(cart, track, tdb);
 puts("</div>");
 /* Category filter */
 printf("<br>");
 char *categoryLabel =  trackDbSettingClosestToHomeOrDefault(tdb, 
                     BAR_CHART_CATEGORY_LABEL, BAR_CHART_CATEGORY_LABEL_DEFAULT);
 char *db = cartString(cart, "db");
-struct barChartCategory *categs = barChartUiGetCategories(db, tdb);
+struct barChartCategory *categs = barChartUiGetCategories(db, tdb, NULL);
 printf("<div><b>%s:</b>\n", categoryLabel);
 char cartVar[1024];
 safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_CATEGORY_SELECT);
 if (isPopup)
     {
     printf("<a href='%s?g=%s'><button type='button'>Change</button><a>", 
                 hTrackUiForTrack(track), track);
     }
 else
     {
     jsMakeCheckboxGroupSetClearButton(cartVar, TRUE);
     puts("&nbsp;");
     jsMakeCheckboxGroupSetClearButton(cartVar, FALSE);
     }
 printf("</div>");