038e590eac583c4253e53b234b365a4e842586c5 kent Sat Jan 30 09:02:52 2021 -0800 Initial implementation of barChartFacet feature in click display. diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c index 9999970..73323f8 100644 --- src/hg/hgc/barChartClick.c +++ src/hg/hgc/barChartClick.c @@ -11,30 +11,31 @@ #include "hCommon.h" #include "hui.h" #include "asParse.h" #include "hgc.h" #include "trackHub.h" #include "memgfx.h" #include "hgColors.h" #include "fieldedTable.h" #include "barChartBed.h" #include "barChartCategory.h" #include "barChartData.h" #include "barChartSample.h" #include "barChartUi.h" #include "hgConfig.h" +#include "facetedBar.h" #define EXTRA_FIELDS_SIZE 256 struct barChartItemData /* Measured value for a sample and the sample category at a locus. * Used for barChart track details (boxplot) */ { struct barChartItemData *next; /* Next in singly linked list. */ char *sample; /* Sample identifier */ char *category; /* Sample category (from barChartSample table or barChartSampleUrl file) */ double value; /* Measured value (e.g. expression level) */ }; static struct hash *getTrackCategories(struct trackDb *tdb) /* Get list of categories from trackDb. This may be a subset of those in matrix. @@ -387,64 +388,63 @@ static double longestLabelSize(struct barChartCategory *categList) /* Get estimate of longest label in pixels */ { int longest = 0; struct barChartCategory *categ; for (categ = categList; categ != NULL; categ = categ->next) { int size = estimateStringWidth(categ->label); if (size > longest) longest = size; } return longest * 1.02; } -void deunderbarColumn(struct fieldedTable *ft, char *field) +void deunderbarColumn(struct fieldedTable *ft, int fieldIx) /* Ununderbar all of a column inside table because space/underbar gets * so confusing */ { -int fieldIx = fieldedTableFindFieldIx(ft, field); struct fieldedRow *row; for (row = ft->rowList; row != NULL; row = row->next) replaceChar(row->row[fieldIx], '_', ' '); } -static void printBarChart(struct barChartBed *chart, struct trackDb *tdb, double maxVal, char *metric) +static void svgBarChart(struct barChartBed *chart, struct trackDb *tdb, double maxVal, char *metric) /* Plot bar chart without quartiles or anything fancy just using SVG */ { /* Load up input labels, color, and data */ struct barChartCategory *categs = barChartUiGetCategories(database, tdb); int categCount = slCount(categs); if (categCount != chart->expCount) { warn("Problem in %s barchart track. There are %d categories in trackDb and %d in data", tdb->track, categCount, chart->expCount); return; } char *statsFile = trackDbSetting(tdb, "barChartStatsUrl"); struct hash *statsHash = NULL; int countStatIx = 0; double statsSize = 0.0; if (statsFile != NULL) { - char *required[] = {"cluster", "count", "total"}; + char *required[] = { "count", "total"}; struct fieldedTable *ft = fieldedTableFromTabFile( statsFile, statsFile, required, ArraySize(required)); - deunderbarColumn(ft, "cluster"); - statsHash = fieldedTableIndex(ft, "cluster"); + deunderbarColumn(ft, 0); + statsHash = fieldedTableIndex(ft, ft->fields[0]); countStatIx = fieldedTableFindFieldIx(ft, "count"); statsSize = 8*(fieldedTableMaxColChars(ft, countStatIx)+1); } /* Some constants that control layout */ double heightPer=18.0; double totalWidth=1250.0; double borderSize = 1.0; double headerHeight = heightPer + 2*borderSize; double innerHeight=heightPer-borderSize; double labelWidth = longestLabelSize(categs) + 9; // Add some because size is just estimate if (labelWidth > totalWidth/2) labelWidth = totalWidth/2; // Don't let labels take up more than half double patchWidth = heightPer; double labelOffset = patchWidth + 2*borderSize; @@ -496,30 +496,42 @@ { struct fieldedRow *fr = hashFindVal(statsHash, deunder); if (fr != NULL) { printf("%s\n", statsRightOffset, yPos+innerHeight-1, innerHeight-1, fr->row[countStatIx]); } } printf("%5.3f\n", barOffset+barWidth+2, yPos+innerHeight-1, innerHeight-1, score); } printf(""); } +static void printBarChart(char *item, struct barChartBed *chart, struct trackDb *tdb, + double maxVal, char *metric) +/* Plot bar chart without expressionMatrix or R plots*/ +{ +char *statsFile = trackDbSetting(tdb, "barChartStatsUrl"); +char *facets = trackDbSetting(tdb, "barChartFacets"); +if (facets != NULL && statsFile != NULL) + facetedBarChart(item, chart, tdb, maxVal, statsFile, facets, metric); +else + svgBarChart(chart, tdb, maxVal, metric); +} + struct asColumn *asFindColByIx(struct asObject *as, int ix) /* Find AS column by index */ { struct asColumn *asCol; int i; for (i=0, asCol = as->columnList; asCol != NULL && inext, i++); return asCol; } void doBarChartDetails(struct trackDb *tdb, char *item) /* Details of barChart item */ { int start = cartInt(cart, "o"); int end = cartInt(cart, "t"); struct asObject *as = NULL; @@ -534,69 +546,70 @@ // get name and name2 from trackDb, .as file, or use defaults struct asColumn *nameCol = NULL, *name2Col = NULL; //struct asColumn *name2Col; char *nameLabel = NULL, *name2Label = NULL; if (as != NULL) { numColumns = slCount(as->columnList); nameCol = asFindColByIx(as, BARCHART_NAME_COLUMN_IX); name2Col = asFindColByIx(as, BARCHART_NAME2_COLUMN_IX); } nameLabel = trackDbSettingClosestToHomeOrDefault(tdb, "bedNameLabel", nameCol ? nameCol->comment : "Item"); if (trackDbSettingClosestToHomeOrDefault(tdb, "url", NULL) != NULL) printCustomUrl(tdb, item, TRUE); else - printf("%s: %s
\n", nameLabel, chartItem->name); + printf("%s: %s ", nameLabel, chartItem->name); name2Label = name2Col ? name2Col->comment : "Alternative name"; if (differentString(chartItem->name2, "")) { if (trackDbSettingClosestToHomeOrDefault(tdb, "url2", NULL) != NULL) printOtherCustomUrl(tdb, chartItem->name2, "url2", TRUE); else - printf("%s: %s
\n", name2Label, chartItem->name2); + printf("(%s: %s)
\n", name2Label, chartItem->name2); } +else + printf("
\n"); int categId; float highLevel = barChartMaxValue(chartItem, &categId); char *units = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, "units"); char *metric = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_METRIC, ""); -printf("Total all %s values: %0.2f %s
\n", metric, barChartTotalValue(chartItem), units); printf("Maximum %s value: %0.2f %s in %s
\n", metric, highLevel, units, barChartUiGetCategoryLabelById(categId, database, tdb)); -printf("Score: %d
\n", chartItem->score); printf("Genomic position: " "%s %s:%d-%d
\n", database, hgTracksPathAndSettings(), database, chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd, chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd); -printf("Strand: %s\n", chartItem->strand); // print any remaining extra fields if (numColumns > 0) { extraFieldsPrint(tdb, NULL, extraFields, extraFieldCount); } char *matrixUrl = NULL, *sampleUrl = NULL; struct barChartItemData *vals = getSampleVals(tdb, chartItem, &matrixUrl, &sampleUrl); puts("

"); if (vals != NULL) { // Print boxplot char *df = makeDataFrame(tdb->table, vals); char *colorFile = makeColorFile(tdb); printBoxplot(df, item, chartItem->name2, units, colorFile); printf("
View all data points for %s%s%s%s\n", df, chartItem->name, chartItem->name2 ? " (" : "", chartItem->name2 ? chartItem->name2 : "", chartItem->name2 ? ")" : ""); } else { if (cfgOptionBooleanDefault("svgBarChart", FALSE)) - printBarChart(chartItem, tdb, highLevel, metric); + { + printBarChart(item, chartItem, tdb, highLevel, metric); + } } puts("
"); }