7f165a4c474605452621918390c40378a571eec5 kent Sun Jan 31 08:31:08 2021 -0800 Getting the facets properly (not in an iFrame) into hgTrackUi. diff --git src/hg/lib/barChartUi.c src/hg/lib/barChartUi.c index 2317e12..f01e7df 100644 --- src/hg/lib/barChartUi.c +++ src/hg/lib/barChartUi.c @@ -4,30 +4,31 @@ * See README in this or parent directory for licensing information. */ #include "cheapcgi.h" #include "cart.h" #include "net.h" #include "errCatch.h" #include "web.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" +#include "facetedTable.h" #include "tablesTables.h" /* Restrict features on right-click (popup) version */ static boolean isPopup = FALSE; /* Convenience functions for category filter controls */ char *makeCategoryLabel(struct barChartCategory *categ) /* Display category color and label */ { char buf[256]; safef(buf, sizeof(buf), "<td class='bcColorPatch' bgcolor=#%06x></td>" "<td> %s</td>", categ->color, categ->label); @@ -179,43 +180,47 @@ cgiMakeDoubleVarWithExtra(cartVar, viewMax, 4, isLogTransform ? "disabled" : ""); char *unit = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, ""); printf("<span class='%s'> %s (range 0-%d)</span>\n", buf, unit, round(barChartUiMaxMedianScore(tdb))); } // TODO: libify static boolean isUrl(char *url) { return startsWith("http://", url) || startsWith("https://", url) || startsWith("ftp://", url); } static void getCategsFromSettings(char *track, char *labelSetting, char *colorSetting, - struct slName **labels, struct slName **colors) + struct slName **retLabels, struct slName **colors) /* Get category labels and optionally colors, from track settings */ { -if (!labels || !colors) - return; if (isEmpty(labelSetting)) { errAbort("barChart track %s missing required setting: %s or %s\n", track, BAR_CHART_CATEGORY_LABELS, BAR_CHART_CATEGORY_URL); } char *words[BAR_CHART_MAX_CATEGORIES]; int labelCount = chopLine(cloneString(labelSetting), words); -*labels = slNameListFromStringArray(words, labelCount); +struct slName *labelList = *retLabels = slNameListFromStringArray(words, labelCount); + +/* Strip out underbars from trackDb early */ +struct slName *label; +for (label = labelList; label != NULL; label = label->next) + subChar(label->name, '_', ' '); + if (isNotEmpty(colorSetting)) { int colorCount = chopLine(cloneString(colorSetting), words); if (colorCount != labelCount) errAbort("barChart track %s settings mismatch: %s (%d) and %s (%d)\n", track, BAR_CHART_CATEGORY_LABELS, labelCount, BAR_CHART_CATEGORY_COLORS, colorCount); *colors = slNameListFromStringArray(words, labelCount); } } static void getCategsFromFile(char *track, char *categUrl, struct slName **labels, struct slName **colors) /* Get category labels and optionally colors, from category file. * This is tab-sep file, column 1 is category label, optional column 2 is a color spec */ { @@ -356,85 +361,133 @@ } char *barChartUiGetCategoryLabelById(int id, char *database, struct trackDb *tdb) /* Get label for a category id */ { struct barChartCategory *categ = barChartUiGetCategoryById(id, database, tdb); if (categ == NULL) return "Unknown"; return categ->label; } void barChartCfgUiSelectEachBar(char *database, struct cart *cart, struct trackDb *tdb, char *track, char *title, boolean boxed) /* Bar chart track type */ { -if (cartVarExists(cart, "ajax")) - isPopup = TRUE; -boxed = cfgBeginBoxAndTitle(tdb, boxed, title); -if (startsWith("big", tdb->type)) - labelCfgUi(database, cart, tdb, track); printf("\n<table id=barChartControls style='font-size:%d%%' %s>\n<tr><td>", isPopup ? 75 : 100, boxed ?" width='100%'":""); -char cartVar[1024]; - /* Data transform. When selected, the next control (view limits max) is disabled */ puts("<div>"); barChartUiLogTransform(cart, track, tdb); /* Viewing limits max. This control is disabled if log transform is selected */ // construct class so JS can toggle puts(" "); barChartUiViewLimits(cart, track, tdb); puts("</div>"); - /* Category filter */ printf("<br>"); char *categoryLabel = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_CATEGORY_LABEL, BAR_CHART_CATEGORY_LABEL_DEFAULT); char *db = cartString(cart, "db"); struct barChartCategory *categs = barChartUiGetCategories(db, tdb); printf("<div><b>%s:</b>\n", categoryLabel); +char cartVar[1024]; safef(cartVar, sizeof(cartVar), "%s.%s", track, BAR_CHART_CATEGORY_SELECT); if (isPopup) { printf("<a href='%s?g=%s'><button type='button'>Change</button><a>", hTrackUiForTrack(track), track); } else { jsMakeCheckboxGroupSetClearButton(cartVar, TRUE); puts(" "); jsMakeCheckboxGroupSetClearButton(cartVar, FALSE); } printf("</div>"); struct slName *selectedValues = NULL; if (cartListVarExistsAnyLevel(cart, tdb, FALSE, BAR_CHART_CATEGORY_SELECT)) selectedValues = cartOptionalSlNameListClosestToHome(cart, tdb, FALSE, BAR_CHART_CATEGORY_SELECT); makeCategoryCheckboxes(cartVar, categs, selectedValues); puts("\n</table>\n"); -cfgEndBox(boxed); +} + +void wrapColor(struct fieldedTable *table, struct fieldedRow *row, + char *field, char *val, char *shortVal, void *context) +/* Write out wrapper draws a SVG bar*/ +{ +printf("<div style=\"background-color:%s\">  </span>", val); +// printf("<TD><TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR>"); } void barChartFacetedUi(char *database, struct cart *cart, struct trackDb *tdb, char *track, char *title, boolean boxed) /* Bar chart track type that has an associated facets tables */ { -printf("<iframe id=\"barChartFacetedUi\" src=\"../cgi-bin/hgFacetedBars?%s\" ", - cartSidUrlString(cart)); -printf(" height=\"600\" width=\"1200\" "); // I hope these get set from javascript soon -printf(">"); +puts("<br>"); +barChartUiLogTransform(cart, track, tdb); +puts(" "); +barChartUiViewLimits(cart, track, tdb); + +char *facets = trackDbSetting(tdb, "barChartFacets"); +char *statsFile = trackDbRequiredSetting(tdb, "barChartStatsUrl"); + +/* Write html to make white background */ +hInsideStyleToWhite(); + +/* Set up url that has enough context to get back to us. */ +struct dyString *returnUrl = dyStringNew(0); +dyStringPrintf(returnUrl, "../cgi-bin/hgTrackUi?g=%s", track); +dyStringPrintf(returnUrl, "&%s", cartSidUrlString(cart)); + +/* Load up table from tsv file */ +char *requiredStatsFields[] = {"count",}; +struct fieldedTable *table = fieldedTableFromTabFile(statsFile, statsFile, + requiredStatsFields, ArraySize(requiredStatsFields)); + +/* Update facet selections from users input if any and get selected part of table */ +struct facetedTable *facTab = facetedTableFromTable(table, tdb->track, facets); +facetedTableUpdateOnClick(facTab, cart); +struct fieldedTable *selected = facetedTableSelect(facTab, cart); + +/* Add wrapper function(s) */ +struct hash *wrapperHash = hashNew(0); +hashAdd(wrapperHash, "color", wrapColor); + +/* Pick which fields to display. We'll take the first field whatever it is + * named, color if possible, and also count, and any faceted fields. */ +struct dyString *displayList = dyStringNew(0); +int colorIx = fieldedTableFindFieldIx(table, "color"); +if (colorIx >= 0) + dyStringPrintf(displayList, "color,"); +dyStringAppend(displayList, table->fields[0]); +dyStringPrintf(displayList, ",count,%s", facets); + +/* Put up facets and table */ +facetedTableWriteHtml(facTab, cart, selected, displayList->string, + returnUrl->string, 40, wrapperHash, NULL, 7); + +/* Clean up and go home. */ +facetedTableFree(&facTab); } void barChartCfgUi(char *database, struct cart *cart, struct trackDb *tdb, char *track, char *title, boolean boxed) /* Put up facets in certain situations. */ { -if (sameString(track, "singleCellMerged")) +if (cartVarExists(cart, "ajax")) + isPopup = TRUE; +boxed = cfgBeginBoxAndTitle(tdb, boxed, title); +if (startsWith("big", tdb->type)) + labelCfgUi(database, cart, tdb, track); +char *facets = trackDbSetting(tdb, "barChartFacets"); +if (facets != NULL) barChartFacetedUi(database, cart, tdb, track, title, boxed); else barChartCfgUiSelectEachBar(database, cart, tdb, track, title, boxed); +cfgEndBox(boxed); }