06257075cb492d423ed0c96a749ea64e2fe96f61 kate Wed Feb 1 15:51:33 2017 -0800 Further work on details page for barchart. refs #18736 diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c index 21aac9b..0fde3db 100644 --- src/hg/hgTracks/barChartTrack.c +++ src/hg/hgTracks/barChartTrack.c @@ -1,115 +1,115 @@ /* barGraph tracks - display a colored bargraph across each region in a file */ /* Copyright (C) 2015 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "hgTracks.h" #include "bed.h" #include "hvGfx.h" #include "spaceSaver.h" -#include "rainbow.h" #include "barChartBed.h" #include "barChartCategory.h" #include "barChartUi.h" struct barChartTrack /* Track info */ { boolean noWhiteout; /* Suppress whiteout of graph background (allow highlight, blue lines) */ double maxMedian; /* Maximum median across all categories */ struct rgbColor *colors; /* Colors for all categories */ boolean doLogTransform; /* Log10(x+1) */ struct barChartCategory *categories; /* Cache category names, colors */ struct hash *categoryFilter; /* NULL out excluded factors */ }; struct barChartItem /* BED item plus computed values for display */ { struct barChartItem *next; /* Next in singly linked list */ struct barChartBed *bed; /* Item coords, name, exp count and values */ int height; /* Item height in pixels */ }; /***********************************************/ /* Cache category info */ +/* TODO: multi-thread caching by track name */ -struct barChartCategory *getCategories(char *track) +struct barChartCategory *getCategories(struct track *tg) /* Get and cache category info */ { static struct barChartCategory *categs = NULL; if (!categs) - categs = barChartGetCategories(database, track); + categs = barChartUiGetCategories(database, tg->tdb); return categs; } -int getCategoryCount(char *track) +int getCategoryCount(struct track *tg) /* Get and cache the number of categories */ { static int categCount = 0; if (!categCount) - categCount = slCount(getCategories(track)); + categCount = slCount(getCategories(tg)); return categCount; } /* TODO: Do we need names ? */ -char *getCategoryName(char *track, int id) +char *getCategoryName(struct track *tg, int id) /* Get category name from id, cacheing */ { static char **categNames = NULL; struct barChartCategory *categ; -int count = getCategoryCount(track); +int count = getCategoryCount(tg); if (!categNames) { - struct barChartCategory *categs = getCategories(track); + struct barChartCategory *categs = getCategories(tg); AllocArray(categNames, count); for (categ = categs; categ != NULL; categ = categ->next) categNames[categ->id] = cloneString(categ->name); } if (id >= count) errAbort("Bar chart track: can't find id %d\n", id); return categNames[id]; } -char *getCategoryLabel(char *track, int id) +char *getCategoryLabel(struct track *tg, int id) /* Get category descriptive label from id, cacheing */ { static char **categLabels = NULL; struct barChartCategory *categ; -int count = getCategoryCount(track); +int count = getCategoryCount(tg); if (!categLabels) { - struct barChartCategory *categs = getCategories(track); + struct barChartCategory *categs = getCategories(tg); AllocArray(categLabels, count); for (categ = categs; categ != NULL; categ = categ->next) categLabels[categ->id] = cloneString(categ->label); } if (id >= count) errAbort("Bar chart track: can't find id %d\n", id); return categLabels[id]; } -struct rgbColor *getCategoryColors(char *track) +struct rgbColor *getCategoryColors(struct track *tg) /* Get RGB colors from category table */ { -struct barChartCategory *categs = getCategories(track); +struct barChartCategory *categs = getCategories(tg); struct barChartCategory *categ = NULL; int count = slCount(categs); struct rgbColor *colors; AllocArray(colors, count); int i = 0; for (categ = categs; categ != NULL; categ = categ->next) { // TODO: reconcile colors[i] = (struct rgbColor){.r=COLOR_32_BLUE(categ->color), .g=COLOR_32_GREEN(categ->color), .b=COLOR_32_RED(categ->color)}; //colors[i] = mgColorIxToRgb(NULL, categ->color); i++; } return colors; } @@ -139,31 +139,31 @@ if (winSize < WIN_MAX_GRAPH) return MAX_BAR_CHART_MODEL_HEIGHT; else if (winSize < WIN_MED_GRAPH) return MED_BAR_CHART_MODEL_HEIGHT; else return MIN_BAR_CHART_MODEL_HEIGHT; } static int barChartItemHeight(struct track *tg, void *item); 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->table); +extras->categories = getCategories(tg); extras->categoryFilter = hashNew(0); 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) { struct slName *name; for (name = selectedValues; name != NULL; name = name->next) hashAdd(extras->categoryFilter, name->name, name->name); return; } } /* no filter */ for (categ = extras->categories; categ != NULL; categ = categ->next) @@ -238,48 +238,32 @@ extras->doLogTransform = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_LOG_TRANSFORM, BAR_CHART_LOG_TRANSFORM_DEFAULT); extras->maxMedian = barChartUiMaxMedianScore(); extras->noWhiteout = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_NO_WHITEOUT, BAR_CHART_NO_WHITEOUT_DEFAULT); /* Get bed (names and all-sample category median scores) in range */ char *filter = getScoreFilterClause(cart, tg->tdb, NULL); bedLoadItemWhere(tg, tg->table, filter, (ItemLoader)barChartBedLoad); /* Create itemInfo items with BED and geneModels */ struct barChartItem *itemInfo = NULL, *list = NULL; struct barChartBed *bed = (struct barChartBed *)tg->items; /* Load category colors */ -#ifdef COLOR_SCHEME -char *colorScheme = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_COLORS, - BAR_CHART_COLORS_DEFAULT); -#else -char *colorScheme = BAR_CHART_COLORS_DEFAULT; -#endif -if (sameString(colorScheme, BAR_CHART_COLORS_USER)) - { - extras->colors = getCategoryColors(tg->table); - } -else - { - if (bed) - { - int expCount = bed->expCount; - extras->colors = getRainbow(&saturatedRainbowAtPos, expCount); - } - } +extras->colors = getCategoryColors(tg); + filterCategories(tg); while (bed != NULL) { AllocVar(itemInfo); itemInfo->bed = bed; slAddHead(&list, itemInfo); bed = bed->next; itemInfo->bed->next = NULL; itemInfo->height = barChartItemHeight(tg, itemInfo); } slReverse(&list); tg->items = list; } @@ -394,31 +378,31 @@ } return valToHeight(useVal, useMax, barChartMaxHeight(), doLogTransform); } static int barChartHeight(struct track *tg, struct barChartItem *itemInfo) /* Determine height in pixels of graph. This will be the box for category with highest value */ { struct barChartBed *bed = (struct barChartBed *)itemInfo->bed; struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; int i; double maxExp = 0.0; int expCount = bed->expCount; double expScore; for (i=0; i<expCount; i++) { - if (!filterCategory(tg, getCategoryName(tg->table, i))) + if (!filterCategory(tg, getCategoryName(tg, i))) continue; expScore = bed->expScores[i]; maxExp = max(maxExp, expScore); } double viewMax = (double)cartUsualIntClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_MAX_LIMIT, BAR_CHART_MAX_LIMIT_DEFAULT); // TODO: add trackDb settings for MAX_LIMIT values ? double maxMedian = ((struct barChartTrack *)tg->extraUiData)->maxMedian; return valToClippedHeight(maxExp, maxMedian, viewMax, barChartMaxHeight(), extras->doLogTransform); } static void drawGraphBox(struct track *tg, struct barChartItem *itemInfo, struct hvGfx *hvg, int x, int y) /* Draw white background for graph */ { Color lighterGray = MAKECOLOR_32(0xF3, 0xF3, 0xF3); @@ -652,31 +636,31 @@ safef(buf, sizeof buf, "%s %s", bed->name, maxTissue); int x1, x2; getItemX(geneStart, geneEnd, &x1, &x2); int width = max(1, x2-x1); mapBoxHc(hvg, geneStart, geneEnd, x1, y, width, height, tg->track, mapItemName, buf); return; } int topGraphHeight = barChartHeight(tg, itemInfo); topGraphHeight = max(topGraphHeight, tl.fontHeight); // label int yZero = topGraphHeight + y - 1; // yZero is bottom of graph int x1 = insideX; // add maps to category bars -struct barChartCategory *categs = getCategories(tg->table); +struct barChartCategory *categs = getCategories(tg); struct barChartCategory *categ = NULL; int barWidth = barChartBarWidth(); int padding = barChartPadding(); double maxMedian = ((struct barChartTrack *)tg->extraUiData)->maxMedian; int graphX = barChartX(bed); if (graphX < 0) return; // x1 is at left of graph x1 = insideX + graphX; double viewMax = (double)cartUsualIntClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_MAX_LIMIT, BAR_CHART_MAX_LIMIT_DEFAULT); for (categ = categs; categ != NULL; categ = categ->next, i++)