d6f591dd751bfa252163c710f614ddd2b4fb421b
kate
  Sun Aug 26 20:03:45 2018 -0700
Overlapping interactions. refs #21917

diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c
index e939004..4147ded 100644
--- src/hg/hgTracks/interactTrack.c
+++ src/hg/hgTracks/interactTrack.c
@@ -274,30 +274,32 @@
 
 double scale = scaleForWindow(width, seqStart, seqEnd);
 struct interact *inter = NULL;
 char buffer[1024];
 char itemBuf[2048];
 int chromStart, chromEnd;
 
 // Gather info for layout
 struct interactTrackInfo *tInfo = interactGetTrackInfo(tg, seqStart, hvg, xOff, font, scale);
 
 // Get spectrum range
 int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMin", "0"));
 int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tg->tdb, "scoreMax", "1000"));
 
 // Draw items
+struct hash *footHash = hashNew(0);
+char footBuf[256];
 for (inter = (struct interact *)tg->items; inter; inter = inter->next)
     {
     char *otherChrom = interactOtherChrom(inter);
     safef(itemBuf, sizeof itemBuf, "%s", inter->name);
     char *statusBuf = interactMouseover(inter, otherChrom);
 
     // Pick colors
 
     #define MG_LIGHT_MAGENTA    0xffffbbff
     #define MG_LIGHT_GRAY         0xff909090
     color = interactItemColor(tg, inter, hvg, scoreMin, scoreMax);
     if (vis == tvDense && otherChrom && color == MG_BLACK)
         // use highlight color for other chrom items in dense mode
         color = MG_LIGHT_MAGENTA;
     int peakColor = (color == MG_BLACK || tg->colorShades) ? MG_LIGHT_MAGENTA : MG_LIGHT_GRAY;
@@ -337,31 +339,31 @@
 
         // add map box to foot
         char *nameBuf = (inter->chromStart == inter->sourceStart ?      
                         inter->sourceName : inter->targetName);
         char *clickArg = endpointClickArg(nameBuf);
         if (isEmptyTextField(nameBuf))
             nameBuf = statusBuf;
         chromStart = inter->chromStart;
         chromEnd = inter->chromEnd;
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd,
                         x - footWidth, yOffOther, footWidth * 2, 4,
                         tg->track, itemBuf, nameBuf, NULL, TRUE, clickArg);
 
         // add map box to vertical
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, x - 2, yOffOther, 4, 
-                            height, tg->track, itemBuf, statusBuf, NULL, TRUE, clickArg);
+                            height, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
         if (tInfo->doOtherLabels)
             {
             // draw label
             safef(buffer, sizeof buffer, "%s", sameString(inter->chrom, inter->sourceChrom) ?
                                         inter->targetChrom : inter->sourceChrom);
             hvGfxTextCentered(hvg, x, yPos + 2, 4, 4, MG_BLUE, font, buffer);
             int labelWidth = vgGetFontStringWidth(hvg->vg, font, buffer);
 
             // add map box to label
             mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, x - labelWidth/2, 
                     yPos, labelWidth, tInfo->fontHeight, tg->track, itemBuf, statusBuf, 
                     NULL, TRUE, clickArg);
             }
         continue;
         }
@@ -388,47 +390,64 @@
         peak = yOff + tg->height;
 
     // NOTE: until time permits, force to rectangle when in reversed strand mode.
 
     int yTarget = yOff;
     int ySource = yOff;
     if (tInfo->offset && draw != DRAW_ELLIPSE)
         // ellipse code doesn't support assymetrical ends
         {
         int yOffset = tg->height/20 + 1;
         if (sameString(tInfo->offset, INTERACT_OFFSET_TARGET))
             yTarget = yOff + yOffset;
         else if (sameString(tInfo->offset, INTERACT_OFFSET_SOURCE))
             ySource = yOff + yOffset;
         }
+    unsigned footColor = color;
     if (sOnScreen)
         {
+        safef(footBuf, sizeof(footBuf), "%s:%d-%d", inter->sourceChrom,
+                                                        inter->sourceStart, inter->sourceEnd);
+        char *footPos = cloneString(footBuf);
+        if (hashLookup(footHash, footPos))
+            footColor = MG_BLACK;
+        else
+            hashStore(footHash, footPos);
+
         // draw foot of source region (2 pixels high)
-        hvGfxBox(hvg, sX - sWidth, ySource, sWidth + sWidth + 1, 2, color);
+        hvGfxBox(hvg, sX - sWidth, ySource, sWidth + sWidth + 1, 2, footColor);
         if (vis == tvDense || !tOnScreen || draw == DRAW_LINE || hvg->rc)
             {
             // draw vertical
             if (isReversed)
                 hvGfxDottedLine(hvg, sX, ySource, sX, peak, color, TRUE);
             else
                 hvGfxLine(hvg, sX, ySource, sX, peak, color);
             }
         }
     if (tOnScreen)
         {
+        safef(footBuf, sizeof(footBuf), "%s:%d-%d", inter->targetChrom,
+                                                        inter->targetStart, inter->targetEnd);
+        char *footPos = cloneString(footBuf);
+        if (hashLookup(footHash, footPos))
+            footColor = MG_BLACK;
+        else
+            hashStore(footHash, footPos);
+
         // draw foot of target region (2 pixels high)
-        hvGfxBox(hvg, tX - tWidth, yTarget, tWidth + tWidth + 1, 2, color);
+        hvGfxBox(hvg, tX - tWidth, yTarget, tWidth + tWidth + 1, 2, footColor);
         if (vis == tvDense || !sOnScreen || draw == DRAW_LINE || hvg->rc)
             {
             // draw vertical
             if (isReversed)
                 hvGfxDottedLine(hvg, tX, yTarget, tX, peak, color, TRUE);
             else
                 hvGfxLine(hvg, tX, yTarget, tX, peak, color);
             }
         }
     if (vis == tvDense)
         continue;
 
     // Full mode: add map boxes and draw interaction
     int highlightColor = MG_WHITE;
     chromStart = inter->chromStart;