e2467a639cc1e98174ffbd9d0da399b3b75bc9ae markd Thu Jul 26 21:33:38 2012 -0700 highlighting by attribute functionality for GENCODE diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 1750298..98ccd2f 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -3318,63 +3318,63 @@ if (first) *first = strtod(a,NULL); freeMem(a); } if (b!=NULL) { if (second) *second = strtod(b,NULL); freeMem(b); } return TRUE; } return FALSE; } -filterBy_t *filterBySetGet(struct trackDb *tdb, struct cart *cart, char *name) +filterBy_t *filterBySetGetGuts(struct trackDb *tdb, struct cart *cart, char *name, char *subName, char *settingName) // Gets one or more "filterBy" settings (ClosestToHome). returns NULL if not found { filterBy_t *filterBySet = NULL; -char *setting = trackDbSettingClosestToHome(tdb, FILTER_BY); +char *setting = trackDbSettingClosestToHome(tdb, settingName); if (setting == NULL) return NULL; if ( name == NULL ) name = tdb->track; setting = cloneString(setting); char *filters[10]; // multiple filterBys are delimited by space but spaces inside filter can be protected "by quotes" int filterCount = chopByWhiteRespectDoubleQuotes(setting, filters, ArraySize(filters)); int ix; for (ix=0;ixcolumn = filter; filter += strlen(filter) + 1; first = strchr(filter,'='); if (first != NULL) *first = '\0'; else - errAbort("filterBySetGet() expected '=' divider between table column and options list."); + errAbort("filterBySetGet() expected '=' divider between table column and options list: %s", filters[ix]); filterBy->title = strSwapChar(filter,'_',' '); // Title does not have underscores filter += strlen(filter) + 1; // Are values indexes to the string titles? if (filter[0] == '+') { filter += 1; filterBy->useIndex = TRUE; } // Now set up each of the values which may have 1-3 parts (value|label{style}) // the slName list will have the 3 parts delimited by null value\0label\0style\0 stripString(filter, "\""); // Remove any double quotes now and chop by commmas filterBy->slValues = slNameListFromComma(filter); struct slName *val = filterBy->slValues; @@ -3417,49 +3417,61 @@ "or none do."); *chipper++ = 0; // The label is found inside filters->svValues as the next string strSwapChar(chipper,'_',' '); // Title does not have underscores } else if (filterBy->valueAndLabel) errAbort("filterBy values either all have labels in form of value|label " "or none do."); } } slAddTail(&filterBySet,filterBy); // Keep them in order (only a few) if (cart != NULL) { char suffix[256]; - safef(suffix, sizeof(suffix), "filterBy.%s", filterBy->column); + safef(suffix, sizeof(suffix), "%s.%s", subName, filterBy->column); boolean parentLevel = isNameAtParentLevel(tdb,name); if (cartLookUpVariableClosestToHome(cart,tdb,parentLevel,suffix,&(filterBy->htmlName))) { filterBy->slChoices = cartOptionalSlNameList(cart,filterBy->htmlName); freeMem(filterBy->htmlName); } } // Note: cannot use found name above because that may be at a higher (composite/view) level int len = strlen(name) + strlen(filterBy->column) + 15; filterBy->htmlName = needMem(len); - safef(filterBy->htmlName, len, "%s.filterBy.%s", name,filterBy->column); + safef(filterBy->htmlName, len, "%s.%s.%s", name,subName,filterBy->column); } freeMem(setting); return filterBySet; } +filterBy_t *filterBySetGet(struct trackDb *tdb, struct cart *cart, char *name) +/* Gets one or more "filterBy" settings (ClosestToHome). returns NULL if not found */ +{ +return filterBySetGetGuts(tdb, cart, name, "filterBy", FILTER_BY); +} + +filterBy_t *highlightBySetGet(struct trackDb *tdb, struct cart *cart, char *name) +/* Gets one or more "highlightBy" settings (ClosestToHome). returns NULL if not found */ +{ +return filterBySetGetGuts(tdb, cart, name, "highlightBy", HIGHLIGHT_BY); +} + void filterBySetFree(filterBy_t **filterBySet) // Free a set of filterBy structs { if (filterBySet != NULL) { while (*filterBySet != NULL) { filterBy_t *filterBy = slPopHead(filterBySet); if (filterBy->slValues != NULL) slNameFreeList(filterBy->slValues); if (filterBy->slChoices != NULL) slNameFreeList(filterBy->slChoices); if (filterBy->htmlName != NULL) freeMem(filterBy->htmlName); freeMem(filterBy->column); @@ -3493,31 +3505,31 @@ } if (dyStringLen(dyClause) == 0) { dyStringFree(&dyClause); return NULL; } if (count > 1) dyStringPrintf(dyClause, ")"); return dyStringCannibalize(&dyClause); } char *filterByClause(filterBy_t *filterBy) // returns the SQL where clause for a single filterBy struct { -if ((filterBy->slChoices == NULL) || (slNameInList(filterBy->slChoices,"All"))) +if (filterByAllChosen(filterBy)) return NULL; else return filterByClauseStd(filterBy); } struct dyString *dyAddFilterByClause(struct cart *cart, struct trackDb *tdb, struct dyString *extraWhere,char *column, boolean *and) // creates the where clause condition to support a filterBy setting. // Format: filterBy column:Title=value,value [column:Title=value|label,value|label,value|label]) // filterBy filters are multiselect's so could have multiple values selected. // thus returns the "column1 in (...) and column2 in (...)" clause. // if 'column' is provided, and there are multiple filterBy columns, only the named column's // clause is returned. // The 'and' param and dyString in/out allows stringing multiple where clauses together { @@ -3560,72 +3572,106 @@ if (notFirst) dyStringPrintf(dyClause, " AND "); dyStringAppend(dyClause, clause); freeMem(clause); notFirst = TRUE; } } if (dyStringLen(dyClause) == 0) { dyStringFree(&dyClause); return NULL; } return dyStringCannibalize(&dyClause); } -void filterBySetCfgUi(struct cart *cart, struct trackDb *tdb, - filterBy_t *filterBySet, boolean onOneLine) -// Does the UI for a list of filterBy structure +void filterBySetCfgUiOption(filterBy_t *filterBy, struct slName *slValue, int ix) +/* output one option for filterBy UI */ +{ +char varName[32]; +char *label = NULL; +char *name = NULL; +if (filterBy->useIndex) + { + safef(varName, sizeof(varName), "%d",ix); + name = varName; + label = slValue->name; + } +else + { + label = (filterBy->valueAndLabel? slValue->name + strlen(slValue->name)+1: slValue->name); + name = slValue->name; + } +printf("slChoices != NULL && slNameInList(filterBy->slChoices,name)) + printf(" SELECTED"); +if (filterBy->useIndex || filterBy->valueAndLabel) + printf(" value='%s'",name); +if (filterBy->styleFollows) + { + char *styler = label + strlen(label)+1; + if (*styler != '\0') + { + if (*styler == '#') // Legacy: just the color that follows + printf(" style='color: %s;'",styler); + else + printf(" style='%s'",styler); + } + } +printf(">%s\n",label); +} + +void filterBySetCfgUiGuts(struct cart *cart, struct trackDb *tdb, + filterBy_t *filterBySet, boolean onOneLine, + char *filterTypeTitle, char *selectIdPrefix, char *allLabel) +// Does the UI for a list of filterBy structure for either filterBy or highlightBy controls { if (filterBySet == NULL) return; #define FILTERBY_HELP_LINK "help" int count = slCount(filterBySet); if (count == 1) puts(""); else printf("Filter items by: (select multiple categories and items - %s)" "
\n",FILTERBY_HELP_LINK); filterBy_t *filterBy = NULL; if (cartOptionalString(cart, "ajax") == NULL) { webIncludeResourceFile("ui.dropdownchecklist.css"); jsIncludeFile("ui.dropdownchecklist.js",NULL); jsIncludeFile("ddcl.js",NULL); } int ix=0; -for (filterBy = filterBySet;filterBy != NULL; filterBy = filterBy->next) +for(filterBy = filterBySet;filterBy != NULL; filterBy = filterBy->next, ix++) { puts("
"); if (count == 1) - printf("Filter by %s (select multiple items - %s)", - filterBy->title,FILTERBY_HELP_LINK); + printf("%s by %s (select multiple items - %s)",filterTypeTitle,filterBy->title,FILTERBY_HELP_LINK); else printf("%s",filterBy->title); printf("
\n"); // TODO: columnCount (Number of filterBoxes per row) should be configurable through tdb setting - #define FILTER_BY_FORMAT "
\n" + printf(FILTER_BY_FORMAT,selectIdPrefix,ix,filterBy->htmlName); + + // value is always "All", even if label is different, to simplify javascript code + printf("%s\n", (filterByAllChosen(filterBy)?" SELECTED":""), allLabel); struct slName *slValue; int ix=1; for (slValue=filterBy->slValues;slValue!=NULL;slValue=slValue->next,ix++) { char varName[32]; char *label = NULL; char *name = NULL; if (filterBy->useIndex) { safef(varName, sizeof(varName), "%d",ix); name = varName; label = slValue->name; } else @@ -3644,32 +3690,44 @@ char *styler = label + strlen(label)+1; if (*styler != '\0') { if (*styler == '#') // Legacy: just the color that follows printf(" style='color: %s;'",styler); else printf(" style='%s'",styler); } } printf(">%s\n",label); } } printf("\n"); puts("
"); +} -return; +void filterBySetCfgUi(struct cart *cart, struct trackDb *tdb, + filterBy_t *filterBySet, boolean onOneLine) +/* Does the filter UI for a list of filterBy structure */ +{ +filterBySetCfgUiGuts(cart, tdb, filterBySet, onOneLine, "Filter", "fbc", "All"); +} + +void highlightBySetCfgUi(struct cart *cart, struct trackDb *tdb, + filterBy_t *filterBySet, boolean onOneLine) +/* Does the highlight UI for a list of filterBy structure */ +{ +filterBySetCfgUiGuts(cart, tdb, filterBySet, onOneLine, "Highlight", "hbc", "None"); } #define COLOR_BG_DEFAULT_IX 0 #define COLOR_BG_ALTDEFAULT_IX 1 #define DIVIDING_LINE "
\n" #define DIVIDER_PRINT(color) printf(DIVIDING_LINE,COLOR_BG_DEFAULT,(color)) static char *checkBoxIdMakeForTrack(struct trackDb *tdb,members_t** dims,int dimMax, membership_t *membership) // Creates an 'id' string for subtrack checkbox in style that matrix understand: // "cb_dimX_dimY_view_cb" { int len = strlen(tdb->track) + 10; char *id = needMem(len); @@ -5710,30 +5768,37 @@ cgiMakeCheckBox(varName, nmdDefault); } if (!sameString(tdb->track, "tigrGeneIndex") && !sameString(tdb->track, "ensGeneNonCoding") && !sameString(tdb->track, "encodeGencodeRaceFrags")) baseColorDropLists(cart, tdb, name); filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); if (filterBySet != NULL) { printf("
"); filterBySetCfgUi(cart,tdb,filterBySet,FALSE); filterBySetFree(&filterBySet); } +filterBy_t *highlightBySet = highlightBySetGet(tdb,cart,name); +if (highlightBySet != NULL) + { + printf("
"); + highlightBySetCfgUi(cart,tdb,highlightBySet,FALSE); + filterBySetFree(&highlightBySet); + } cfgEndBox(boxed); } static boolean isSpeciesOn(struct cart *cart, struct trackDb *tdb, char *species, char *option, int optionSize, boolean defaultState) /* check the cart to see if species is turned off or on (default is defaultState) */ { boolean parentLevel = isNameAtParentLevel(tdb,option); if (*option == '\0') safef(option, optionSize, "%s.%s", tdb->track, species); else { char *suffix = option + strlen(option); int suffixSize = optionSize - strlen(option); safef(suffix,suffixSize,".%s",species);