3c2afd674ec5ab0ddbc9695caecb1965c93c021a kate Thu Jan 15 13:34:45 2015 -0800 Support for computing track priorities by subtrack color in hgTrackDb diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 38b1497..34d4e8c 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -3066,30 +3066,44 @@ { int ix; for (ix=0;ixcount;ix++) { if (sameString(name,membership->subgroups[ix])) { if (value != NULL) *value = cloneString(membership->membership[ix]); return TRUE; } } } return FALSE; } +static char *subtrackColorToCompare(struct trackDb *subtrack) +/* Convert RGB color to string with scaled hue, suitable for alpha sort */ +{ +struct rgbColor rgbColor; +rgbColor.r = subtrack->colorR; +rgbColor.g = subtrack->colorG; +rgbColor.b = subtrack->colorB; +struct hslColor hslColor = mgRgbToHsl(rgbColor); +int hue = hslColor.h * 10; +char buf[5]; +safef(buf, 5, "%04d", hue); +return cloneString(buf); +} + boolean subgroupFindTitle(struct trackDb *parentTdb, char *name,char **value) // looks for a a subgroup matching the name and returns the title if found { if (value != (void*)NULL) *value = NULL; members_t*members=subgroupMembersGet(parentTdb, name); //const members_t *members = membersFindByTag(parentTdb,name); // Can't use because of dimension dependence if (members==NULL) return FALSE; *value = cloneString(members->groupTitle); //subgroupMembersFree(&members); return TRUE; } @@ -3098,31 +3112,30 @@ { if (value && *value) freez(value); } boolean subgroupRequired(char *value) /* Returns whether subgroup much be specified for each track. * Generally true. Exceptions are specially defined subgroups */ { return differentString(SUBTRACK_COLOR_SUBGROUP, value); } #define SORT_ON_TRACK_NAME "trackName" #define SORT_ON_RESTRICTED "dateUnrestricted" - sortOrder_t *sortOrderGet(struct cart *cart,struct trackDb *parentTdb) // Parses any list sort order instructions for parent of subtracks (from cart or trackDb) // Some trickiness here. sortOrder->sortOrder is from cart (changed by user action), // as is sortOrder->order, But columns are in original tdb order (unchanging)! // However, if cart is null, all is from trackDb.ra { int ix; char *setting = trackDbSetting(parentTdb, "sortOrder"); if (setting == NULL) // Must be in trackDb or not a sortable table return NULL; sortOrder_t *sortOrder = needMem(sizeof(sortOrder_t)); sortOrder->htmlId = needMem(strlen(parentTdb->track)+15); safef(sortOrder->htmlId, (strlen(parentTdb->track)+15), "%s.sortOrder", parentTdb->track); char *cartSetting = NULL; @@ -3217,54 +3230,65 @@ if (sortOrder && *sortOrder) { int ix; for (ix=0;ix<(*sortOrder)->count;ix++) { subgroupFree(&((*sortOrder)->title[ix])); } freeMem((*sortOrder)->sortOrder); freeMem((*sortOrder)->htmlId); freeMem((*sortOrder)->column); freeMem((*sortOrder)->forward); freeMem((*sortOrder)->order); freeMem((*sortOrder)->setting); freez(sortOrder); } } + + sortableTdbItem *sortableTdbItemCreate(struct trackDb *tdbChild,sortOrder_t *sortOrder) // creates a sortable tdb item struct, given a child tdb and its parent's sort table // Errors in interpreting a passed in sortOrder will return NULL { sortableTdbItem *item = NULL; if (tdbChild == NULL || tdbChild->shortLabel == NULL) return NULL; AllocVar(item); item->tdb = tdbChild; if (sortOrder != NULL) // Add some sort buttons { int sIx=0; for (sIx=sortOrder->count - 1;sIx>=0;sIx--) // walk backwards to ensure sort order in columns { sortColumn *column = NULL; AllocVar(column); column->fwd = sortOrder->forward[sIx]; - if (!subgroupFind(item->tdb,sortOrder->column[sIx],&(column->value))) + char *col = sortOrder->column[sIx]; + if (!subgroupFind(item->tdb, col, &(column->value))) { - char *setting = trackDbSetting(item->tdb,sortOrder->column[sIx]); + if (sameString(col, SUBTRACK_COLOR_SUBGROUP)) + { + // convert RGB color to hue so alpha sort can compare + column->value = subtrackColorToCompare(tdbChild); + } + else + { + char *setting = trackDbSetting(item->tdb,col); if (setting != NULL) column->value = cloneString(setting); // No subgroup, assume there is a matching setting (eg longLabel) } + } if (column->value != NULL) slAddHead(&(item->columns), column); else { freez(&column); if (item->columns != NULL) slFreeList(&(item->columns)); freeMem(item); return NULL; // sortOrder setting doesn't match items to be sorted. } } } return item; } @@ -4343,57 +4367,55 @@ { #define SUBTRACK_CFG_WRENCH "\n" printf(SUBTRACK_CFG_WRENCH,(visibleCB ? "":" disabled"),subtrack->track); } } printf(""); // If sortable, then there must be a column per sortable dimension if (sortOrder != NULL) { int sIx=0; for (sIx=0; sIx count; sIx++) { - ix = stringArrayIx(sortOrder->column[sIx], membership->subgroups, membership->count); + char *col = sortOrder->column[sIx]; + ix = stringArrayIx(col, membership->subgroups, membership->count); // TODO: Sort needs to expand from subGroups to labels as well if (ix >= 0) { char *titleRoot=NULL; - if (cvTermIsEmpty(sortOrder->column[sIx],membership->titles[ix])) + if (cvTermIsEmpty(col, membership->titles[ix])) titleRoot = cloneString("  "); else titleRoot = labelRoot(membership->titles[ix],NULL); // Each sortable column requires hidden goop (in the "abbr" field currently) // which is the actual sort on value printf(" ", - subtrack->track,sortOrder->column[sIx],membership->membership[ix]); + subtrack->track, col, membership->membership[ix]); printf("%s",titleRoot); puts(""); freeMem(titleRoot); } - else if (sameString(sortOrder->column[sIx], SUBTRACK_COLOR_SUBGROUP)) + else if (sameString(col, SUBTRACK_COLOR_SUBGROUP)) { - struct rgbColor rgbColor; - rgbColor.r = subtrack->colorR; - rgbColor.g = subtrack->colorG; - rgbColor.b = subtrack->colorB; - struct hslColor hslColor = mgRgbToHsl(rgbColor); - int hue = hslColor.h * 10; - printf("    ", - subtrack->track, sortOrder->column[sIx], hue, rgbColor.r, rgbColor.g, rgbColor.b); + char *hue = subtrackColorToCompare(subtrack); + printf("" + "    ", + subtrack->track, col, hue, + subtrack->colorR, subtrack->colorG, subtrack->colorB); } } } else // Non-sortable tables do not have sort by columns but will display a short label { // (which may be a configurable link) printf(" "); hierarchy_t *hierarchy = hierarchySettingGet(parentTdb); indentIfNeeded(hierarchy,membership); hierarchyFree(&hierarchy); printf("%s",subtrack->shortLabel); puts(""); } // The long label column (note that it may have a metadata dropdown) printf(" %s", subtrack->longLabel);