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;