b4bb3a8a5e38cc6f8f58adc19186469f379a64af max Mon Apr 29 14:55:30 2013 -0700 adding mouseOverField to trackDb for bigBed and using it for the spMut track diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c index bac6ade..da0b2ba 100644 --- src/hg/hgTracks/bigBedTrack.c +++ src/hg/hgTracks/bigBedTrack.c @@ -85,54 +85,100 @@ track->bbiFile = NULL; } errCatchEnd(errCatch); if (errCatch->gotError) { track->networkErrMsg = cloneString(errCatch->message->string); track->drawItems = bigDrawWarning; track->totalHeight = bigWarnTotalHeight; result = NULL; } errCatchFree(&errCatch); return result; } +int bbExtraFieldIndex(struct trackDb *tdb, char* fieldName) +/* return the index of a given extra field from the bbInterval + * 0 is the name-field of bigBed and is used as an error code + * as this is the default anyways */ +{ +if (fieldName==NULL) + return 0; +// copied from hgc.c +// get .as file for track +struct sqlConnection *conn = NULL ; +if (!trackHubDatabase(database)) + conn = hAllocConnTrack(database, tdb); +struct asObject *as = asForTdb(conn, tdb); +hFreeConn(&conn); +if (as == NULL) + return 0; + +// search for field name, return index if found +struct asColumn *col = as->columnList; +int ix = 0; +for (;col != NULL;col=col->next, ix+=1) + if (sameString(col->name, fieldName)) + return max(ix-3, 0); // never return a negative value +return 0; +} + +char* restField(struct bigBedInterval *bb, int fieldIdx) +/* 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[256]; +int restCount = chopTabs(rest, restFields); +char *field = NULL; +if (fieldIdx < restCount) + field = cloneString(restFields[fieldIdx]); +freeMem(rest); +return field; +} + void bigBedAddLinkedFeaturesFrom(struct track *track, char *chrom, int start, int end, int scoreMin, int scoreMax, boolean useItemRgb, int fieldCount, struct linkedFeatures **pLfList) /* 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 = bigBedSelectRange(track, chrom, start, end, lm); char *bedRow[32]; char startBuf[16], endBuf[16]; char *scoreFilter = cartOrTdbString(cart, track->tdb, "scoreFilter", NULL); +char *mouseOverField = cartOrTdbString(cart, track->tdb, "mouseOverField", NULL); int minScore = 0; if (scoreFilter) minScore = atoi(scoreFilter); +int mouseOverIdx = bbExtraFieldIndex(tdb, mouseOverField); + for (bb = bbList; bb != NULL; bb = bb->next) { + char* mouseOver = restField(bb, mouseOverIdx); bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); struct bed *bed = bedLoadN(bedRow, fieldCount); struct linkedFeatures *lf = bedMungToLinkedFeatures(&bed, tdb, fieldCount, scoreMin, scoreMax, useItemRgb); if (scoreFilter == NULL || lf->score >= minScore) slAddHead(pLfList, lf); + lf->mouseOver = mouseOver; // leaks some memory, cloneString handles NULL ifself } lmCleanup(&lm); } 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, @@ -166,22 +212,38 @@ else { int x; for (x=0; x 0) { hvGfxBox(hvg, x+xOff, yOff, 1, tg->heightPer, color); } } } } freez(&tg->summary); } +static void bigBedMapItem(struct track *tg, struct hvGfx *hvg, void *item, + char *itemName, char *mapItemName, int start, int end, + int x, int y, int width, int height) +/* Pull out special mouseover text from item->mouseOver. + * Fallback to item->name if it's not set. + * (derived from bedPlusLabelMapItem) */ +{ +// Don't bother if we are imageV2 and a dense child. +if (theImgBox && tg->limitedVis == tvDense && tdbIsCompositeChild(tg->tdb)) + return; + +struct linkedFeatures *lf = item; +char *mouseOverText = isEmpty(lf->mouseOver) ? lf->name : lf->mouseOver; +mapBoxHc(hvg, start, end, x, y, width, height, tg->track, mapItemName, mouseOverText); +} + void bigBedMethods(struct track *track, struct trackDb *tdb, int wordCount, char *words[]) /* Set up bigBed methods. */ { complexBedMethods(track, tdb, TRUE, wordCount, words); - +track->mapItem = bigBedMapItem; }