7537f40b289d8ff6b05f41f66e683d97a130b794
kate
Tue Nov 17 12:24:52 2020 -0800
Rough cut adding category file setting to barChart. refs #22075
diff --git src/hg/lib/barChartUi.c src/hg/lib/barChartUi.c
index 255b10b..3855f22 100644
--- src/hg/lib/barChartUi.c
+++ src/hg/lib/barChartUi.c
@@ -1,22 +1,23 @@
/* 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 "net.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 */
static boolean isPopup = FALSE;
/* Convenience functions for category filter controls */
@@ -144,93 +145,169 @@
{
char cartVar[1024];
char buf[512];
safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_LOG_TRANSFORM);
boolean isLogTransform = cartCgiUsualBoolean(cart, cartVar, BAR_CHART_LOG_TRANSFORM_DEFAULT);
safef(buf, sizeof buf, "%sViewLimitsMaxLabel %s", track, isLogTransform ? "disabled" : "");
printf("View limits maximum:\n", buf);
safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_MAX_VIEW_LIMIT);
int viewMax = cartCgiUsualInt(cart, cartVar, BAR_CHART_MAX_VIEW_LIMIT_DEFAULT);
cgiMakeIntVarWithExtra(cartVar, viewMax, 4, isLogTransform ? "disabled" : "");
char *unit = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, "");
printf(" %s (range 0-%d)\n", buf, unit,
round(barChartUiMaxMedianScore(tdb)));
}
+// TODO: libify
+static boolean isUrl(char *url)
+{
+return ((startsWith("http://", url)
+ || startsWith("https://", url)
+ || startsWith("ftp://", url)));
+}
+
struct barChartCategory *barChartUiGetCategories(char *database, struct trackDb *tdb)
-/* 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
+/* Get category colors and descriptions.
+ 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.
*/
{
-struct barChartCategory *categs = NULL;
+int count = 0;
+struct slName *labels = NULL, *colors = NULL;
+char *fileOrUrl = trackDbSetting(tdb, BAR_CHART_CATEGORY_URL);
+if (isEmpty(fileOrUrl))
+ {
+ // use trackDb settings for labels and perhaps colors
+ char *labelSetting = trackDbSetting(tdb, BAR_CHART_CATEGORY_LABELS);
+ if (isEmpty(labelSetting))
+ {
+ errAbort("barChart track %s missing required setting: %s or %s\n",
+ tdb->track, BAR_CHART_CATEGORY_LABELS, BAR_CHART_CATEGORY_URL);
+ }
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;
+ count = chopLine(cloneString(labelSetting), words);
+ labels = slNameListFromStringArray(words, count);
+ char *colorSetting = trackDbSetting(tdb, BAR_CHART_CATEGORY_COLORS);
+ if (isNotEmpty(colorSetting))
+ {
+ int ct = chopLine(cloneString(colorSetting), words);
+ if (ct != count)
+ errAbort("barChart track %s settings mismatch: %s (%d) and %s (%d)\n",
+ tdb->track, BAR_CHART_CATEGORY_LABELS, count, BAR_CHART_CATEGORY_COLORS, ct);
+ colors = slNameListFromStringArray(words, count);
+ }
+ }
+else
+ {
+ // use file for labels and perhaps colors
+ struct lineFile *lf = NULL;
+
+#ifdef TODO
+// TODO: protect against network error
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
+ {
+ if (isUrl(fileOrUrl))
+ {
+ lf = netLineFileOpen(fileOrUrl);
+ else
+ lf = lineFileMayOpen(fileOrUrl, TRUE);
+ }
+ }
+errCatchEnd(errCatch);
+if (errCatch->gotError)
+ {
+ if (isNotEmpty(errCatch->message->string))
+ warn("unable to open %s: %s", fileOrUrl, errCatch->message->string);
+ }
+errCatchFree(&errCatch);
+#endif
-if (labels == NULL)
+ if (isUrl(fileOrUrl))
+ lf = netLineFileOpen(fileOrUrl);
+ else
+ lf = lineFileMayOpen(fileOrUrl, TRUE);
+ char *line = NULL;
+ int cols = 0;
+ while (lineFileNextReal(lf, &line))
+ {
+ char *words[2];
+ int wordCount = chopTabs(line, words);
+ if (cols)
{
- errAbort("barChart track %s missing required %s setting\n", tdb->track, BAR_CHART_CATEGORY_LABELS);
+ if (wordCount != cols)
+ errAbort("barChart track %s category file %s expecting %d words, got %d",
+ tdb->track, fileOrUrl, cols, wordCount);
}
else
{
- int count = chopLine(cloneString(labels), words);
- struct rgbColor *rainbow = getRainbow(&saturatedRainbowAtPos, count);
- if (colors != NULL)
+ cols = wordCount;
+ }
+ slAddHead(&labels, slNameNew(words[0]));
+ if (wordCount == 2)
+ slAddHead(&colors, slNameNew(words[1]));
+ count++;
+ }
+ slReverse(&labels);
+ slReverse(&colors);
+ }
+
+// populate categories
+struct barChartCategory *categs = NULL, *categ = NULL;
+struct rgbColor *rainbow = NULL;
+if (!colors)
{
- 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);
+ rainbow = getRainbow(&saturatedRainbowAtPos, count);
}
int i;
char buf[6];
- for (i=0; iid = i;
safef(buf, sizeof buf, "%d", i);
categ->name = cloneString(buf);
- categ->label = words[i];
+ categ->label = labels->name;
if (colors)
{
unsigned rgb;
- char *color = colorWords[i];
+ char *color = colors->name;
if (htmlColorForCode(color, &rgb))
{
categ->color = rgb;
}
else if (htmlColorForName(color, &rgb))
{
categ->color = rgb;
}
else
warn("barChart track %s unknown color %s. Must be one of %s\n",
tdb->track, color, slNameListToString(htmlColorNames(),','));
}
else
{
categ->color = ((rainbow[i].r & 0xff)<<16) +
((rainbow[i].g & 0xff)<<8) +
((rainbow[i].b & 0xff));
}
slAddHead(&categs, categ);
+ labels = labels->next;
+ if (colors)
+ colors = colors->next;
}
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);
for (categ = categs; categ != NULL; categ = categ->next)
if (categ->id == id)
return categ;
return NULL;
}