093cdb88859d6e144f97c121b9175f9e7ac98f07 chmalee Tue Sep 27 09:22:47 2022 -0700 Get $<fieldName> substitution supported in bigBarChart url link outs, refs #29954 diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c index 5fe5692..c6b809c 100644 --- src/hg/hgc/barChartClick.c +++ src/hg/hgc/barChartClick.c @@ -27,36 +27,45 @@ #include "pipeline.h" #include "chromAlias.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 barChartBed *getBarChartFromFile(struct trackDb *tdb, char *file, +struct barChartPlusRow +/* Keep original row around for url processing */ + { + struct barChartPlusRow *next; + struct barChartBed *barChart; + char **row; + }; + +static struct barChartPlusRow *getBarChartFromFile(struct trackDb *tdb, char *file, char *item, char *chrom, int start, int end, struct asObject **retAs, char **extraFieldsRet, int *extraFieldsCountRet) /* Retrieve barChart BED item from big file */ { +struct barChartPlusRow *ret = NULL; boolean hasOffsets = TRUE; struct bbiFile *bbi = bigBedFileOpenAlias(file, chromAliasFindAliases); struct asObject *as = bigBedAsOrDefault(bbi); if (retAs != NULL) *retAs = as; hasOffsets = ( asColumnFind(as, BARCHART_OFFSET_COLUMN) != NULL && asColumnFind(as, BARCHART_LEN_COLUMN) != NULL); struct lm *lm = lmInit(0); struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chrom, start, end, 0, lm); for (bb = bbList; bb != NULL; bb = bb->next) { char *rest = cloneString(bb->rest); char startBuf[16], endBuf[16]; char *row[32]; @@ -64,80 +73,87 @@ struct barChartBed *barChart = barChartBedLoadOptionalOffsets(row, hasOffsets); if (barChart == NULL) continue; if (sameString(barChart->name, item)) { char *restFields[EXTRA_FIELDS_SIZE]; int restCount = chopTabs(rest, restFields); int restBedFields = (6 + (hasOffsets ? 2 : 0)); if (restCount > restBedFields) { int i; for (i = 0; i < restCount - restBedFields; i++) extraFieldsRet[i] = restFields[restBedFields + i]; *extraFieldsCountRet = (restCount - restBedFields); } - return barChart; + AllocVar(ret); + ret->barChart = barChart; + ret->row = row; + return ret; } } return NULL; } -static struct barChartBed *getBarChartFromTable(struct trackDb *tdb, char *table, +static struct barChartPlusRow *getBarChartFromTable(struct trackDb *tdb, char *table, char *item, char *chrom, int start, int end) /* Retrieve barChart BED item from track table */ { +struct barChartPlusRow *ret = NULL; struct sqlConnection *conn = NULL; struct customTrack *ct = lookupCt(tdb->track); if (ct == NULL) conn = hAllocConnTrack(database, tdb); else { conn = hAllocConn(CUSTOM_TRASH); table = ct->dbTableName; } if (conn == NULL) return NULL; struct barChartBed *barChart = NULL; char **row; char query[512]; struct sqlResult *sr; if (sqlTableExists(conn, table)) { boolean hasOffsets = (sqlColumnExists(conn, table, BARCHART_OFFSET_COLUMN) && sqlColumnExists(conn, table, BARCHART_LEN_COLUMN)); sqlSafef(query, sizeof query, "SELECT * FROM %s WHERE name='%s'" "AND chrom='%s' AND chromStart=%d AND chromEnd=%d", table, item, chrom, start, end); sr = sqlGetResult(conn, query); row = sqlNextRow(sr); if (row != NULL) { barChart = barChartBedLoadOptionalOffsets(row, hasOffsets); + AllocVar(ret); + ret->barChart = barChart; + ret->row = row; } sqlFreeResult(&sr); } hFreeConn(&conn); -return barChart; +return ret; } -static struct barChartBed *getBarChart(struct trackDb *tdb, char *item, char *chrom, int start, int end, +static struct barChartPlusRow *getBarChart(struct trackDb *tdb, char *item, char *chrom, int start, int end, struct asObject **retAs, char **extraFieldsReg, int *extraFieldsCountRet) /* Retrieve barChart BED item from track */ { -struct barChartBed *barChart = NULL; +struct barChartPlusRow *barChart = NULL; char *file = hReplaceGbdb(trackDbSetting(tdb, "bigDataUrl")); if (file != NULL) barChart = getBarChartFromFile(tdb, file, item, chrom, start, end, retAs, extraFieldsReg, extraFieldsCountRet); else barChart = getBarChartFromTable(tdb, tdb->table, item, chrom, start, end); return barChart; } static struct barChartItemData *getSampleValsFromFile(struct trackDb *tdb, struct hash *categoryHash, struct barChartBed *bed, char *dataFile, char *sampleFile) /* Get all data values in a file for this item (locus) */ { // Get sample categories from sample file // Format: id, category, extras @@ -529,49 +545,52 @@ struct asColumn *asCol; int i; for (i=0, asCol = as->columnList; asCol != NULL && i<ix; asCol = asCol->next, 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; char *extraFields[EXTRA_FIELDS_SIZE]; int extraFieldCount = 0; int numColumns = 0; -struct barChartBed *chartItem = getBarChart(tdb, item, seqName, start, end, &as, extraFields, &extraFieldCount); +struct barChartPlusRow *bcRow = getBarChart(tdb, item, seqName, start, end, &as, extraFields, &extraFieldCount); +struct barChartBed *chartItem = bcRow->barChart; +char **row = bcRow->row; if (chartItem == NULL) errAbort("Can't find item %s in barChart table/file %s\n", item, tdb->table); genericHeader(tdb, item); // 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"); +struct slPair *fields = getFields(tdb, row); if (trackDbSettingClosestToHomeOrDefault(tdb, "url", NULL) != NULL) - printCustomUrl(tdb, item, TRUE); + printCustomUrlWithFields(tdb, item, nameLabel, TRUE, fields); else printf("<b>%s: </b>%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)<br>\n", name2Label, chartItem->name2); } else printf("<br>\n"); int categId; float highLevel = barChartMaxValue(chartItem, &categId);