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("
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("
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("
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("
IN s=%d, e=%d, sOn: %d, eOn: %d. ", s, e, sOnScreen, eOnScreen);
-//if (s>e)
- //uglyf("
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);
+}
+