374405106b2e246ff47079103aee676e413b7534
kate
  Wed Aug 15 16:11:04 2018 -0700
Adding 'foot' arg to click through, so interactions using same endpoint can be shown on details page.  Still need to add code to make use of bigBed indexing. refs #21917

diff --git src/hg/hgTracks/interactTrack.c src/hg/hgTracks/interactTrack.c
index 02b0a10..e939004 100644
--- src/hg/hgTracks/interactTrack.c
+++ src/hg/hgTracks/interactTrack.c
@@ -229,55 +229,66 @@
         if (labelStart <= prevLabelEnd && 
                 !(labelStart == prevLabelStart && labelEnd == prevLabelEnd && 
                     sameString(otherChrom, prevLabel)))
             tInfo->doOtherLabels = FALSE;
         prevLabelStart = labelStart;
         prevLabelEnd = labelEnd;
         prevLabel = otherChrom;
         }
     }
 tInfo->fontHeight = vgGetFontPixelHeight(hvg->vg, font);
 tInfo->otherHeight = (tInfo->otherCount) ? 3 * tInfo->fontHeight : 0;
 tInfo->sameHeight = (tInfo->sameCount) ? tg->height - tInfo->otherHeight : 0;
 return tInfo;
 }
 
+char *endpointClickArg(char *endpointName)
+/* Add var to identify endpoint ('foot'), or NULL if no name for endpoint */
+{
+if (isEmptyTextField(endpointName))
+    return NULL;
+char buf[256];
+safef(buf, sizeof(buf),"foot=%s", cgiEncode(endpointName));
+return(cloneString(buf));
+}
+
 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
 
 // Determine drawing mode
 int draw = DRAW_LINE;
 if (vis != tvDense)
     {
     char *drawMode = cartUsualStringClosestToHome(cart, tg->tdb, FALSE,
                                 INTERACT_DRAW, INTERACT_DRAW_DEFAULT);
     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 *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
 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);
 
@@ -315,53 +326,54 @@
         // draw the foot (2 pixels high)
         hvGfxBox(hvg, x - footWidth, yOffOther, footWidth + footWidth + 1, 2, color);
 
         // draw the vertical
         if (tInfo->isDirectional && differentString(inter->chrom, inter->sourceChrom))
             hvGfxDottedLine(hvg, x, yOffOther, x, yPos, color, TRUE);
         else
             hvGfxLine(hvg, x, yOffOther, x, yPos, color);
         
         if (vis == tvDense)
             continue;
 
         // add map box to foot
         char *nameBuf = (inter->chromStart == inter->sourceStart ?      
                         inter->sourceName : inter->targetName);
+        char *clickArg = endpointClickArg(nameBuf);
         if (isEmptyTextField(nameBuf))
             nameBuf = statusBuf;
-        int chromStart = inter->chromStart;
-        int chromEnd = inter->chromEnd;
+        chromStart = inter->chromStart;
+        chromEnd = inter->chromEnd;
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd,
                         x - footWidth, yOffOther, footWidth * 2, 4,
-                        tg->track, itemBuf, nameBuf, NULL, TRUE, NULL);
+                        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, NULL);
+                            height, tg->track, itemBuf, statusBuf, NULL, TRUE, clickArg);
         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, NULL);
+                    NULL, TRUE, clickArg);
             }
         continue;
         }
 
     // Draw same chromosome interaction
 
     // source region
     unsigned s = interactRegionCenter(inter->sourceStart, inter->sourceEnd);
     int sX = getX(s, seqStart, scale, xOff); 
     int sWidth = regionFootWidth(inter->sourceStart, inter->sourceEnd, scale);
     boolean sOnScreen = (s >= seqStart) && (s< seqEnd);
 
     // target region
     unsigned t = interactRegionCenter(inter->targetStart, inter->targetEnd);
     int tX = getX(t, seqStart, scale, xOff);
@@ -407,55 +419,61 @@
         hvGfxBox(hvg, tX - tWidth, yTarget, tWidth + tWidth + 1, 2, color);
         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;
-    int chromStart = inter->chromStart;
-    int chromEnd = inter->chromEnd;
+    chromStart = inter->chromStart;
+    chromEnd = inter->chromEnd;
     char *nameBuf = NULL;
     if (sOnScreen)
         {
         // add map box to source region
-        nameBuf = isEmptyTextField(inter->sourceName) ? statusBuf : inter->sourceName;
+        nameBuf = inter->sourceName;
+        char *clickArg = endpointClickArg(nameBuf);
+        if (isEmptyTextField(nameBuf))
+            nameBuf = statusBuf;
         //hvGfxBox(hvg, sX-1, yOff-1, 3, 3, peakColor); // needed ?
         hvGfxBox(hvg, sX-1, ySource, 3, 2, peakColor);
         hvGfxBox(hvg, sX, ySource, 1, 1, highlightColor);
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, 
                            sX - sWidth, ySource, sWidth * 2, 4,
-                           tg->track, itemBuf, nameBuf, NULL, TRUE, NULL);
+                           tg->track, itemBuf, nameBuf, NULL, TRUE, clickArg);
         }
     if (tOnScreen)
         {
         // add map box to target region
-        nameBuf = isEmptyTextField(inter->targetName) ? statusBuf : inter->targetName;
+        nameBuf = inter->targetName;
+        char *clickArg = endpointClickArg(nameBuf);
+        if (isEmptyTextField(nameBuf))
+            nameBuf = statusBuf;
         //hvGfxBox(hvg, tX-1, yTarget-1, 3, 3, tInfo->isDirectional ? MG_MAGENTA : peakColor);
         hvGfxBox(hvg, tX-1, yTarget, 3, 2, tInfo->isDirectional ? MG_MAGENTA : peakColor);
         hvGfxBox(hvg, tX, yTarget, 1, 1, highlightColor);
         mapBoxHgcOrHgGene(hvg, chromStart, chromEnd, 
                         //tX - tWidth, yTarget, tWidth * 2, 4,
                         tX - tWidth, yTarget, tWidth * 2, 3,
-                        tg->track, itemBuf, nameBuf, NULL, TRUE, NULL);
+                        tg->track, itemBuf, nameBuf, NULL, TRUE, clickArg);
         }
     if ((s < seqStart && t < seqStart) || (s > seqEnd && t > seqEnd))
         continue;
 
     // Draw interaction and map boxes
     int lowerX = 0, upperX = 0;
     if (s < t)
         {
         lowerX = sOnScreen ? sX : xOff;
         upperX = tOnScreen ? tX : xOff + width;
         }
     else
         {
         lowerX = tOnScreen ? tX : xOff;
         upperX = sOnScreen ? sX : xOff + width;