725e90237508115d42656743ea35a6da01be4464 angie Wed May 29 18:49:14 2024 -0700 When multiple references are matched, we make multiple 'view single subtree' buttons so add serial number to their IDs to prevent broken clicks. Also, apply MAX_SUBTREE_BUTTONS only when we're making individual buttons, not when we're making a dropdown to select the subtree. diff --git src/hg/hgPhyloPlace/phyloPlace.c src/hg/hgPhyloPlace/phyloPlace.c index 55a9244..d00d9d4 100644 --- src/hg/hgPhyloPlace/phyloPlace.c +++ src/hg/hgPhyloPlace/phyloPlace.c @@ -1494,31 +1494,34 @@ { char buttonId[256]; safef(buttonId, sizeof buttonId, "%s%d", idBase, ix+1); char buttonLabel[256]; safef(buttonLabel, sizeof buttonLabel, "view subtree %d in Nextstrain", ix+1); struct dyString *dyMo = dyStringCreate("view subtree %d with %d of your sequences and %d other " "sequences from the phylogenetic tree for context", ix+1, userSampleCount, subtreeSize - userSampleCount); makeNextstrainButton(buttonId, jsonTns[ix], buttonLabel, dyMo->string); dyStringFree(&dyMo); } static void makeNsSingleTreeButton(struct tempName *tn) /* Make a button to view single subtree (with all uploaded samples) in Nextstrain. */ { -makeNextstrainButton("viewNextstrainSingleSubtree", tn, +static int serial = 0; +char buttonId[256]; +safef(buttonId, sizeof buttonId, "viewNextstrainSingleSubtree%d", serial++); +makeNextstrainButton(buttonId, tn, "view downsampled global tree in Nextstrain", "view one subtree that includes all of your uploaded sequences plus " SINGLE_SUBTREE_SIZE" randomly selected sequences from the global phylogenetic " "tree for context"); } char *microbeTraceHost() /* Return the MicrobeTrace hostname from an hg.conf param, or NULL if missing. Do not free result. */ { return cfgOption("microbeTraceHost"); } static char *microbeTraceUrlBase() /* Alloc & return the part of the MicrobeTrace URL before the JSON filename. */ { @@ -1617,31 +1620,31 @@ NEXTSTRAIN_URL_PARAMS, TRUE); puts("<br>"); if (subtreeSize <= MAX_MICROBETRACE_SUBTREE_SIZE) { makeSubtreeJumpButton(subtreeDropdownName, "MicrobeTrace", microbeTraceUrlBase(), MICROBETRACE_URL_PARAMS, FALSE); } else { cgiMakeOptionalButton("disabledMTButton", "MicrobeTrace", TRUE); printf(" (%d samples is too many to view in MicrobeTrace; maximum is %d)", subtreeSize, MAX_MICROBETRACE_SUBTREE_SIZE); } puts("</td>"); } -else if (nextstrainHost()) +else if (nextstrainHost() && slCount(subtreeInfoList) <= MAX_SUBTREE_BUTTONS) { // Nextstrain only: do the old row of subtree buttons puts("<td>"); struct subtreeInfo *ti; int ix; for (ix = 0, ti = subtreeInfoList; ti != NULL; ti = ti->next, ix++) { int userSampleCount = slCount(ti->subtreeUserSampleIds); printf(" "); makeNextstrainButtonN("viewNextstrainTopRow", ix, userSampleCount, subtreeSize, jsonTns); } puts("</td>"); } if (0 && isFasta) { @@ -3456,44 +3459,41 @@ treeToAuspiceJson(ti, org, refName, geneInfoList, gSeqWin, sampleMetadata, NULL, results->samplePlacements, jsonTns[ix]->forCgi, source); // Add a link for every sample to this subtree, so the single-subtree JSON can // link to subtree JSONs char *subtreeUrl = nextstrainUrlFromTn(jsonTns[ix]); struct slName *sample; for (sample = ti->subtreeUserSampleIds; sample != NULL; sample = sample->next) hashAdd(sampleUrls, sample->name, subtreeUrl); } struct tempName *singleSubtreeJsonTn; AllocVar(singleSubtreeJsonTn); trashDirFile(singleSubtreeJsonTn, "ct", "singleSubtreeAuspice", ".json"); treeToAuspiceJson(results->singleSubtreeInfo, org, refName, geneInfoList, gSeqWin, sampleMetadata, sampleUrls, results->samplePlacements, singleSubtreeJsonTn->forCgi, source); reportTiming(&startTime, "make Auspice JSON"); - struct subtreeInfo *subtreeInfoForButtons = results->subtreeInfoList; - if (subtreeCount > MAX_SUBTREE_BUTTONS) - subtreeInfoForButtons = NULL; char *dbSetting = phyloPlaceRefSetting(org, refName, "db"); if (dbSetting) db = connectIfHub(cart, dbSetting); boolean canDoCustomTracks = (!subtreesOnly && (sameString(db, refName) || isNotEmpty(dbSetting))); if (canDoCustomTracks) // Form submits subtree custom tracks to hgTracks printf("<form action='%s' name='resultsForm_%s' method=%s>\n\n", hgTracksName(), db, cartUsualString(cart, "formMethod", "POST")); - makeButtonRow(singleSubtreeJsonTn, jsonTns, subtreeInfoForButtons, subtreeSize, isFasta, + makeButtonRow(singleSubtreeJsonTn, jsonTns, results->subtreeInfoList, subtreeSize, isFasta, canDoCustomTracks); printf("<p>If you have metadata you wish to display, click a 'view subtree in " "Nextstrain' button, and then you can drag on a CSV file to " "<a href='"NEXTSTRAIN_DRAG_DROP_DOC"' target=_blank>add it to the tree view</a>." "</p>\n"); puts("<p><em>Note: " "The Nextstrain subtree views, and Download files below, are temporary files and will " "expire within two days. " "Please download the Nextstrain subtree JSON files if you will want to view them " "again in the future. The JSON files can be drag-dropped onto " "<a href='https://auspice.us/' target=_blank>https://auspice.us/</a>." "</em></p>"); struct tempName *tsvTn = NULL, *sTsvTn = NULL; struct tempName *zipTn = makeSubtreeZipFile(results, jsonTns, singleSubtreeJsonTn,