5199438a1019eff8b60a3f9bc404b6494ed800c2
braney
  Tue May 9 07:41:33 2017 -0700
Add menus to do sorting on custom composites.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index c670623..3ef530b 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -80,30 +80,31 @@
  * variables are not hgt. qualified.  It's a good idea if other
  * program's unique variables be qualified with a prefix though. */
 char *excludeVars[] = { "submit", "Submit", "dirty", "hgt.reset",
             "hgt.in1", "hgt.in2", "hgt.in3", "hgt.inBase",
             "hgt.out1", "hgt.out2", "hgt.out3", "hgt.out4",
             "hgt.left1", "hgt.left2", "hgt.left3",
             "hgt.right1", "hgt.right2", "hgt.right3",
             "hgt.dinkLL", "hgt.dinkLR", "hgt.dinkRL", "hgt.dinkRR",
             "hgt.tui", "hgt.hideAll", "hgt.visAllFromCt",
 	    "hgt.psOutput", "hideControls", "hgt.toggleRevCmplDisp",
 	    "hgt.collapseGroups", "hgt.expandGroups", "hgt.suggest",
 	    "hgt.jump", "hgt.refresh", "hgt.setWidth",
             "hgt.trackImgOnly", "hgt.ideogramToo", "hgt.trackNameFilter", "hgt.imageV1", "hgt.suggestTrack", "hgt.setWidth",
              TRACK_SEARCH,         TRACK_SEARCH_ADD_ROW,     TRACK_SEARCH_DEL_ROW, TRACK_SEARCH_PAGER,
             "hgt.contentType", "hgt.positionInput", "hgt.internal",
+            "sortExp", "sortSim",
             NULL };
 
 /* These variables persist from one incarnation of this program to the
  * next - living mostly in the cart. */
 boolean baseShowPos;           /* TRUE if should display full position at top of base track */
 boolean baseShowAsm;           /* TRUE if should display assembly info at top of base track */
 boolean baseShowScaleBar;      /* TRUE if should display scale bar at very top of base track */
 boolean baseShowRuler;         /* TRUE if should display the basic ruler in the base track (default) */
 char *baseTitle = NULL;        /* Title it should display top of base track (optional)*/
 static char *userSeqString = NULL;  /* User sequence .fa/.psl file. */
 
 /* These variables are set by getPositionFromCustomTracks() at the very
  * beginning of tracksDisplay(), and then used by loadCustomTracks(). */
 char *ctFileName = NULL;    /* Custom track file. */
 struct customTrack *ctList = NULL;  /* Custom tracks. */
@@ -8300,43 +8301,46 @@
                 hPrintf("<th align=\"left\" colspan=%d class='blueToggleBar'>",MAX_CONTROL_COLUMNS);
             else
                 hPrintf("<th align=\"left\" colspan=%d class='blueToggleBar'>",
                         MAX_CONTROL_COLUMNS-1);
 
             hPrintf("<table style='width:100%%;'><tr><td style='text-align:left;'>");
             hPrintf("\n<A NAME=\"%sGroup\"></A>",group->name);
 
 	    char idText[256];
 	    safef(idText, sizeof idText, "%s_button", group->name);
             hPrintf("<IMG class='toggleButton'"
                     " id='%s' src=\"%s\" alt=\"%s\" title='%s this group'>&nbsp;&nbsp;",
                     idText, indicatorImg, indicator,isOpen?"Collapse":"Expand");
 	    jsOnEventByIdF("click", idText, "return vis.toggleForGroup(this, '%s');", group->name);
 
-            hPrintf("</td><td style='text-align:center; width:90%%;'>\n<B>%s</B>", group->label);
-            hPrintf("</td><td style='text-align:right;'>\n");
             if (isHubTrack(group->name))
 		{
                 if (strstr(group->label, "Composite"))
                     {
                     safef(idText, sizeof idText, "%s_edit", group->name);
                     hPrintf("<input name=\"hubEditButton\" id='%s'"
                         " type=\"button\" value=\"edit\">\n", idText);
                     jsOnEventByIdF("click", idText,
                         "document.editHubForm.submit();return true;");
                     }
+                }
 
+            hPrintf("</td><td style='text-align:center; width:90%%;'>\n<B>%s</B>", group->label);
+            hPrintf("</td><td style='text-align:right;'>\n");
+            if (isHubTrack(group->name))
+		{
 		safef(idText, sizeof idText, "%s_disconn", group->name);
                 hPrintf("<input name=\"hubDisconnectButton\" id='%s'"
                     " type=\"button\" value=\"disconnect\">\n", idText);
 		jsOnEventByIdF("click", idText,
                     "document.disconnectHubForm.elements['hubId'].value='%s';"
                     "document.disconnectHubForm.submit();return true;",
 		    group->name + strlen(hubTrackPrefix));
 		}
 
             hPrintf("<input type='submit' name='hgt.refresh' value='refresh' "
                     "title='Update image with your changes'>\n");
             hPrintf("</td></tr></table></th>\n");
             controlGridEndRow(cg);
 
             /* Base Position track goes into map group, which will always exist. */
@@ -9814,30 +9818,43 @@
 // tell UDC where to put its statistics file
 char *udcLogFile;
 if ((udcLogFile =  cfgOption("udcLog")) != NULL)
     {
     FILE *fp = mustOpen(udcLogFile, "a");
     udcSetLog(fp);
     }
 
 initTl();
 
 char *configPageCall = cartCgiUsualString(cart, "hgTracksConfigPage", "notSet");
 char *configMultiRegionPageCall = cartCgiUsualString(cart, "hgTracksConfigMultiRegionPage", "notSet");
 
 /* Do main display. */
 
+char *sortTrack;
+if ((sortTrack = cgiOptionalString( "sortSim")) != NULL)
+    {
+    printf("sort track by similarity %s\n", sortTrack);
+    //sortTrackByExpression(cart);
+    }
+
+if ((sortTrack = cgiOptionalString( "sortExp")) != NULL)
+    {
+    printf("sort track by expression %s\n", sortTrack);
+    //sortTrackByExpression(cart);
+    }
+
 if (cartUsualBoolean(cart, "hgt.trackImgOnly", FALSE))
     {
     trackImgOnly = TRUE;
     ideogramToo = cartUsualBoolean(cart, "hgt.ideogramToo", FALSE);
     hideControls = TRUE;
     withNextItemArrows = FALSE;
     withNextExonArrows = FALSE;
     hgFindMatches = NULL;     // XXXX necessary ???
     }
 
 jsonForClient = newJsonObject(newHash(8));
 jsonObjectAdd(jsonForClient, "cgiVersion", newJsonString(CGI_VERSION));
 boolean searching = differentString(cartUsualString(cart, TRACK_SEARCH,"0"), "0");
 
 if(!trackImgOnly)