61b8f9bb3cd7d2b67e8c698c9657efd6df58b309
hiram
  Thu Nov 12 20:52:14 2020 -0800
better isolation of the mouseOver calculations refs #21980

diff --git src/hg/hgTracks/wigTrack.c src/hg/hgTracks/wigTrack.c
index f73de33..2784455 100644
--- src/hg/hgTracks/wigTrack.c
+++ src/hg/hgTracks/wigTrack.c
@@ -867,75 +867,76 @@
     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
 Color clipColor = MG_MAGENTA;
 enum wiggleTransformFuncEnum transformFunc = wigCart->transformFunc;
 enum wiggleGraphOptEnum lineBar = wigCart->lineBar;
 boolean whiskers = (wigCart->windowingFunction == wiggleWindowingWhiskers
 			&& width < winEnd-winStart);
 
+boolean skipMouseOvers = FALSE;
 /* 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 = FALSE;
-#define epsilonLimit 1.0e-6
+else
+    skipMouseOvers = TRUE;
 
 /*	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)
         {
+	int mouseOverX2 = -1;
+	double previousValue = 0;
         if (!skipMouseOvers && (p->count > 0)) /* checking mouseOver construction */
             {
             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].valueCount = p->count;
                     previousValue = thisValue;
                     }
                 else	/* see if we need a new item */
                     {
+#define epsilonLimit 1.0e-6
                     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].valueCount = p->count;
                         previousValue = thisValue;
                         }
                     else	/* continue run of same data value */
                         mouseOverX2 = x1+1;
                     }
@@ -1590,57 +1591,63 @@
  *
  *	The data to be drawn: to be read from file f at offset wi->Offset
  *	data points available: wi->Count, representing wi->Span bases
  *	for each data point
  *
  *	The drawing window, in pixels:
  *	xOff = left margin, yOff = top margin, h = height of drawing window
  *	drawing window in chrom coords: seqStart, seqEnd
  *      'basesPerPixel' is known, 'pixelsPerBase' is known
  */
         /*      let's check end point screen coordinates.  If they are
          *      the same, then this entire data block lands on one pixel,
          *      no need to walk through it, just use the block's specified
          *      max/min.  It is OK if these end up + or - values, we do want to
          *      keep track of pixels before and after the screen for
-         *      later smoothing operations.
+         *      later smoothing operations.  x1d,x2d are pixel coordinates
          */
 double x1d = (double)(wi->start - seqStart) * pixelsPerBase;
-        x1 = round(x1d);
 double x2d = (double)((wi->start+(wi->count * usingDataSpan))-seqStart) * pixelsPerBase;
-	x2 = round(x2d);
 
         /* this used to be if (x2 > x1) which often caused reading of blocks
 	 * when they were merely x2 = x1 + 1 due to rounding errors as
 	 * they became integers.  This double comparison for something over
 	 * 0.5 will account for rounding errors that are really small, but
 	 * still handle a slipping window size as it walks across the screen
 	 */
 	if ((x2d - x1d) > 0.5)
 	    {
 	    unsigned char *readData;	/* the bytes read in from the file */
 	    udcSeek(wibFH, wi->offset);
 	    readData = (unsigned char *) needMem((size_t) (wi->count + 1));
 	    udcRead(wibFH, readData,
 		(size_t) wi->count * (size_t) sizeof(unsigned char));
-	    /*	walk through all the data in this block	*/
+	    /*	walk through all the data in this wiggle data block	*/
 	    for (dataOffset = 0; dataOffset < wi->count; ++dataOffset)
 		{
 		unsigned char datum = readData[dataOffset];
 		if (datum != WIG_NO_DATA)
 		    {
+		    /* (wi->start-seqStart) == base where this wiggle data block
+		     *	begins.  Add to that (dataOffset * usingDataSpan) which
+		     *	is how many bases this specific datum is from the start
+		     *	of this wiggle data block.
+		     * x1,x2 are the pixel begin and end for this data item */
 		    x1 = ((wi->start-seqStart) + (dataOffset * usingDataSpan)) * pixelsPerBase;
+		    /* (usingDataSpan * pixelsPerBase) is the number of pixels
+		     *	occupied by this one data item
+		     */
 		    x2 = x1 + (usingDataSpan * pixelsPerBase);
 		    for (i = x1; i <= x2; ++i)
 			{
 			int xCoord = preDrawZero + i;
 			if ((xCoord >= 0) && (xCoord < preDrawSize))
 			    {
 			    double dataValue =
 			       BIN_TO_VALUE(datum,wi->lowerLimit,wi->dataRange);
 
 			    ++preDraw[xCoord].count;
 			    if (dataValue > preDraw[xCoord].max)
 				preDraw[xCoord].max = dataValue;
 			    if (dataValue < preDraw[xCoord].min)
 				preDraw[xCoord].min = dataValue;
 			    preDraw[xCoord].sumData += dataValue;