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;