442fef159db4b61a41789813c9068776ef2f8cfb kate Mon Sep 17 19:39:24 2018 -0700 Pack mode. refs #21917 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index f0ce9e1..0e55e1a 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -1,23 +1,24 @@ /* interactTrack -- draw interaction between two genomic regions */ /* Copyright (C) 2018 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "obscure.h" #include "hgTracks.h" +#include "bedCart.h" #include "bigWarn.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); return tg->height = current; } @@ -47,31 +48,31 @@ boolean interactSourceInWindow(struct interact *inter) /* True if midpoint of source is on screen */ { unsigned s = interactRegionCenter(inter->sourceStart, inter->sourceEnd); return (s >= winStart) && (s < winEnd); } boolean interactTargetInWindow(struct interact *inter) /* True if midpoint of target is on screen */ { unsigned t = interactRegionCenter(inter->targetStart, inter->targetEnd); return (t >= winStart) && (t < winEnd); } -void interactLoadItems(struct track *tg) +static void loadAndFilterItems(struct track *tg) /* Load all interact items in region */ { loadSimpleBedWithLoader(tg, (bedItemLoader)interactLoadAndValidate); if (slCount(tg->items) == 0 && tg->limitedVisSet) { // too many items to display // borrowed behaviors in bamTrack and vcfTrack // TODO BRANEY: make this behavior generic for bigBeds // (bigBedSelectRange) tg->drawItems = bigDrawWarning; tg->networkErrMsg = "Too many items in display (zoom in)"; tg->totalHeight = bigWarnTotalHeight; return; } @@ -99,43 +100,82 @@ { if (!(sOnScreen || tOnScreen)) continue; } } slAddHead(&filteredItems, inter); } slReverse(&filteredItems); // consider sorting by score/value so highest scored items draw last (on top) if (slCount(filteredItems) != count) labelTrackAsFiltered(tg); tg->items = filteredItems; } -void interactLoadBedItems(struct track *tg) -/* Load interact items as linked features */ +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 interactFreeItems(struct track *tg) +/* Free up interact items track */ +{ +interactFreeList((struct interact **)(&tg->items)); +} + +static boolean isBedMode(struct track *tg) +/* Pack and squish modes display using BED linked features code */ { -interactLoadItems(tg); +return tg->visibility == tvPack || tg->visibility == tvDense; +} + +void interactLoadItems(struct track *tg) +/* Load interact items in interact format */ +{ +loadAndFilterItems(tg); +if (isBedMode(tg)) + { + /* convert to BEDs for linked feature display */ struct interact *inters = tg->items, *inter; -struct bed *beds = NULL, *bed; + struct linkedFeatures *lfs = NULL, *lf; for (inter = inters; inter; inter = inter->next) { - bed = interactToBed(inter); - slAddHead(&beds, bed); + struct bed *bed = interactToBed(inter); + lf = lfFromBed(bed); + if (!tg->colorShades) + { + lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */ + lf->filterColor = bed->itemRgb; + } + bedFree(&bed); + // TODO: use lfFromBedExtra with scoreMin, scoreMax + slAddHead(&lfs, lf); + } + slReverse(&lfs); + tg->items = lfs; + } +else + { + tg->mapsSelf = TRUE; + tg->totalHeight = interactTotalHeight; + tg->drawLeftLabels = interactDrawLeftLabels; + tg->freeItems = interactFreeItems; } -slReverse(&beds); -tg->items = beds; } char *interactMouseover(struct interact *inter, char *otherChrom) /* Make mouseover text for an interaction */ { struct dyString *ds = dyStringNew(0); if (isEmptyTextField(inter->name)) { if (!isEmptyTextField(inter->exp)) dyStringPrintf(ds, "%s ", inter->exp); if (otherChrom) dyStringPrintf(ds, "%s", otherChrom); else { char buf[4096]; @@ -324,31 +364,31 @@ 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) /* Draw grab box and add map box */ { if (drawUp) y = flipY(tg, y); 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); } -void interactDrawItems(struct track *tg, int seqStart, int seqEnd, +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 structures. */ { #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); @@ -586,49 +626,44 @@ 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); } } } -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 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. */ { +if (isBedMode(tg)) + { + tg->drawItemAt = linkedFeaturesDrawAt; + linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); + } +else + drawInteractItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } void interactMethods(struct track *tg) /* Interact track type methods */ { -tg->canPack = TRUE; -if (tg->visibility == tvPack) -//if (1) - { - bedMethods(tg); - tg->loadItems = interactLoadBedItems; - } -else - { +tg->bedSize = 12; +linkedFeaturesMethods(tg); // for pack and squish modes 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); }