5e55b76e29e2ac663dcfa4e288bd0caa701ab3da hiram Mon May 3 13:36:12 2021 -0700 adding mouseOverFunction trackDb variable and feature to turn off mouse over value display for averaged values refs #27457 diff --git src/hg/hgTracks/wigTrack.c src/hg/hgTracks/wigTrack.c index a49dea9..c2f4211 100644 --- src/hg/hgTracks/wigTrack.c +++ src/hg/hgTracks/wigTrack.c @@ -859,43 +859,51 @@ 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); struct wigMouseOver *mouseOverData = NULL; /* list of mouse over data, if created here */ boolean skipMouseOvers = TRUE; /* assuming not using */ int mouseOverX2 = -1; double previousValue = 0; if (enableMouseOver) skipMouseOvers = FALSE; +boolean noAverage = FALSE; +boolean dropMouseOverData = FALSE; // will become TRUE if noAverage + // condition is encountered +char *mouseOverFunction = trackDbSetting(tg->tdb, "mouseOverFunction"); +if (sameOk(mouseOverFunction, "noAverage")) + noAverage = 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) + if (enableMouseOver && !dropMouseOverData) { - if (!skipMouseOvers && (p->count > 0)) /* checking mouseOver construction */ + /* checking if mouseOver construction is allowed */ + if (!skipMouseOvers && (p->count > 0) && !(noAverage && p->count>1)) { if (p->count > 0) /* allow any number of values to display */ { double thisValue = p->sumData/p->count; /*average if count > 1*/ if (mouseOverX2 < 0) /* first valid data found */ { struct wigMouseOver *dataItem; AllocVar(dataItem); mouseOverX2 = x1+1; dataItem->x1 = x1; dataItem->x2 = mouseOverX2; dataItem->value = thisValue; dataItem->valueCount = p->count; slAddHead(&mouseOverData, dataItem); previousValue = thisValue; @@ -914,31 +922,34 @@ dataItem->x2 = mouseOverX2; dataItem->value = thisValue; dataItem->valueCount = p->count; slAddHead(&mouseOverData, dataItem); 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 */ + + if (noAverage && p->count>1) + dropMouseOverData = TRUE; + else if (mouseOverX2 > 0) /* yes, been in data, end it here */ { mouseOverData->x2 = mouseOverX2; mouseOverX2 = -1; /* start over with new data when found*/ } } /* potentially end the last mouseOver box */ if (mouseOverX2 > 0 && mouseOverX2 > mouseOverData->x2) mouseOverData->x2 = mouseOverX2; } // if (enableMouseOver) else skipMouseOvers = TRUE; /* ===== done with mouseOver calculations===== */ @@ -1140,53 +1151,55 @@ else if (vis == tvDense || vis == tvSquish) { double grayValue; int grayIndex; /* honor the viewLimits, data below is white, data above is black */ grayValue = max(dataValue,graphLowerLimit); grayValue = min(grayValue,graphUpperLimit); grayIndex = ((grayValue-graphLowerLimit)/graphRange)*MAX_WIG_VALUE; drawColor = tg->colorShades[grayInRange(grayIndex, 0, MAX_WIG_VALUE)]; doLine(image, x, yOff, tg->lineHeight, drawColor); } /* vis == tvDense || vis == tvSquish */ } /* if (preDraw[].count) */ } /* for (x1 = 0; x1 < width; ++x1) */ + +if (dropMouseOverData) + slFreeList(&mouseOverData); return(mouseOverData); } /* graphPreDraw() */ static struct wigMouseOver *graphPreDrawContainer(struct preDrawContainer *preDrawContainer, int preDrawZero, int width, struct track *tg, struct hvGfx *hvg, int xOff, int yOff, double graphUpperLimit, double graphLowerLimit, double graphRange, enum trackVisibility vis, struct wigCartOptions *wigCart) /* Draw the graphs for all tracks in container. */ { double epsilon = graphRange / tg->lineHeight; struct preDrawElement *preDraw = preDrawContainer->preDraw; Color *colorArray = makeColorArray(preDraw, width, preDrawZero, wigCart, tg, hvg); struct wigGraphOutput *wgo = tg->wigGraphOutput; struct wigMouseOver *mouseOverData = graphPreDraw(preDraw, preDrawZero, width, tg, wgo->image, wgo->vLine, wgo->xOff, wgo->yOff, wgo->yOffsets, wgo->numTrack, graphUpperLimit, graphLowerLimit, graphRange, epsilon, colorArray, vis, wigCart, wgo->pixelBins); freez(&colorArray); return mouseOverData; } - void drawZeroLine(enum trackVisibility vis, enum wiggleGridOptEnum horizontalGrid, double graphUpperLimit, double graphLowerLimit, struct hvGfx *hvg, int xOff, int yOff, int width, int lineHeight) /* draw a line at y=0 on the graph */ { /* Do we need to draw a zero line ? * This is to be generalized in the future to allow horizontal grid * lines, perhaps user specified to indicate thresholds. */ if ((vis == tvFull) && (horizontalGrid == wiggleHorizontalGridOn)) { Color black = hvGfxFindColorIx(hvg, 0, 0, 0); int x1, x2, y1, y2; @@ -1447,39 +1460,40 @@ { jsonWriteObjectStart(mouseOverJson, NULL); jsonWriteNumber(mouseOverJson, "x1", (long long)dataItem->x1); jsonWriteNumber(mouseOverJson, "x2", (long long)dataItem->x2); jsonWriteDouble(mouseOverJson, "v", dataItem->value); jsonWriteNumber(mouseOverJson, "c", dataItem->valueCount); jsonWriteObjectEnd(mouseOverJson); } jsonWriteListEnd(mouseOverJson); jsonWriteObjectEnd(mouseOverJson); slFreeList(&mouseOverData); // hidden element to pass along jsonUrl file name and also the trigger // that this track has data to display. hPrintf("<div id='mouseOver_%s' name='%s' class='hiddenText mouseOverData' jsonUrl='%s'></div>\n", tg->track, tg->track, mouseOverJsonFile->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); -// } +else if (enableMouseOver) + { + jsonWriteObjectStart(mouseOverJson, tg->track); + jsonWriteString(mouseOverJson, "t", tg->tdb->type); + jsonWriteString(mouseOverJson, "mo", "noAverage"); + jsonWriteObjectEnd(mouseOverJson); + } wigMapSelf(tg, hvg, seqStart, seqEnd, xOff, yOff, width); -} +} /* void wigDrawPredraw() */ 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; char *currentFile = NULL; //char *currentFileRewrite = NULL; struct udcFile *wibFH = NULL; /* file handle to binary file */