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/wigTrack.c src/hg/hgTracks/wigTrack.c
index 2733cdf..803e98d 100644
--- src/hg/hgTracks/wigTrack.c
+++ src/hg/hgTracks/wigTrack.c
@@ -675,31 +675,31 @@
 		preDraw[winMiddle].smooth = sum / points;
 	++winEnd;
 	++winMiddle;
 	}
     }
 }
 
 double preDrawAutoScale(struct preDrawElement *preDraw, int preDrawZero,
     int width, enum wiggleScaleOptEnum autoScale,
     enum wiggleWindowingEnum windowingFunction,
     double *graphUpperLimit, double *graphLowerLimit,
     double *epsilon, int lineHeight,
     double maxY, double minY, enum wiggleAlwaysZeroEnum alwaysZero)
 /*	if autoScaling, scan preDraw array and determine limits */
 {
-if (autoScale == wiggleScaleAuto)
+if ((autoScale == wiggleScaleAuto) || (autoScale == wiggleScaleCumulative))
     {
     double overallUpperLimit = wigEncodeStartingUpperLimit;
     double overallLowerLimit = wigEncodeStartingLowerLimit;
     int i, lastI = preDrawZero+width;
 
     /* reset limits for auto scale */
     for (i = preDrawZero; i < lastI; ++i)
 	{
 	/*	count is non-zero meaning valid data exists here	*/
 	if (preDraw[i].count)
 	    {
 	    double val =  preDraw[i].smooth;
 	    if (windowingFunction ==  wiggleWindowingWhiskers)
 		val =  preDraw[i].max;
 	    if (val > overallUpperLimit)
@@ -1229,30 +1229,60 @@
 
 return usingDataSpan;
 }
 
 void wigTrackSetGraphOutputDefault(struct track *tg, int xOff, int yOff, int width, struct hvGfx *hvg)
 /* Set up to draw on hvg if no other destination set already */
 {
 if (tg->wigGraphOutput == NULL)
     {
     tg->wigGraphOutput = wigGraphOutputSolid(xOff, yOff, hvg);
 void AllocPixelBins(struct wigGraphOutput *wgo, int width);
     AllocPixelBins(tg->wigGraphOutput, width);
     }
 }
 
+static void setMinMax(struct track *tg, double graphLowerLimit, double graphUpperLimit)
+// We need to check to see if this track changes our min/max for all tracks with this parent.
+// We use tdb entry to store this because it may be per view, which has been smashed out in track list
+{
+struct trackDb *parent = tg->tdb->parent;
+struct tdbExtras *extras = parent->tdbExtras;
+
+if (extras == NULL)
+    {
+    AllocVar(extras);
+    parent->tdbExtras = extras;
+    }
+
+struct minMax *minMax = extras->minMax;
+if (minMax == NULL)
+    {
+    AllocVar(minMax);
+    extras->minMax = minMax;
+    minMax->min = graphLowerLimit;
+    minMax->max = graphUpperLimit;
+    }
+else
+    {
+    if (minMax->min > graphLowerLimit)
+        minMax->min = graphLowerLimit;
+    if (minMax->max < graphUpperLimit)
+        minMax->max = graphUpperLimit;
+    }
+}
+
 void wigPreDrawPredraw(struct track *tg, int seqStart, int seqEnd,
                     struct hvGfx *hvg, int xOff, int yOff, int width,
                     MgFont *font, Color color, enum trackVisibility vis,
                     struct preDrawContainer *preContainer, int preDrawZero,
                     int preDrawSize, double *retGraphUpperLimit, double *retGraphLowerLimit)
 /* Figure out graph limits after running windowingFunction and smoothing if needed.
  * This code is shared by wig, bigWig, and bedGraph drawers. */
 {
 
 /*	determined from data	*/
 double graphUpperLimit=0;	/*	scaling choice will set these	*/
 double graphLowerLimit=0;	/*	scaling choice will set these	*/
 double epsilon;			/*	range of data in one pixel	*/
 struct wigCartOptions *wigCart = (struct wigCartOptions *) tg->wigCartData;
 
@@ -1270,42 +1300,53 @@
     {
     preDrawAutoScale(preDraw, preDrawZero, width,
 	wigCart->autoScale, wigCart->windowingFunction,
 	&preContainer->graphUpperLimit, &preContainer->graphLowerLimit,
 	&epsilon, tg->lineHeight,
 	wigCart->maxY, wigCart->minY, wigCart->alwaysZero);
     }
 
 graphUpperLimit = preContainer->graphUpperLimit;
 graphLowerLimit = preContainer->graphLowerLimit;
 
 if (retGraphUpperLimit != NULL)
     *retGraphUpperLimit = graphUpperLimit;
 if (retGraphLowerLimit != NULL)
     *retGraphLowerLimit = graphLowerLimit;
+
+if (wigCart->autoScale == wiggleScaleCumulative)
+    setMinMax(tg, graphLowerLimit, graphUpperLimit);
 }
 
 void wigDrawPredraw(struct track *tg, int seqStart, int seqEnd,
                     struct hvGfx *hvg, int xOff, int yOff, int width,
                     MgFont *font, Color color, enum trackVisibility vis,
                     struct preDrawContainer *preContainer, int preDrawZero,
                     int preDrawSize, double graphUpperLimit, double graphLowerLimit)
 /* Draw once we've figured out predraw (numerical values to graph) we draw it here.
  * This code is shared by wig, bigWig, and bedGraph drawers. */
 {
 struct wigCartOptions *wigCart = (struct wigCartOptions *) tg->wigCartData;
 double graphRange;   /*	scaling choice will set this */
+
+// if we want the cumulative autoscale, grab it from our parent
+if (wigCart->autoScale == wiggleScaleCumulative)
+    {
+    tg->graphLowerLimit = graphLowerLimit = tg->tdb->parent->tdbExtras->minMax->min;
+    tg->graphUpperLimit = graphUpperLimit = tg->tdb->parent->tdbExtras->minMax->max;
+    }
+
 /* if we're autoscaling and the range is 0 this implies that all values 
  * in the given range are the same.  We create a bottom of the scale  
  * by subtracting one from the only value.
  * This results in drawing a box that fills the range. */
 if (graphUpperLimit == graphLowerLimit)
     {
     graphLowerLimit = graphUpperLimit - 1;
     }
 graphRange = graphUpperLimit - graphLowerLimit;
 
 wigTrackSetGraphOutputDefault(tg, xOff, yOff, width, hvg); 
 
 graphPreDrawContainer(preContainer, preDrawZero, width, tg, hvg, xOff, yOff, 
     graphUpperLimit, graphLowerLimit, graphRange, vis, wigCart);