ca96dfa92667ad79f4d247e25befab59cfa90258
kate
  Thu Apr 13 12:49:53 2017 -0700
Add barChartColors setting to allow specifying barchart colors by name.  Add HTML color names support to lib. refs #18736

diff --git src/hg/lib/barChartUi.c src/hg/lib/barChartUi.c
index 0772270..6bc0d3f 100644
--- src/hg/lib/barChartUi.c
+++ src/hg/lib/barChartUi.c
@@ -1,27 +1,28 @@
 /* Bar chart track controls */
 
 /* Copyright (C) 2015 The Regents of the University of California 
  * See README in this or parent directory for licensing information. */
 
 #include "cheapcgi.h"
 #include "cart.h"
 #include "hui.h"
 #include "trackDb.h"
 #include "jsHelper.h"
 #include "hCommon.h"
 #include "rainbow.h"
+#include "htmlColor.h"
 #include "barChartCategory.h"
 #include "barChartUi.h"
 
 /* Restrict features on right-click (popup) version */
 /* FIXME: NOT STATIC */
 static boolean isPopup = FALSE;
 
 /* Convenience functions for category filter controls */
 
 
 char *makeCategoryLabel(struct barChartCategory *categ)
 /* Display category color and label */
 {
 char buf[256];
 safef(buf, sizeof(buf), "<td class='bcColorPatch' bgcolor=#%06x></td>"
@@ -147,58 +148,83 @@
 safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_MAX_LIMIT);
 int viewMax = cartCgiUsualInt(cart, cartVar, BAR_CHART_MAX_LIMIT_DEFAULT);
 cgiMakeIntVarWithExtra(cartVar, viewMax, 4, isLogTransform ? "disabled" : "");
 char *unit = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, "");
 printf("<span class='%s'> %s (range 0-%d)</span>\n", buf, unit, round(barChartUiMaxMedianScore()));
 }
 
 char *barChartUiGetLabel(char *database, struct trackDb *tdb)
 /* Get label for category list */
 {
 return trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_CATEGORY_LABEL, 
                                         BAR_CHART_CATEGORY_LABEL_DEFAULT);
 }
 
 struct barChartCategory *barChartUiGetCategories(char *database, struct trackDb *tdb)
-/* Get category colors and descriptions.  If barChartLabel setting contains label list, assign rainbow colors.
- * O/w look for a table naed track+Category, and use labels and colors there */
+/* Get category colors and descriptions.  Use barChartColors setting if present.
+   If not, if there is a barChartBars setting, assign rainbow colors.
+ * O/w look for a table naed track+Category, and use labels and colors there 
+ * TODO: Consider removing table code */
 {
 struct barChartCategory *categs = NULL;
 char *words[BAR_CHART_MAX_CATEGORIES];
+char *colorWords[BAR_CHART_MAX_CATEGORIES];
 char *labels = trackDbSettingClosestToHome(tdb, BAR_CHART_CATEGORY_LABELS);
+char *colors = trackDbSettingClosestToHome(tdb, BAR_CHART_CATEGORY_COLORS);
 struct barChartCategory *categ = NULL;
 
-if (!labels)
+if (labels == NULL)
     {
     categs = barChartGetCategories(database, tdb->table);
     }
 else
     {
+    struct rgbColor *rainbow;
     int count = chopLine(cloneString(labels), words);
-    struct rgbColor *rainbow = getRainbow(&saturatedRainbowAtPos, count);
+    if (colors == NULL)
+        rainbow = getRainbow(&saturatedRainbowAtPos, count);
+    else
+        {
+        int colorCount = chopLine(cloneString(colors), colorWords);
+        if (colorCount != count)
+            warn("barChart track %s mismatch between label (%d)  and color (%d) settings", 
+                    tdb->track, count, colorCount);
+        }
     int i;
     char buf[6];
     for (i=0; i<count; i++)
         {
         AllocVar(categ);
         categ->id = i;
         safef(buf, sizeof buf, "%d", i);
         categ->name = cloneString(buf);
         categ->label = words[i];
+        if (colors)
+            {
+            unsigned rgb;
+            if (htmlColorForName(colorWords[i], &rgb))
+                categ->color = rgb;
+            else
+                warn("barChart track %s unknown color %s. Must be one of %s\n",
+                        tdb->track, colorWords[i], slNameListToString(htmlColorNames(),','));
+            }
+        else
+            {
             categ->color = ((rainbow[i].r & 0xff)<<16) + 
                         ((rainbow[i].g & 0xff)<<8) + 
                         ((rainbow[i].b & 0xff));
+            }
         slAddHead(&categs, categ);
         }
     slReverse(&categs);
     }
 return categs;
 }
 
 struct barChartCategory *barChartUiGetCategoryById(int id, char *database, 
                                                         struct trackDb *tdb)
 /* Get category info by id */
 {
 struct barChartCategory *categ;
 struct barChartCategory *categs = barChartUiGetCategories(database, tdb);
 // TODO: consider making this more efficient
 for (categ = categs; categ != NULL; categ = categ->next)