12d023ae3337d8909508d543d9d78c99758b25c5 braney Mon Sep 2 10:29:34 2019 -0700 add cumulative auto-scaling to composites and views. Remove REMOTE_TRACK_AJAX_CALLBACK stuff that was apparently an experiment from ten years ago. diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 1a9e5a5..0a64a02 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -408,65 +408,30 @@ char *trackUrl(char *mapName, char *chromName) /* Return hgTrackUi url; chromName is optional. */ { char *encodedMapName = cgiEncode(mapName); char buf[2048]; char *hgTrackUi = hTrackUiForTrack(mapName); if(chromName == NULL) safef(buf, sizeof(buf), "%s?%s=%s&g=%s", hgTrackUi, cartSessionVarName(), cartSessionId(cart), encodedMapName); else safef(buf, sizeof(buf), "%s?%s=%s&c=%s&g=%s", hgTrackUi, cartSessionVarName(), cartSessionId(cart), chromName, encodedMapName); freeMem(encodedMapName); return(cloneString(buf)); } -#ifdef REMOTE_TRACK_AJAX_CALLBACK -static boolean trackUsesRemoteData(struct track *track) -/* returns TRUE is this track has a remote datasource */ -{ -if (!IS_KNOWN(track->remoteDataSource)) - { - SET_TO_NO(track->remoteDataSource); - //if (track->bbiFile != NULL) // FIXME: Chicken or the egg. bigWig/bigBed "bbiFile" filled - // // in by loadItems, but we don't want to load items. - // { - // if (!startsWith("/gbdb/",track->bbiFile->fileName)) - // SET_TO_YES(track->remoteDataSource); - // } - if (startsWithWord("bigWig",track->tdb->type) || startsWithWord("bigBed",track->tdb->type) || - startsWithWord("halSnake",track->tdb->type) || - startsWithWord("pslSnake",track->tdb->type) || - startsWithWord("bigPsl",track->tdb->type) || - startsWithWord("bigGenePred",track->tdb->type) || - startsWithWord("bigChain",track->tdb->type) || - startsWithWord("bigMaf",track->tdb->type) || - startsWithWord("bam",track->tdb->type) || startsWithWord("vcfTabix", track->tdb->type)) - { - SET_TO_YES(track->remoteDataSource); - } - } -return IS_YES(track->remoteDataSource); -} - -boolean trackShouldUseAjaxRetrieval(struct track *track) -/* Tracks with remote data sources should berendered via an ajax callback */ -{ -return (theImgBox && !trackImgOnly && trackUsesRemoteData(track)); -} -#endif///def REMOTE_TRACK_AJAX_CALLBACK - static boolean isCompositeInAggregate(struct track *track) // Check to see if this is a custom composite in aggregate mode. { if (!isCustomComposite(track->tdb)) return FALSE; char *aggregateVal = cartOrTdbString(cart, track->tdb, "aggregate", NULL); if ((aggregateVal == NULL) || sameString(aggregateVal, "none")) return FALSE; struct track *subtrack = NULL; for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) break; @@ -484,33 +449,30 @@ //track->wigCartData = (void *) wigCart; //track->lineHeight = wigCart->defaultHeight; //wigCart->isMultiWig = TRUE; //wigCart->autoScale = wiggleScaleAuto; //wigCart->defaultHeight = track->lineHeight; //struct wigGraphOutput *wgo = setUpWgo(xOff, yOff, width, tg->height, numTracks, wigCart, hvg); //tg->wigGraphOutput = wgo; return TRUE; } static int trackPlusLabelHeight(struct track *track, int fontHeight) /* Return the sum of heights of items in this track (or subtrack as it may be) * and the center label(s) above the items (if any). */ { -if (trackShouldUseAjaxRetrieval(track)) - return REMOTE_TRACK_HEIGHT; - enum trackVisibility vis = limitVisibility(track); int y = track->totalHeight(track, vis); if (isCenterLabelIncluded(track)) y += fontHeight; if (tdbIsComposite(track->tdb) && !isCompositeInAggregate(track)) { struct track *subtrack; for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack) && isCenterLabelIncluded(subtrack)) y += fontHeight; } } return y; } @@ -4988,32 +4950,30 @@ { track = flatTrack->track; if (!isLimitedVisHiddenForAllWindows(track)) { struct track *winTrack; for (winTrack=track; winTrack; winTrack=winTrack->nextWindow) { if (winTrack->labelColor == winTrack->ixColor && winTrack->ixColor == 0) { winTrack->ixColor = hvGfxFindRgb(hvg, &winTrack->color); } } int order = flatTrack->order; curImgTrack = imgBoxTrackFindOrAdd(theImgBox,track->tdb,NULL,track->limitedVis, isCenterLabelIncluded(track),order); - if (trackShouldUseAjaxRetrieval(track)) - imgTrackMarkForAjaxRetrieval(curImgTrack,TRUE); } } } /* Draw mini-buttons. */ if (withLeftLabels && psOutput == NULL) { int butOff; boolean grayButtonGroup = FALSE; struct group *lastGroup = NULL; y = gfxBorder; if (rulerMode != tvHide) { @@ -5175,63 +5135,59 @@ track = flatTrack->track; if (track->limitedVis == tvHide) continue; if (theImgBox) { // side label slice for tracks //ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight); sliceHeight = flatTrack->maxHeight; sliceOffsetY = y; curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL, sliceWidth[stSide],sliceHeight, sliceOffsetX[stSide],sliceOffsetY); (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot } - if (trackShouldUseAjaxRetrieval(track)) - y += REMOTE_TRACK_HEIGHT; - else - { + boolean doWiggle = cartOrTdbBoolean(cart, track->tdb, "doWiggle" , FALSE); if (doWiggle) track->drawLeftLabels = wigLeftLabels; #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL if (theImgBox && track->limitedVis != tvDense) y += sliceHeight; else #endif ///def IMAGEv2_NO_LEFTLABEL_ON_FULL { setGlobalsFromWindow(windows); // use GLOBALS from first window int ynew = 0; /* rmskJoined tracks are non-standard in FULL mode they are just their track height, not per-item height */ if (startsWith("rmskJoined", track->track)) ynew = flatTrack->maxHeight + y; else ynew = doLeftLabels(track, hvgSide, font, y); y += flatTrack->maxHeight; if ((ynew - y) > flatTrack->maxHeight) { // TODO should be errAbort? warn("doLeftLabels(y=%d) returned new y value %d that is too high - should be %d at most.", y, ynew, flatTrack->maxHeight); } } } } - } else { leftLabelX = leftLabelWidth = 0; } /* Draw guidelines. */ if (virtMode && emAltHighlight) withGuidelines = TRUE; // we cannot draw the alternating backgrounds without guidelines layer if (withGuidelines) { struct hvGfx *bgImg = hvg; // Default to the one image boolean exists = FALSE; @@ -5372,135 +5328,132 @@ { // center label slice of tracks Must always make, even if the centerLabel is empty sliceHeight = fontHeight; sliceOffsetY = y; curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stCenter,theOneImg,NULL, sliceWidth[stData],sliceHeight, sliceOffsetX[stData],sliceOffsetY); (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot if (isCenterLabelConditional(track)) // sometimes calls track height, especially when no data there { imgTrackUpdateCenterLabelSeen(curImgTrack,isCenterLabelConditionallySeen(track) ? clNowSeen : clNotSeen); } } - if (trackShouldUseAjaxRetrieval(track)) - { - y += REMOTE_TRACK_HEIGHT; - } - else - { + int savey = y; // GALT y = doCenterLabels(track, track, hvg, font, y, fullInsideWidth); // calls track height y = savey + flatTrack->maxHeight; } - } hvGfxUnclip(hvg); setGlobalsFromWindow(windows); // first window } /* Draw tracks. */ { // brace allows local vars long lastTime = 0; y = yAfterRuler; if (measureTiming) lastTime = clock1000(); + + // first do predraw for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) { track = flatTrack->track; - // parallelize more this?: - - //ORIG if (track->limitedVis == tvHide) if (isLimitedVisHiddenForAllWindows(track)) continue; - int centerLabelHeight = (isCenterLabelIncluded(track) ? fontHeight : 0); - int yStart = y + centerLabelHeight; - // ORIG int yEnd = y + trackPlusLabelHeight(track, fontHeight); - int yEnd = y + flatTrack->maxHeight; - if (theImgBox) - { - // data slice of tracks - sliceOffsetY = yStart; - sliceHeight = yEnd - yStart - 1; - curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); - if (sliceHeight > 0) - { - curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,NULL, - sliceWidth[stData],sliceHeight, - sliceOffsetX[stData],sliceOffsetY); - (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot - } - } - if (trackShouldUseAjaxRetrieval(track)) - y += REMOTE_TRACK_HEIGHT; - else - { - int savey = y; struct track *winTrack; // do preDraw if (track->preDrawItems) { for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow) { setGlobalsFromWindow(window); if (winTrack->limitedVis == tvHide) { warn("Draw tracks skipping %s because winTrack->limitedVis=hide", winTrack->track); continue; } if (insideWidth >= 1) // do not try to draw if width < 1. { doPreDrawItems(winTrack, hvg, font, y, &lastTime); } } } setGlobalsFromWindow(windows); // first window // do preDrawMultiRegion across all windows, e.g. wig autoScale if (track->preDrawMultiRegion) { track->preDrawMultiRegion(track); } + } + + // now do the actual draw + for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) + { + int savey = y; + struct track *winTrack; + track = flatTrack->track; + if (isLimitedVisHiddenForAllWindows(track)) + continue; + int centerLabelHeight = (isCenterLabelIncluded(track) ? fontHeight : 0); + int yStart = y + centerLabelHeight; + int yEnd = y + flatTrack->maxHeight; + + if (theImgBox) + { + // data slice of tracks + sliceOffsetY = yStart; + sliceHeight = yEnd - yStart - 1; + curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); + if (sliceHeight > 0) + { + curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,NULL, + sliceWidth[stData],sliceHeight, + sliceOffsetX[stData],sliceOffsetY); + (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot + } + } // doDrawItems for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow) { setGlobalsFromWindow(window); if (winTrack->limitedVis == tvHide) { warn("Draw tracks skipping %s because winTrack->limitedVis=hide", winTrack->track); continue; } if (insideWidth >= 1) // do not try to draw if width < 1. { int ynew = doDrawItems(winTrack, hvg, font, y, &lastTime); if ((ynew-y) > flatTrack->maxHeight) // so compiler does not complain ynew is not used. errAbort("oops track too high!"); } } setGlobalsFromWindow(windows); // first window y = savey + flatTrack->maxHeight; - } if (theImgBox && tdbIsCompositeChild(track->tdb) && (track->limitedVis == tvDense || (track->limitedVis == tvPack && centerLabelHeight == 0))) mapBoxToggleVis(hvg, 0, yStart,tl.picWidth, sliceHeight,track); // Strange mapBoxToggleLogic handles reverse complement itself so x=0,width=tl.picWidth if (yEnd != y) warn("Slice height for track %s does not add up. Expecting %d != %d actual", track->shortLabel, yEnd - yStart - 1, y - yStart); } calcWiggleOrdering(cart, flatTracks); y++; } @@ -5518,33 +5471,31 @@ track = flatTrack->track; if (track->limitedVis == tvHide) continue; if (theImgBox) { // side label slice of tracks sliceHeight = flatTrack->maxHeight; sliceOffsetY = y; curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL, sliceWidth[stSide],sliceHeight, sliceOffsetX[stSide],sliceOffsetY); (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot } - if (trackShouldUseAjaxRetrieval(track)) - y += REMOTE_TRACK_HEIGHT; - else if (track->drawLeftLabels != NULL) + if (track->drawLeftLabels != NULL) { setGlobalsFromWindow(windows); y = doOwnLeftLabels(track, hvgSide, font, y); setGlobalsFromWindow(windows); // first window } else y += flatTrack->maxHeight; } } /* Make map background. */ y = yAfterRuler; for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) { @@ -6127,32 +6078,30 @@ else if (sameString(type, "wig")) { tg = trackFromTrackDb(tdb); if (ct->dbTrack) tg->loadItems = wigLoadItems; else tg->loadItems = ctWigLoadItems; tg->customPt = ct; tg->nextItemButtonable = FALSE; } else if (sameString(type, "bigWig")) { tg = trackFromTrackDb(tdb); tg->bbiFile = ct->bbiFile; tg->nextItemButtonable = FALSE; - if (trackShouldUseAjaxRetrieval(tg)) - tg->loadItems = dontLoadItems; } else if (sameString(type, "bigBed")|| sameString(type, "bigGenePred") || sameString(type, "bigNarrowPeak") || sameString(type, "bigPsl") || sameString(type, "bigMaf")|| sameString(type, "bigChain") || sameString(type, "bigLolly") || sameString(type, "bigBarChart") || sameString(type, "bigInteract")) { struct bbiFile *bbi = ct->bbiFile; /* Find field counts, and from that revise the tdb->type to be more complete. */ char extra = (bbi->fieldCount > bbi->definedFieldCount ? '+' : '.'); char typeBuf[64]; if (sameString(type, "bigGenePred")) safef(typeBuf, sizeof(typeBuf), "bigGenePred"); else if (sameString(type, "bigNarrowPeak")) @@ -6165,32 +6114,30 @@ safef(typeBuf, sizeof(typeBuf), "bigPsl"); else if (sameString(type, "bigBarChart")) safef(typeBuf, sizeof(typeBuf), "bigBarChart"); else if (sameString(type, "bigLolly")) safef(typeBuf, sizeof(typeBuf), "bigLolly"); else if (sameString(type, "bigInteract")) safef(typeBuf, sizeof(typeBuf), "bigInteract"); else safef(typeBuf, sizeof(typeBuf), "bigBed %d %c", bbi->definedFieldCount, extra); tdb->type = cloneString(typeBuf); /* Finish wrapping track around tdb. */ tg = trackFromTrackDb(tdb); tg->bbiFile = bbi; tg->nextItemButtonable = TRUE; - if (trackShouldUseAjaxRetrieval(tg)) - tg->loadItems = dontLoadItems; } else if (sameString(type, "bedGraph")) { tg = trackFromTrackDb(tdb); tg->canPack = FALSE; tg->customPt = ct; ct->wigFile = ctFileName; tg->mapItemName = ctMapItemName; tg->nextItemButtonable = FALSE; } else if (sameString(type, "bed")) { tg = trackFromTrackDb(tdb); if (ct->fieldCount < 8) { @@ -6246,41 +6193,37 @@ tg->nextItemButtonable = TRUE; tg->customPt = ct; } else if (sameString(type, "encodePeak")) { tg = trackFromTrackDb(tdb); encodePeakMethodsCt(tg); tg->nextItemButtonable = TRUE; tg->customPt = ct; } else if (sameString(type, "bam")) { tg = trackFromTrackDb(tdb); tg->customPt = ct; bamMethods(tg); - if (trackShouldUseAjaxRetrieval(tg)) - tg->loadItems = dontLoadItems; tg->mapItemName = ctMapItemName; } else if (sameString(type, "vcfTabix")) { tg = trackFromTrackDb(tdb); tg->customPt = ct; vcfTabixMethods(tg); - if (trackShouldUseAjaxRetrieval(tg)) - tg->loadItems = dontLoadItems; tg->mapItemName = ctMapItemName; } else if (sameString(type, "vcf")) { tg = trackFromTrackDb(tdb); tg->customPt = ct; vcfMethods(tg); tg->mapItemName = ctMapItemName; } else if (sameString(type, "makeItems")) { tg = trackFromTrackDb(tdb); makeItemsMethods(tg); tg->nextItemButtonable = TRUE; tg->customPt = ct;