7d425214dcf40fa365f6f448379b709ec071eab4
hiram
  Fri Nov 6 22:43:17 2020 -0800
now showing mean of values when not at base display refs #21980

diff --git src/hg/hgTracks/wigTrack.c src/hg/hgTracks/wigTrack.c
index 0edb936..75ca4e3 100644
--- src/hg/hgTracks/wigTrack.c
+++ src/hg/hgTracks/wigTrack.c
@@ -845,30 +845,31 @@
 wgo->yOff = yOff;
 return wgo;
 }
 
 /* prototype version of mouseOverData using this static array,
  *   will alter this to be a private linked list
  */
 static struct wigMouseOver *mouseOverData = NULL;
 static int mouseOverIdx = -1;
 
 struct wigMouseOver
     {
     int x1;	/* beginning of a rectangle for this value */
     int x2;	/* end of the rectangle */
     double value;	/* data value for this region */
+    boolean mean;	/* if data value is mean */
     };
 
 void graphPreDraw(struct preDrawElement *preDraw, int preDrawZero, int width,
     struct track *tg, void *image, WigVerticalLineVirtual vLine, int xOff, int yOff, double *yOffsets, int numTrack,
     double graphUpperLimit, double graphLowerLimit, double graphRange,
     double epsilon, Color *colorArray, enum trackVisibility vis,
     struct wigCartOptions *wigCart, struct pixelCountBin *pixelBins)
 /*	graph the preDraw array */
 {
 int x1;
 int h = tg->lineHeight;	/*	the height of our drawing window */
 double scaleFactor = h/graphRange;
 Color oldDrawColor = colorArray[0] + 1;	/* Just to be different from 1st drawColor. */
 Color mediumColor = MG_BLACK;	// Will be overriden
 Color lightColor = MG_BLACK;	// Will be overriden
@@ -879,70 +880,76 @@
 			&& width < winEnd-winStart);
 
 /* start new data for a new track, freez old data if exists */
 if (enableMouseOver)
     {
     if (mouseOverData)
 	{
 	mouseOverIdx = -1;
 	freez(&mouseOverData);
 	}
     AllocArray(mouseOverData, width);
     }
 
 int mouseOverX2 = -1;
 double previousValue = 0;
-boolean skipMouseOvers = TRUE;
+boolean skipMouseOvers = FALSE;
 #define epsilonLimit 1.0e-6
 
 /*	right now this is a simple pixel by pixel loop.  Future
  *	enhancements could draw boxes where pixels
  *	are all the same height in a run.
  */
 for (x1 = 0; x1 < width; ++x1)
     {
     int x = x1 + xOff;
     int preDrawIndex = x1 + preDrawZero;
     struct preDrawElement *p = &preDraw[preDrawIndex];
     /* ===== mouseOver calculations===== */
     if (enableMouseOver)
         {
         if (!skipMouseOvers && (p->count > 0)) /* checking mouseOver construction */
             {
-            if (p->count < 3)	/* allow 1 or 2 values to display */
+            if (p->count > 0)	/* allow any number of values to display */
                 {
                 double thisValue = p->sumData/p->count;	/* average if 2 */
                 if (mouseOverX2 < 0)    /* first valid data found */
                     {
                     ++mouseOverIdx;
                     mouseOverX2 = x1+1;
                     mouseOverData[mouseOverIdx].x1 = x1;
                     mouseOverData[mouseOverIdx].x2 = mouseOverX2;
                     mouseOverData[mouseOverIdx].value = thisValue;
+		    mouseOverData[mouseOverIdx].mean = FALSE;
+		    if (p->count > 1)
+			mouseOverData[mouseOverIdx].mean = TRUE;
                     previousValue = thisValue;
                     }
                 else	/* see if we need a new item */
                     {
                     if (fabs(thisValue - previousValue) > epsilonLimit)
                         {
                         /* finish off the existing run of data */
                         mouseOverData[mouseOverIdx].x2 = mouseOverX2;
                         mouseOverX2 = x1+1;
                         ++mouseOverIdx;
                         mouseOverData[mouseOverIdx].x1 = x1;
                         mouseOverData[mouseOverIdx].x2 = mouseOverX2;
                         mouseOverData[mouseOverIdx].value = thisValue;
+			mouseOverData[mouseOverIdx].mean = FALSE;
+			if (p->count > 1)
+			    mouseOverData[mouseOverIdx].mean = TRUE;
                         previousValue = thisValue;
                         }
                     else	/* continue run of same data value */
                         mouseOverX2 = x1+1;
                     }
                 }
             else
                 skipMouseOvers = TRUE;	/* has become too dense to make sense */
             }
         else  /* perhaps entered region without values after some data already */
             {
             if (mouseOverX2 > 0)	/* yes, been in data, end it here */
                 {
                 mouseOverData[mouseOverIdx].x2 = mouseOverX2;
                 mouseOverX2 = -1;	/* start over with new data when found */
@@ -1464,49 +1471,56 @@
     trashDirFile(&jsonData, "hgt", tg->track, ".json");
     FILE *trashJson = mustOpen(jsonData.forCgi, "w");
     struct jsonWrite *jw = jsonWriteNew();
     jsonWriteObjectStart(jw, NULL);
     jsonWriteListStart(jw, tg->track);
     int i;
     /* could put up a 'no data' box when these items are not contiguous
      *    e.g. when gaps interrupt the track data
      */
     for (i = 0; i <= mouseOverIdx; ++i)
         {
         jsonWriteObjectStart(jw, NULL);
         jsonWriteNumber(jw, "x1", (long long)mouseOverData[i].x1);
         jsonWriteNumber(jw, "x2", (long long)mouseOverData[i].x2);
         jsonWriteDouble(jw, "v", mouseOverData[i].value);
+        jsonWriteBoolean(jw, "m", mouseOverData[i].mean);
         jsonWriteObjectEnd(jw);
         }
     jsonWriteListEnd(jw);
     jsonWriteObjectEnd(jw);
     fputs(jw->dy->string,trashJson);
     carefulClose(&trashJson);
     mouseOverIdx = -1;
     freez(&mouseOverData);
     if (! beenHereDoneThat )
         {
         hPrintf("<div id='mouseOverVerticalLine' class='mouseOverVerticalLine'></div>\n");
         hPrintf("<div id='mouseOverText' class='mouseOverText'></div>\n");
 // hPrintf("<div id='mouseDbg'><span id='debugMsg'><p>. . . mouseDbg</p></span></div>\n");
         beenHereDoneThat = TRUE;
         }
     // hidden element to pass along jsonData file name and also the trigger
     // that this track has data to display.
     hPrintf("<div id='mouseOver_%s' name='%s' class='hiddenText mouseOverData' jsonData='%s'></div>\n", tg->track, tg->track, jsonData.forCgi);
     }
+// Might need something like this later for other purposes
+// else if (enableMouseOver)       // system enabled, but no data for this track
+//     {
+    /* signal to indicate zoom in required to see data */
+//     hPrintf("<div id='mouseOver_%s' name='%s' class='hiddenText mouseOverData'></div>\n", tg->track, tg->track);
+//     }
 
 wigMapSelf(tg, hvg, seqStart, seqEnd, xOff, yOff, width);
 }
 
 struct preDrawContainer *wigLoadPreDraw(struct track *tg, int seqStart, int seqEnd, int width)
 /* Do bits that load the predraw buffer tg->preDrawContainer. */
 {
 /* Just need to do this once... */
 if (tg->preDrawContainer)
     return tg->preDrawContainer;
 
 struct wigItem *wi;
 double pixelsPerBase = scaleForPixels(width);
 double basesPerPixel = 1.0;
 int itemCount = 0;