5be304c4bdd41bd4452a4b9f1b8fcf37930079e4 braney Fri Feb 3 11:09:59 2017 -0800 allow arbitrary fields with a bigBed file to be used for labels. #18782 diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c index 2a5f1e8..9653b4c 100644 --- src/hg/hgTracks/bigBedTrack.c +++ src/hg/hgTracks/bigBedTrack.c @@ -110,30 +110,49 @@ /* return a given field from the bb->rest field, NULL on error */ { if (fieldIdx==0) // we don't return the first(=name) field of bigBed return NULL; char *rest = cloneString(bb->rest); char *restFields[1024]; int restCount = chopTabs(rest, restFields); char *field = NULL; if (fieldIdx < restCount) field = cloneString(restFields[fieldIdx]); freeMem(rest); return field; } +char *makeLabel(struct track *track, struct bigBedInterval *bb) +// Build a label for a bigBedTrack from the requested label fields. +{ +char *restFields[256]; +chopTabs(cloneString(bb->rest), restFields); +struct dyString *dy = newDyString(128); +boolean firstTime = TRUE; +struct slInt *labelInt = track->labelColumns; +for(; labelInt; labelInt = labelInt->next) + { + if (!firstTime) + dyStringPrintf(dy, "/"); + + dyStringPrintf(dy, "%s", restFields[labelInt->val - 3]); + firstTime = FALSE; + } +return dyStringCannibalize(&dy); +} + void bigBedAddLinkedFeaturesFromExt(struct track *track, char *chrom, int start, int end, int scoreMin, int scoreMax, boolean useItemRgb, int fieldCount, struct linkedFeatures **pLfList, int maxItems) /* Read in items in chrom:start-end from bigBed file named in track->bbiFileName, convert * them to linkedFeatures, and add to head of list. */ { struct lm *lm = lmInit(0); struct trackDb *tdb = track->tdb; struct bigBedInterval *bb, *bbList = bigBedSelectRangeExt(track, chrom, start, end, lm, maxItems); char *scoreFilter = cartOrTdbString(cart, track->tdb, "scoreFilter", NULL); char *mouseOverField = cartOrTdbString(cart, track->tdb, "mouseOverField", NULL); int minScore = 0; if (scoreFilter) minScore = atoi(scoreFilter); @@ -166,44 +185,47 @@ reverseComplement(seq, strlen(seq)); lf->extra = seq; lf->cds = cds; } else { char startBuf[16], endBuf[16]; char *bedRow[32]; bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); struct bed *bed = bedLoadN(bedRow, fieldCount); lf = bedMungToLinkedFeatures(&bed, tdb, fieldCount, scoreMin, scoreMax, useItemRgb); } + lf->label = makeLabel(track, bb); if (sameString(track->tdb->type, "bigGenePred") || startsWith("genePred", track->tdb->type)) { struct genePred *gp = lf->original = genePredFromBigGenePred(chromName, bb); lf->extra = gp->name2; lf->isBigGenePred = TRUE; } char* mouseOver = restField(bb, mouseOverIdx); lf->mouseOver = mouseOver; // leaks some memory, cloneString handles NULL ifself if (scoreFilter == NULL || lf->score >= minScore) slAddHead(pLfList, lf); } lmCleanup(&lm); + +track->itemName = bigLfItemName; } boolean canDrawBigBedDense(struct track *tg) /* Return TRUE if conditions are such that can do the fast bigBed dense data fetch and * draw. */ { return tg->isBigBed; } void bigBedDrawDense(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color) /* Use big-bed summary data to quickly draw bigBed. */ @@ -235,21 +257,37 @@ else { int x; for (x=0; x 0) { hvGfxBox(hvg, x+xOff, yOff, 1, tg->heightPer, color); } } } } freez(&tg->summary); } +char *bigBedItemName(struct track *tg, void *item) +// return label for simple beds +{ +struct bed *bed = (struct bed *)item; + +return bed->label; +} + +char *bigLfItemName(struct track *tg, void *item) +// return label for linked features +{ +struct linkedFeatures *lf = (struct linkedFeatures *)item; + +return lf->label; +} + void bigBedMethods(struct track *track, struct trackDb *tdb, int wordCount, char *words[]) /* Set up bigBed methods. */ { complexBedMethods(track, tdb, TRUE, wordCount, words); }