2755debd56fbb1a69333d485b22079c1a8a7495a kate Wed Jan 27 11:49:42 2016 -0800 Special handling of popup configuration for GTEx track (see RM #15873 for why). refs #155645 diff --git src/hg/lib/gtexUi.c src/hg/lib/gtexUi.c index 34d7d52..611e290 100644 --- src/hg/lib/gtexUi.c +++ src/hg/lib/gtexUi.c @@ -8,56 +8,55 @@ #include "hui.h" #include "trackDb.h" #include "jsHelper.h" #include "gtexTissue.h" #include "gtexUi.h" #define SYSTEM_BRAIN "Brain" #define SYSTEM_REPRODUCTIVE "Reproductive" #define SYSTEM_GASTRO "Digestive" #define SYSTEM_ENDOCRINE "Endocrine" #define SYSTEM_CARDIO "Cardiovascular" #define SYSTEM_OTHER "Other" -static void initTissueTableStyle() -{ -puts("<style>\n" - "#tissueTable th, #tissueTable td {\n" - "font-size: 75%;\n" - "}\n" - "</style>\n"); -} +/* Restrict features on right-click (popup) version */ +static boolean isPopup = FALSE; + +/* Convenience functions for tissue filter controls */ static char *makeTissueColorPatch(struct gtexTissue *tis) +/* Display a box colored by defined tissue color */ { char buf[256]; safef(buf, sizeof(buf), "<td style='width:10px;' bgcolor=%X></td>", tis->color); return(cloneString(buf)); } static char *makeTissueLabel(struct gtexTissue *tis) { +/* Display tissue color and label */ char buf[256]; safef(buf, sizeof(buf), "<td style='width:10px;' bgcolor=%X></td>" "<td> %s</td>", tis->color, tis->description); return(cloneString(buf)); } static char *getSystem(struct gtexTissue *tis) +/* Rough categorization of tissues for filter presentation */ { if (startsWith("brain", tis->name)) return(SYSTEM_BRAIN); else if (sameString(tis->name, "uterus") || sameString(tis->name, "testis") || sameString(tis->name, "vagina") || sameString(tis->name, "prostate") || sameString(tis->name, "ovary") || sameString(tis->name, "breastMamTissue") || sameString(tis->name, "ectocervix") || sameString(tis->name, "endocervix") || sameString(tis->name, "fallopianTube")) return(SYSTEM_REPRODUCTIVE); else if (startsWith("esophagus", tis->name) || startsWith("colon", tis->name) || sameString(tis->name, "stomach") || sameString("smallIntestine", tis->name) || sameString("pancreas", tis->name) || sameString("liver", tis->name)) return(SYSTEM_GASTRO); else if (sameString("adrenalGland", tis->name) || sameString("pituitary", tis->name) || sameString("thyroid", tis->name)) @@ -88,127 +87,118 @@ for (i=0, tsel = tisSelects; tsel != NULL; tsel = tsel->next, i++) tisArray[i] = tsel; int col=0; int row=0; int tableColumns=3; for (i=0; i<count; i++) { int j = row + col*(count/tableColumns+1); if (j>=count) { printf("</tr><tr>"); row++; col = 0; } j = row + col*(count/tableColumns+1); + if (!isPopup) + { printf("<td><input type=checkbox name=\"%s\" value=\"%s\" %s></td>" "<td>%s</td>\n", name, tisArray[j]->name, tisArray[j]->checked ? "checked" : "", tisArray[j]->label); + } col++; } if ((i % tableColumns) != 0) while ((i++ % tableColumns) != 0) printf("<td></td>"); printf("</tr><tr><td></td></tr>\n"); } -static void makeAllTissueCheckboxes(char *name, struct gtexTissue *tissues, struct slName *checked) -{ -struct hash *checkHash = hashNew(0); -struct slName *sel; -for (sel = checked; sel != NULL; sel = sel->next) - hashAdd(checkHash, sel->name, sel->name); -puts("<table borderwidth=0><tr>"); -struct tissueSelect *tsel; -struct gtexTissue *tis; -struct tissueSelect *allTissues = NULL; -for (tis = tissues; tis != NULL; tis = tis->next) +static void initTissueTableStyle() +/* Reduce font in tissue table so more rows are visible. + * Specify some colors.*/ { - AllocVar(tsel); - tsel->name = tis->name; - tsel->label = makeTissueLabel(tis); - if (hashNumEntries(checkHash) == 0) - tsel->checked = TRUE; - else - tsel->checked = (hashLookup(checkHash, tis->name) != NULL); - slAddHead(&allTissues, tsel); - } -slReverse(&allTissues); -makeGroupCheckboxes(name, NULL, allTissues); -puts("</tr></table>"); -char buf[512]; -safef(buf, sizeof(buf), "%s%s", cgiMultListShadowPrefix(), name); -cgiMakeHiddenVar(buf, "0"); +puts("<style>\n" + "#tissueTable th, #tissueTable td {font-size: 75%;}\n" + ".notSortable {font-color: black;}\n" + "</style>\n"); } static void makeTableTissueCheckboxes(char *name, struct gtexTissue *tissues, - struct slName *checked, struct cart *cart) + struct slName *checked, struct cart *cart, char *track) { initTissueTableStyle(); char *onClick = ""; // Sortable table can't be displayed when UI is activated from right-click (popup mode) -if (!cartVarExists(cart, "ajax")) +if (!isPopup) { jsIncludeFile("hui.js", NULL); onClick = "'tableSortAtButtonPress(this);"; } struct hash *checkHash = hashNew(0); struct slName *sel; for (sel = checked; sel != NULL; sel = sel->next) hashAdd(checkHash, sel->name, sel->name); //puts("<table borderwidth=0><tr>"); puts("\n<table id='tissueTable' cellspacing='2' cellpadding='0' border='0' class='sortable'>"); /* table header */ char orderVar[256]; safef(orderVar, sizeof(orderVar), "%s.sortOrder", name); char *sortOrder = cartCgiUsualString(cart, orderVar, "tissue=+ samples=+ organ=+ system=+"); puts("\n<thead class='sortable'>"); puts("\n<tr class='sortable'>"); +char *sortableClass = isPopup ? "notSortable" : "sortable"; +if (isPopup) + { + printf("<th> <a style='color: blue; cursor: pointer; text-decoration: none' href='%s?g=%s' " + "title='Sorry you cannot select tissues from the list below. To do so, click the ?.'>?</a>", + "../cgi-bin/hgTrackUi", track); // Better to use hgTrackUiName(), but there's an issue + //with header includes, so punting for now + } +else + { printf("\n<th> <input type=hidden name='%s' class='sortOrder' value='%s'></th>\n", orderVar, sortOrder); + } puts("<th> </th>"); - -printf("<th id='tissue' class='sortable sort1' %s " - "align='left' title='Sort on tissue'> Tissue</th>", onClick); - -printf("<th id='samples' abbr='use' class='sortable sort2' %s " - "align='left' title='Sort on sample count'> Samples</th>", onClick); - -printf("<th id='organ' class='sortable sort3' %s " - "align='left' title='Sort on organ'> Organ</th>", onClick); - -printf("<th id='system' class='sortable sort4' %s " - "align='left' title='Sort on system'> System</th>", onClick); +printf("<th id='tissue' class='%s sort1' %s align='left'> Tissue</th>", + sortableClass, onClick); +printf("<th id='samples' abbr='use' class='%s sort2' %s align='left'> Samples</th>", + sortableClass, onClick); +printf("<th id='organ' class='%s sort3' %s align='left'> Organ</th>", + sortableClass, onClick); +printf("<th id='system' class='%s sort4' %s align='left'> System</th>", + sortableClass, onClick); puts("\n</tr>"); puts("</thead>"); /* table body */ printf("<tbody class='sortable noAltColors initBySortOrder'>"); struct hash *tscHash = gtexGetTissueSampleCount(); struct gtexTissue *tis; boolean isChecked = FALSE; for (tis = tissues; tis != NULL; tis = tis->next) { puts("\n<tr valign='top'>"); // checkbox if (hashNumEntries(checkHash) == 0) isChecked = TRUE; else isChecked = (hashLookup(checkHash, tis->name) != NULL); - printf("<td><input type=checkbox name=\"%s\" value=\"%s\" %s></td>", - name, tis->name, isChecked ? "checked" : ""); + printf("<td><input type=checkbox name=\"%s\" value=\"%s\" %s %s></td>", + name, tis->name, isChecked ? "checked" : "", isPopup ? "disabled" : ""); // color patch printf("\n%s", makeTissueColorPatch(tis)); // tissue name printf("\n<td> %s</td>", tis->description); // sample count int samples = hashIntValDefault(tscHash, tis->name, 0); printf("\n<td abbr='%05d' style='text-align: right; padding-right: 10px'> %d</td>", samples, samples); // organ printf("\n<td style='padding-right: 10px'> %s</td>", tis->organ); // system printf("\n<td> %s</td>", getSystem(tis)); puts("\n</tr>"); } puts("</tbody>"); @@ -252,33 +242,65 @@ } slReverse(&brainTissues); slReverse(&digestiveTissues); slReverse(&reproductiveTissues); slReverse(&otherTissues); makeGroupCheckboxes(name, "Brain", brainTissues); makeGroupCheckboxes(name, "Gastrointestinal", digestiveTissues); makeGroupCheckboxes(name, "Reproductive", reproductiveTissues); makeGroupCheckboxes(name, "Other", otherTissues); puts("</tr></table>"); char buf[512]; safef(buf, sizeof(buf), "%s%s", cgiMultListShadowPrefix(), name); cgiMakeHiddenVar(buf, "0"); } +static void makeAllTissueCheckboxes(char *name, struct gtexTissue *tissues, + struct slName *checked) +{ +struct hash *checkHash = hashNew(0); +struct slName *sel; +for (sel = checked; sel != NULL; sel = sel->next) + hashAdd(checkHash, sel->name, sel->name); +puts("<table borderwidth=0><tr>"); +struct tissueSelect *tsel; +struct gtexTissue *tis; +struct tissueSelect *allTissues = NULL; +for (tis = tissues; tis != NULL; tis = tis->next) + { + AllocVar(tsel); + tsel->name = tis->name; + tsel->label = makeTissueLabel(tis); + if (hashNumEntries(checkHash) == 0) + tsel->checked = TRUE; + else + tsel->checked = (hashLookup(checkHash, tis->name) != NULL); + slAddHead(&allTissues, tsel); + } +slReverse(&allTissues); +makeGroupCheckboxes(name, NULL, allTissues); +puts("</tr></table>"); +char buf[512]; +safef(buf, sizeof(buf), "%s%s", cgiMultListShadowPrefix(), name); +cgiMakeHiddenVar(buf, "0"); +} + void gtexGeneUi(struct cart *cart, struct trackDb *tdb, char *track, char *title, boolean boxed) /* GTEx (Genotype Tissue Expression) per gene data */ { +if (cartVarExists(cart, "ajax")) + isPopup = TRUE; boxed = cfgBeginBoxAndTitle(tdb, boxed, title); printf("<table%s><tr><td>", boxed ?" width='100%'":""); char cartVar[1024]; char *selected = NULL; /* Sample selection */ printf("<b>Samples:</b> "); safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_SAMPLES); selected = cartCgiUsualString(cart, cartVar, GTEX_SAMPLES_DEFAULT); boolean isAllSamples = sameString(selected, GTEX_SAMPLES_ALL); cgiMakeRadioButton(cartVar, GTEX_SAMPLES_ALL, isAllSamples); printf("All\n"); cgiMakeRadioButton(cartVar, GTEX_SAMPLES_COMPARE_SEX, !isAllSamples); printf("Compare by gender\n"); @@ -299,48 +321,52 @@ printf("<p><b>Log10 transform:</b>\n"); safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_LOG_TRANSFORM); boolean isLogTransform = cartCgiUsualBoolean(cart, cartVar, GTEX_LOG_TRANSFORM_DEFAULT); cgiMakeCheckBox(cartVar, isLogTransform); /* Viewing limits max */ printf(" <b>View limits maximum:</b>\n"); safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_MAX_LIMIT); // TODO: set max and initial limits from gtexInfo table int viewMax = cartCgiUsualInt(cart, cartVar, GTEX_MAX_LIMIT_DEFAULT); cgiMakeIntVar(cartVar, viewMax, 4); printf(" RPKM (range 10-180000)<br>\n"); printf("</p>"); /* Color scheme */ -// Not sure if we still want this option +// We don't need the rainbow color scheme, but may want another (e.g. different +// colors for brain tissues), so leaving code in for now. #ifdef COLOR_SCHEME printf("<p><b>Tissue colors:</b>\n"); safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_COLORS); selected = cartCgiUsualString(cart, cartVar, GTEX_COLORS_DEFAULT); boolean isGtexColors = sameString(selected, GTEX_COLORS_GTEX); cgiMakeRadioButton(cartVar, GTEX_COLORS_GTEX, isGtexColors); printf("GTEx\n"); cgiMakeRadioButton(cartVar, GTEX_COLORS_RAINBOW, !isGtexColors); printf("Rainbow\n"); printf("</p>"); #endif /* Tissue filter */ -printf("<p><b>Tissue selection:</b>\n"); +if (!isPopup) + { + printf("<p><b>Tissue filter:</b>\n"); safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_TISSUE_SELECT); jsMakeCheckboxGroupSetClearButton(cartVar, TRUE); puts(" "); jsMakeCheckboxGroupSetClearButton(cartVar, FALSE); + } struct gtexTissue *tissues = gtexGetTissues(); struct slName *selectedValues = NULL; if (cartListVarExistsAnyLevel(cart, tdb, FALSE, GTEX_TISSUE_SELECT)) selectedValues = cartOptionalSlNameListClosestToHome(cart, tdb, FALSE, GTEX_TISSUE_SELECT); char *selectType = cgiUsualString("tis", "table"); if (sameString(selectType, "group")) makeGroupedTissueCheckboxes(cartVar, tissues, selectedValues); else if (sameString(selectType, "table")) - makeTableTissueCheckboxes(cartVar, tissues, selectedValues, cart); + makeTableTissueCheckboxes(cartVar, tissues, selectedValues, cart, track); else makeAllTissueCheckboxes(cartVar, tissues, selectedValues); cfgEndBox(boxed); }