6db4d4f2dcc485622fe4b22f33c796d708c6fdea kate Mon Mar 26 16:28:35 2018 -0700 Fixes to click handling. refs #17512 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index aee8b9d..1c2a482 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -95,53 +95,47 @@ { char buf[4096]; sprintLongWithCommas(buf, inter->chromEnd - inter->chromStart); dyStringPrintf(ds, "%s bp", buf); } } else dyStringPrintf(ds, "%s", inter->name); if (inter->score) dyStringPrintf(ds, " %d", inter->score); if (inter->value != 0.0) dyStringPrintf(ds, " %0.2f", inter->value); return dyStringCannibalize(&ds); } -int regionCenter(int start, int end) -/* Return center of genomic region */ -{ -return ((double)(end - start + .5) / 2) + start; -} - 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; } void interactRegionCenters(struct interact *inter, int *sourceCenter, int *targetCenter) /* Return genomic position of endpoint centers */ { assert(sourceCenter); assert(targetCenter); -*sourceCenter = regionCenter(inter->sourceStart, inter->sourceEnd); -*targetCenter = regionCenter(inter->targetStart, inter->targetEnd); +*sourceCenter = interactRegionCenter(inter->sourceStart, inter->sourceEnd); +*targetCenter = interactRegionCenter(inter->targetStart, inter->targetEnd); } int interactSize(struct interact *inter) /* Compute length of interaction (distance between middle of each region) in bp */ { int sourceCenter = 0, targetCenter = 0; interactRegionCenters(inter, &sourceCenter, &targetCenter); return abs(targetCenter - sourceCenter); } int getX(int pos, int seqStart, double scale, int xOff) /* Get x coordinate of a genomic location. Return -1 if off-screen */ { if (pos < seqStart) return -1; @@ -255,85 +249,87 @@ if (otherChrom) { // different chromosomes // draw below same chrom items, if any int height = 0; int yOffOther = yOff; if (vis == tvDense) { height = tg->height; } else { height = tInfo->otherHeight/2; yOffOther = yOff + tInfo->sameHeight; } - unsigned r = regionCenter(inter->chromStart, inter->chromEnd); + unsigned r = interactRegionCenter(inter->chromStart, inter->chromEnd); int x = getX(r, seqStart, scale, xOff); int footWidth = regionFootWidth(inter->chromStart, inter->chromEnd, scale); unsigned yPos = yOffOther + height; // draw the foot hvGfxLine(hvg, x - footWidth, yOffOther, x + footWidth, yOffOther, color); // draw the vertical if (tInfo->isDirectional && differentString(inter->chrom, inter->sourceChrom)) hvGfxDottedLine(hvg, x, yOffOther, x, yPos, color, TRUE); else hvGfxLine(hvg, x, yOffOther, x, yPos, color); if (vis == tvDense) continue; // add map box to foot char *nameBuf = (inter->chromStart == inter->sourceStart ? inter->sourceName : inter->targetName); if (isEmptyTextField(nameBuf)) nameBuf = statusBuf; - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, + int chromStart = inter->chromStart; + int chromEnd = inter->chromEnd; + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, x - footWidth, yOffOther, footWidth * 2, 4, tg->track, itemBuf, nameBuf, NULL, TRUE, NULL); // add map box to vertical - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, x - 2, yOffOther, 4, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, x - 2, yOffOther, 4, height, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); if (tInfo->doOtherLabels) { // draw label safef(buffer, sizeof buffer, "%s", sameString(inter->chrom, inter->sourceChrom) ? inter->targetChrom : inter->sourceChrom); hvGfxTextCentered(hvg, x, yPos + 2, 4, 4, MG_BLUE, font, buffer); int labelWidth = vgGetFontStringWidth(hvg->vg, font, buffer); // add map box to label - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, x - labelWidth/2, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, x - labelWidth/2, yPos, labelWidth, tInfo->fontHeight, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } continue; } // Draw same chromosome interaction // source region - unsigned s = regionCenter(inter->sourceStart, inter->sourceEnd); + unsigned s = interactRegionCenter(inter->sourceStart, inter->sourceEnd); int sX = getX(s, seqStart, scale, xOff); int sWidth = regionFootWidth(inter->sourceStart, inter->sourceEnd, scale); boolean sOnScreen = (s >= seqStart) && (s< seqEnd); // target region - unsigned t = regionCenter(inter->targetStart, inter->targetEnd); + unsigned t = interactRegionCenter(inter->targetStart, inter->targetEnd); int tX = getX(t, seqStart, scale, xOff); int tWidth = regionFootWidth(inter->targetStart,inter->targetEnd, scale); boolean tOnScreen = (t >= seqStart) && (t< seqEnd); boolean isReversed = (tInfo->isDirectional && t < s); int interSize = abs(t - s); int peakHeight = (tInfo->sameHeight - 15) * ((double)interSize / tInfo->maxSize) + 10; int peak = yOff + peakHeight; if (vis == tvDense) peak = yOff + tg->height; if (sOnScreen) { // draw foot of source region hvGfxLine(hvg, sX - sWidth, yOff, sX + sWidth, yOff, color); @@ -351,104 +347,106 @@ // draw foot of target region hvGfxLine(hvg, tX - tWidth, yOff, tX + tWidth, yOff, color); if (vis == tvDense || !sOnScreen || draw == DRAW_LINE) { // draw vertical if (isReversed) hvGfxDottedLine(hvg, tX, yOff, tX, peak, color, TRUE); else hvGfxLine(hvg, tX, yOff, tX, peak, color); } } if (vis == tvDense) continue; // Full mode: add map boxes and draw interaction + int chromStart = inter->chromStart; + int chromEnd = inter->chromEnd; char *nameBuf = NULL; if (sOnScreen) { // add map box to source region nameBuf = isEmptyTextField(inter->sourceName) ? statusBuf : inter->sourceName; hvGfxBox(hvg, sX-1, yOff, 3, 1, peakColor); hvGfxBox(hvg, sX, yOff, 1, 1, MG_WHITE); - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, sX - sWidth, yOff, sWidth * 2, 3, tg->track, itemBuf, nameBuf, NULL, TRUE, NULL); } if (tOnScreen) { // add map box to target region nameBuf = isEmptyTextField(inter->targetName) ? statusBuf : inter->targetName; hvGfxBox(hvg, tX-1, yOff, 3, 1, peakColor); hvGfxBox(hvg, tX, yOff, 1, 1, MG_WHITE); - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, tX - tWidth, yOff, tWidth * 2, 3, tg->track, itemBuf, nameBuf, NULL, TRUE, NULL); } // Draw interaction and map boxes int lowerX = 0, upperX = 0; if (s < t) { lowerX = sOnScreen ? sX : xOff; upperX = tOnScreen ? tX : xOff + width; } else { lowerX = tOnScreen ? tX : xOff; upperX = sOnScreen ? sX : xOff + width; } if (draw == DRAW_LINE || !sOnScreen || !tOnScreen) { // draw horizontal line between region centers at 'peak' height if (isReversed) hvGfxDottedLine(hvg, lowerX, peak, upperX, peak, color, TRUE); else hvGfxLine(hvg, lowerX, peak, upperX, peak, color); // map box on mid-point of horizontal line int xMap = lowerX + (double)(upperX-lowerX)/2; int yMap = peak-1; hvGfxBox(hvg, xMap, peak-1, 1, 3, peakColor); hvGfxBox(hvg, xMap, peak, 1, 1, MG_WHITE); - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, xMap-1, yMap, 3, 3, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, xMap-1, yMap, 3, 3, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); continue; } // Draw curves if (draw == DRAW_CURVE) { int peakX = ((upperX - lowerX + 1) / 2) + lowerX; int peakY = peak + 30; // admittedly a hack (obscure how to define ypeak of curve) int maxY = hvGfxCurve(hvg, lowerX, yOff, peakX, peakY, upperX, yOff, color, isReversed); // curve drawer does not use peakY as expected, so it returns actual max Y used // draw map box on peak hvGfxBox(hvg, peakX-1, maxY, 3, 1, peakColor); hvGfxBox(hvg, peakX, maxY, 1, 1, MG_WHITE); - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, peakX, maxY, 3, 1, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, peakX, maxY, 3, 1, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } else if (draw == DRAW_ELLIPSE) { int yLeft = yOff + peakHeight; int yTop = yOff - peakHeight; hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ELLIPSE_BOTTOM, isReversed); // draw map box on peak int maxY = peakHeight + yOff; int peakX = ((upperX - lowerX + 1) / 2) + lowerX; hvGfxBox(hvg, peakX-1, maxY, 3, 1, peakColor); hvGfxBox(hvg, peakX, maxY, 1, 1, MG_WHITE); - mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, peakX, maxY, 3, 1, + mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, peakX, maxY, 3, 1, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } } } void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, int height, boolean withCenterLabels, MgFont *font, Color color, enum trackVisibility vis) /* Override default */ { } void interactMethods(struct track *tg) /* Interact track type methods */