6f726d2bcdb4fca993c06cf2181dce97b061702d kate Thu Feb 22 08:59:49 2018 -0800 Add support for custom tracks and hub tracks. refs #17512 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index 6ad7e43..e519d3e 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -5,182 +5,166 @@ #include "common.h" #include "hgTracks.h" #include "interact.h" #include "interactUi.h" static int interactTotalHeight(struct track *tg, enum trackVisibility vis) /* calculate height of all the interactions being displayed */ { if ( tg->visibility == tvDense) return tl.fontHeight; int min, max, deflt, current; cartTdbFetchMinMaxPixels(cart, tg->tdb, INTERACT_MINHEIGHT, INTERACT_MAXHEIGHT, atoi(INTERACT_DEFHEIGHT), &min, &max, &deflt, ¤t); -//uglyf("IN totalHeight=%d. ", current); -// FIXME DEBUG -//return 300; return tg->height = current; } static Color interactItemColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color to draw an interaction */ { struct interact *inter = item; struct rgbColor itemRgb; // There must be a better way... itemRgb.r = (inter->color & 0xff0000) >> 16; itemRgb.g = (inter->color & 0xff00) >> 8; itemRgb.b = inter->color & 0xff; -//uglyf("IN color=%X", hvGfxFindColorIx(hvg, itemRgb.r, itemRgb.g, itemRgb.b)); return hvGfxFindColorIx(hvg, itemRgb.r, itemRgb.g, itemRgb.b); } void interactLoadItems(struct track *tg) /* Load all interact items in region */ { loadSimpleBedWithLoader(tg, (bedItemLoader)interactLoad); } static void interactDrawItems(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 structures. */ { #define DRAW_LINE 0 #define DRAW_CURVE 1 #define DRAW_ELLIPSE 2 char *drawMode = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, INTERACT_DRAW, INTERACT_DRAW_DEFAULT); int draw = DRAW_LINE; if (sameString(drawMode, INTERACT_DRAW_CURVE)) draw = DRAW_CURVE; else if (sameString(drawMode, INTERACT_DRAW_ELLIPSE)) draw = DRAW_ELLIPSE; double scale = scaleForWindow(width, seqStart, seqEnd); struct interact *inters = tg->items; -//uglyf("Found %d items. ", slCount(inters)); unsigned int maxWidth = 0; struct interact *inter; char buffer[1024]; char itemBuf[2048]; safef(buffer, sizeof buffer, "%s.%s", tg->tdb->track, INTERACT_MINSCORE); -//double minScore = sqlDouble(cartUsualString(cart, buffer, INTERACT_DEFMINSCORE)); // Determine if there are mixed inter and intra-chromosomal // Suppress interchromosomal labels if they overlap int nSame = 0, nOther = 0; int prevLabelEnd = 0, prevLabelStart = 0; char *prevLabel = 0; boolean doOtherLabels = TRUE; char *otherChrom = NULL; for (inter=inters; inter; inter=inter->next) { int width = inter->chromEnd - inter->chromStart; if (width > maxWidth) maxWidth = width; } -//uglyf("Max width is %d. ", maxWidth); for (inter=inters; inter; inter=inter->next) { otherChrom = interactOtherChrom(inter); if (otherChrom == NULL) nSame++; else { nOther++; if (!doOtherLabels) continue; int labelWidth = vgGetFontStringWidth(hvg->vg, font, otherChrom); // TODO: simplify now that center approach is abandoned int sx = ((inter->chromStart - seqStart) + .5) * scale + xOff; // x coord of center int labelStart = (double)sx - labelWidth/2; int labelEnd = labelStart + labelWidth - 1; if (labelStart <= prevLabelEnd && !(labelStart == prevLabelStart && labelEnd == prevLabelEnd && sameString(otherChrom, prevLabel))) doOtherLabels = FALSE; prevLabelStart = labelStart; prevLabelEnd = labelEnd; prevLabel = otherChrom; } } int fontHeight = vgGetFontPixelHeight(hvg->vg, font); int otherHeight = (nOther) ? 3 * fontHeight : 0; int sameHeight = (nSame) ? tg->height - otherHeight: 0; // Draw items -//uglyf("IN seqStart=%d", seqStart); for (inter=inters; inter; inter=inter->next) { char *otherChrom = interactOtherChrom(inter); safef(itemBuf, sizeof itemBuf, "%s", inter->name); struct dyString *ds = dyStringNew(0); dyStringPrintf(ds, "%s", inter->name); if (inter->score) dyStringPrintf(ds, " %d", inter->score); char *statusBuf = dyStringCannibalize(&ds); -//uglyf("statusBuf: %s. ", statusBuf); color = interactItemColor(tg, inter, hvg); // TODO: simplify by using start/end instead of center and width // This is a holdover from longRange track implementation unsigned lowStart, lowEnd, highStart, highEnd; if (otherChrom) { lowStart = inter->chromStart; lowEnd = inter->chromEnd; } else if (inter->sourceStart < inter->targetStart) { lowStart = inter->sourceStart; lowEnd = inter->sourceEnd; highStart = inter->targetStart; highEnd = inter->targetEnd; } else { lowStart = inter->targetStart; lowEnd = inter->targetEnd; highStart = inter->sourceStart; highEnd = inter->sourceEnd; } unsigned s = lowStart + ((double)(lowEnd - lowStart + .5) / 2); int sx = ((s - seqStart) + .5) * scale + xOff; // x coord of center (lower region) -//uglyf("<br>IN seqStart=%d, start=%d, start1=%d, end1=%d, start2=%d, end2=%d, end=%d, s=%d, sx=%d. ", - //seqStart, inter->chromStart, inter->chromStart1, inter->chromEnd1, - //inter->chromStart2, inter->chromEnd2, inter->chromEnd, s, sx); unsigned sw = lowEnd - lowStart; int sFootWidth = scale * (double)sw / 2; // width in pixels of half foot (lower) if (sFootWidth == 0) sFootWidth = 1; unsigned e = highStart + (double)(highEnd - highStart + .5) / 2; int ex = ((e - seqStart) + .5) * scale + xOff; unsigned ew = highEnd - highStart; int eFootWidth = scale * (double)ew / 2; if (eFootWidth == 0) eFootWidth = 1; -//uglyf("<br>IN s=%d, sx=%d, sw=%d, sFootWidth=%d. e=%d, ex=%d, ew=%d, eFootWidth=%d, chromStart=%d", - //s, sx, sw, sFootWidth, e, ex, ew, eFootWidth, inter->chromStart); -//uglyf("<br> IN start1=%d, end1=%d, start2=%d, end2=%d.", - //inter->chromStart1, inter->chromEnd1, inter->chromStart2, inter->chromEnd2); if (otherChrom) { // different chromosomes // draw below same chrom items, if any unsigned yPos = 0; int height = 0; int yOffOther = yOff; if (tg->visibility == tvDense) { height = tg->height; } else { height = otherHeight/2; @@ -214,35 +198,30 @@ inter->targetChrom : inter->sourceChrom); hvGfxTextCentered(hvg, sx, yPos + 2, 4, 4, MG_BLUE, font, buffer); int width = vgGetFontStringWidth(hvg->vg, font, buffer); // add mapBox to label mapBoxHgcOrHgGene(hvg, inter->chromStart, inter->chromEnd, sx - width/2, yPos, width, fontHeight, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } } continue; } // draw same chromosome interaction boolean sOnScreen = (s >= seqStart) && (s < seqEnd); boolean eOnScreen = (e >= seqStart) && (e < seqEnd); -//uglyf("<br>IN s=%d, e=%d, sOn: %d, eOn: %d. ", s, e, sOnScreen, eOnScreen); -//if (s>e) - //uglyf("<br> IN s>e start=%d, start1=%d, end1=%d, start2=%d, end2=%d, end=%d, s=%d, sx=%d. ", - //inter->chromStart, inter->chromStart1, inter->chromEnd1, - //inter->chromStart2, inter->chromEnd2, inter->chromEnd, s, sx); double interWidth = e - s; int peakHeight = (sameHeight - 15) * ((double)interWidth / maxWidth) + 10; int peak = yOff + peakHeight; if (tg->visibility == tvDense) peak = yOff + tg->height; if (sOnScreen) { // draw foot of lower region hvGfxLine(hvg, sx - sFootWidth, yOff, sx + sFootWidth, yOff, color); // draw vertical if (!eOnScreen || draw == DRAW_LINE) { if (inter->chromStart == inter->targetStart) @@ -339,24 +318,28 @@ } } } 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 */ { -//tg->bedSize = 6; -//bedMethods(tg); tg->loadItems = interactLoadItems; tg->drawItems = interactDrawItems; tg->drawLeftLabels = interactDrawLeftLabels; tg->totalHeight = interactTotalHeight; tg->mapsSelf = TRUE; } +void interactCtMethods(struct track *tg) +/* Interact track methods for custom track */ +{ +interactMethods(tg); +} +