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);