5b4f3f94dc828128ddd13c8a192d7762b3f74878 kate Thu Oct 11 11:01:39 2018 -0700 Fix grab box peak location for all drawing modes. refs #21917 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index 14af2fb..c07e5bd 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -441,30 +441,36 @@ if (inter->value != 0.0) dyStringPrintf(ds, " %0.2f", inter->value); return dyStringCannibalize(&ds); } int regionFootWidth(int start, int end, double scale) /* Return half foot width in pixels */ { unsigned size = end - start; int width = scale * (double)size / 2; if (width == 0) width = 1; return width; } +/* Draw helper routines */ + +#define DRAW_LINE 0 +#define DRAW_CURVE 1 +#define DRAW_ELLIPSE 2 + static void drawFoot(struct track *tg, struct hvGfx *hvg, char *seq, int seqStart, int seqEnd, int x, int y, int width, Color color, boolean drawUp, struct hash *footHash) /* Draw interaction end, 2 pixels high. Force to black if it exactly overlaps another */ { char buf[256]; safef(buf, sizeof(buf), "%s:%d-%d", seq, seqStart, seqEnd); char *pos = cloneString(buf); Color footColor = color; if (hashLookup(footHash, pos)) footColor = MG_BLACK; else hashStore(footHash, pos); if (drawUp) y = flipY(tg, y) - 2; hvGfxBox(hvg, x, y, width, 2, footColor); @@ -494,51 +500,49 @@ if (!isEmptyTextField(item)) { char buf[256]; safef(buf, sizeof(buf),"foot=%s", cgiEncode(item)); clickArg = cloneString(buf); } char *itemBuf = isEmptyTextField(item) ? status : item; if (drawUp) y = flipY(tg, y) - 3; hvGfxBox(hvg, x-1, y, 3, 2, peakColor); hvGfxBox(hvg, x, y, 1, 1, highlightColor); mapBoxHgcOrHgGene(hvg, start, end, x - width, y, width * 2, 4, tg->track, item, itemBuf, NULL, TRUE, clickArg); } -void drawPeakMapbox(struct track *tg, struct hvGfx *hvg, int seqStart, int seqEnd, char *item, char *status, - int x, int y, Color peakColor, Color highlightColor, boolean drawUp) +void drawPeakMapbox(struct track *tg, struct hvGfx *hvg, int seqStart, int seqEnd, + char *item, char *status, int x, int y, + Color peakColor, Color highlightColor, boolean drawUp, int drawMode) /* Draw grab box and add map box */ { +int yAdjust = (drawMode == DRAW_CURVE ? 3 : 0); if (drawUp) - y = flipY(tg, y) - 3; + y = flipY(tg, y) - yAdjust; hvGfxBox(hvg, x-1, y-1, 3, 3, peakColor); hvGfxBox(hvg, x, y, 1, 1, highlightColor); mapBoxHgcOrHgGene(hvg, seqStart, seqEnd, x-1, y-1, 3, 3, tg->track, item, status, NULL, TRUE, NULL); } static void drawInteractItems(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw a list of interact items with connectors (e.g. curves) */ { -#define DRAW_LINE 0 -#define DRAW_CURVE 1 -#define DRAW_ELLIPSE 2 - // Determine drawing mode int draw = DRAW_LINE; boolean doDashes = FALSE; if (vis != tvDense) { char *drawMode = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, INTERACT_DRAW, INTERACT_DRAW_DEFAULT); if (sameString(drawMode, INTERACT_DRAW_CURVE)) draw = DRAW_CURVE; else if (sameString(drawMode, INTERACT_DRAW_ELLIPSE)) draw = DRAW_ELLIPSE; doDashes = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, INTERACT_DIRECTION_DASHES, INTERACT_DIRECTION_DASHES_DEFAULT); } double scale = scaleForWindow(width, seqStart, seqEnd); @@ -722,74 +726,74 @@ upperX = tOnScreen ? tX : xOff + width; } else { lowerX = tOnScreen ? tX : xOff; upperX = sOnScreen ? sX : xOff + width; } if (draw == DRAW_LINE || !sOnScreen || !tOnScreen || hvg->rc) { // draw horizontal line between region centers at 'peak' height drawLine(tg, hvg, lowerX, peak, upperX, peak, color, isReversed && doDashes, drawUp); // draw grab box and map box on mid-point of horizontal line int xMap = lowerX + (double)(upperX-lowerX)/2; drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, itemBuf, statusBuf, - xMap, peak, peakColor, highlightColor, drawUp); + xMap, peak, peakColor, highlightColor, drawUp, draw); continue; } // Draw curves if (draw == DRAW_CURVE) { int peakX = ((upperX - lowerX + 1) / 2) + lowerX; int fudge = 30; int peakY = peak + fudge; // admittedly a hack (obscure how to define ypeak of curve) int y1 = isReversed ? yTarget : ySource; int y2 = isReversed ? ySource : yTarget; if (drawUp) { y1 = flipY(tg, y1); y2 = flipY(tg, y2); peakY = flipY(tg, peakY); } int maxY = hvGfxCurve(hvg, lowerX, y1, peakX, peakY, upperX, y2, color, isReversed && doDashes); // curve drawer does not use peakY as expected, so it returns actual max Y used // draw grab box and map box on peak if (drawUp) maxY = (maxY - peakY)/2 + tg->customInt; drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf, - peakX, maxY, peakColor, highlightColor, drawUp); + peakX, maxY, peakColor, highlightColor, drawUp, draw); } else if (draw == DRAW_ELLIPSE) { // can not support offsets int yLeft = yOff + peakHeight; int yTop = yOff - peakHeight; int ellipseOrient = ELLIPSE_BOTTOM; if (drawUp) { ellipseOrient = ELLIPSE_TOP; yLeft = yOff + tg->height - peakHeight; yTop = yOff + tg->height + peakHeight; } hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ellipseOrient, isReversed && doDashes); // draw grab box and map box on peak int maxY = peakHeight + yOff; int peakX = ((upperX - lowerX + 1) / 2) + lowerX; drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf, - peakX, maxY, peakColor, highlightColor, drawUp); + peakX, maxY, peakColor, highlightColor, drawUp, draw); } } } void interactLinkedFeaturesDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw an item with target in contrasting color */ { struct linkedFeatures *lf = item; if (vis == tvDense) { lf->filterColor = slightlyDarkerColor(hvg, MG_GRAY); // can't distinguish overlapping colors, so force to gray }