ce8ecbbd267e3cd3f1c9bb24ace346e61fbe9019 kate Thu Oct 18 11:27:36 2018 -0700 Fix some issues with linked features display (tall region). refs #21917 diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c index 6fc8280..9bd7e92 100644 --- src/hg/hgTracks/interactTrack.c +++ src/hg/hgTracks/interactTrack.c @@ -139,43 +139,64 @@ lf->original = ends; // coopt this void * field (would have preferred to use extra) } static struct interactLfEndNames *getInteractLfEndNames(struct linkedFeatures *lf) /* Retrieve endpoint names from linked feature */ { return (struct interactLfEndNames *)lf->original; } void interactFreeItems(struct track *tg) /* Free up interact items track */ { interactFreeList((struct interact **)(&tg->items)); } +void interactLfSortAndBound(struct linkedFeatures *lf) +/* Sort simpleFeatures in the linkedFeature and set start and end based on simpleFetaures */ +// TODO: dedupe the simpleFeatures ? +{ +struct simpleFeature *sfLast, *sf, *sfs = lf->components; +slSort(&sfs, simpleFeatureCmp); +lf->components = sfs; +sfLast = (struct simpleFeature *)slLastEl(sfs); +int start = sfs->start; +int end = sfLast->end; +for (sf = sfs; sf != NULL; sf = sf->next) + { + if (sf->start < start) + start = sf->start; + if (sf->end > end) + end = sf->end; + } +lf->start = start; +lf->end = end; +} + static struct linkedFeatures *interactToLf(struct interact *inter, boolean doColor) /* Convert interact BED to linkedFeatures */ { struct bed *bed = interactToBed(inter); struct linkedFeatures *lf = lfFromBed(bed); // save source and target names to extra field of linked feature, so we can display them // in pack mode // TODO: code to free setInteractLfEndNames(lf, cloneString(inter->sourceName), cloneString(inter->targetName)); // not sure why this is needed -- lfFromBed seems to reorder blocks, sometimes ? -linkedFeaturesSortAndBound(lf); +interactLfSortAndBound(lf); if (doColor) { lf->extra = (void *)USE_ITEM_RGB; /* signal for coloring */ lf->filterColor = bed->itemRgb; } bedFree(&bed); return lf; } static boolean isLinkedFeaturesMode(struct track *tg) /* Determine if linked feature display will be used */ { return (tg->visibility != tvFull); } @@ -392,31 +413,31 @@ } else { lf->orientation = 0; } slAddHead(&lfs, lf); } } if (tInfo->clusterMode) { // sort simplefeatures and adjust bounds of clustered features struct hashEl *el, *els = hashElListHash(intersCluster); for (el = els; el; el = el->next) { lf = (struct linkedFeatures *)el->val; - linkedFeaturesSortAndBound(lf); + interactLfSortAndBound(lf); slAddHead(&lfs, lf); } slSort(&lfs, linkedFeaturesCmp); } else { slReverse(&lfs); } tg->items = lfs; // TODO: consider freeing interact items } char *interactMouseover(struct interact *inter, char *otherChrom) /* Make mouseover text for an interaction */ { @@ -793,66 +814,60 @@ 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 } struct interactTrackInfo *tInfo = tg->customPt; linkedFeaturesDrawAt(tg, item, hvg, xOff, y, scale, font, color, vis); -// draw overlapping items in white and add right label if (tInfo->clusterMode) { struct simpleFeature *sf; int shortHeight = tg->heightPer/2; for (sf = lf->components; sf; sf = sf->next) { if (sf->start > lf->tallStart && sf->end < lf->tallEnd) { drawScaledBox(hvg, sf->start, sf->end, scale, xOff, y + shortHeight/2, shortHeight, MG_WHITE); } } } else { struct simpleFeature *sf1 = lf->components, *sf2 = sf1->next; - if (sf2 && sf2->start < sf1->end) - { + if (sf2->start > lf->tallStart && sf2->end < lf->tallEnd) drawScaledBox(hvg, sf2->start, sf2->end, scale, xOff, y, tg->heightPer, MG_WHITE); - } - else - { if (vis == tvPack || vis == tvFull) { - // right label + // add right label int x2 = round((double)((int)lf->end - winStart) * scale) + xOff; int x = x2 + tl.mWidth/2; struct interactLfEndNames *ends = getInteractLfEndNames(lf); char *rightLabel = (lf->orientation < 0 ? ends->source : ends->target); int w = mgFontStringWidth(font, rightLabel); hvGfxTextCentered(hvg, x, y, w, tg->heightPer, color, font, rightLabel); } } } -} 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. */ { struct interactTrackInfo *tInfo = (struct interactTrackInfo *)tg->customPt; if (tInfo->clusterMode || isLinkedFeaturesMode(tg)) { tg->drawItemAt = interactLinkedFeaturesDrawAt; linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis); } else // curve, etc. connector display drawInteractItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis);