0be7b604dc94f877a813c77d1caffb6caa5ff267 hiram Wed Dec 10 11:06:58 2025 -0800 improved prompt tags for the expandable sectios refs #35776 diff --git src/hg/hgc/togaClick.c src/hg/hgc/togaClick.c index 9d8f957bbbf..de092e4773d 100644 --- src/hg/hgc/togaClick.c +++ src/hg/hgc/togaClick.c @@ -281,30 +281,36 @@ } void print_with_newlines(const char *str) { int line_length = 80; // Number of characters per line int length = strlen(str); int i = 0; while (i < length) { /* Print up to 80 characters or the remainder of the string */ int chars_to_print = (length - i < line_length) ? (length - i) : line_length; printf("%.*s<BR>", chars_to_print, &str[i]); i += chars_to_print; } } +static void panelPrompt(char *target, char *prompt) +/* output span element for an expandable text element */ +{ +printf("<span class='hideToggle' dataTarget='%s' style='cursor: pointer; color: blue;'><img height='18' width='18' src='../images/add_sm.gif'> %s:</span>\n", target, prompt); +printf("<div id='%s' style='display: none;'>\n", target); +} void doHillerLabTOGAGeneBig(char *database, struct trackDb *tdb, char *item, char *table_name) /* Put up TOGA Gene track info. */ // To think about -> put into a single bigBed // string: HTML formatted inact mut // string: HTML formatted exon ali section { int start = cartInt(cart, "o"); int end = cartInt(cart, "t"); char *chrom = cartString(cart, "c"); char *fileName = bbiNameFromSettingOrTable(tdb, NULL, tdb->table); struct bbiFile *bbi = bigBedFileOpenAlias(hReplaceGbdb(fileName), chromAliasFindAliases); struct lm *lm = lmInit(0); struct bigBedInterval *bbList = bigBedIntervalQuery(bbi, chrom, start, end, 0, lm); struct bigBedInterval *bb; @@ -323,32 +329,31 @@ char startBuf[16], endBuf[16]; bigBedIntervalToRow(bb, chrom, startBuf, endBuf, fields, bbi->fieldCount); break; } printf("<h3>Projection v2 %s</h3>\n", item); struct togaDataBB *info = togaDataBBLoad(&fields[11], bbi->fieldCount); // Bogdan: why 11? 0-11 are bed-like fields likely printf("<B>Reference transcript: </B>%s<BR>", info->ref_link); printf("<B>Genomic locus in reference: </B>%s<BR>\n", info->ref_region); printf("<B>Genomic locus in query: </B>%s<BR>\n", info->query_region); printf("<B>Projection classification: </B>%s<BR>\n", info->status); printf("<B>Probability that query locus is orthologous: </B>%s<BR>\n", info->chain_score); // list of chain features (for orthology classification) -printf("<span class='hideToggle' data-target='collapseChain' style='cursor: pointer;'>Show features used for ortholog probability:</span>\n"); -printf("<div id='collapseChain' style='display: none;'>\n"); +panelPrompt("collapseChain", "Show features used for ortholog probability"); printf("<p><ul>\n"); printf("<li>Synteny (log10 value): %s</li>\n", info->chain_synteny); printf("<li>Global CDS fraction: %s</li>\n", info->chain_gl_cds_fract); printf("<li>Local CDS fraction: %s</li>\n", info->chain_loc_cds_fract); printf("<li>Local intron fraction: %s</li>\n", info->chain_intron_cov); printf("<li>Local CDS coverage: %s</li>\n", info->chain_exon_cov); printf("<li>Flank fraction: %s</li>\n", info->chain_flank); printf("</ul></p>\n"); printf("<p>\n<b>Feature description:</b>\n"); printf("For each projection (one reference transcript and one overlapping chain),\n"); printf("TOGA computes the following features by intersecting the reference coordinates of aligning\n"); printf("blocks in the chain with different gene parts (coding exons, UTR (untranslated region) exons, introns)\n"); printf("and the respective intergenic regions.\n</p>\n"); @@ -380,108 +385,101 @@ printf("<li>"local CDS coverage" as c / CDS, which is only used for single-exon genes. </li>\n"); printf("</ul></p>\n"); printf("</div>\n"); printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); // show inact mut plot printf("<h4>Visualization of inactivating mutations on exon-intron structure</h4>\n"); printf("%s\n", info->svg_line); printf("<BR>Exons shown in grey are missing (often overlap assembly gaps).\nExons shown in"); printf(" red or blue are deleted or do not align at all.\nRed indicates that the exon deletion "); printf("shifts the reading frame, while blue indicates that exon deletion(s) are framepreserving.<br>\n"); // GLP features -printf("<span class='hideToggle data-target='collapseGLP' style='cursor: pointer;'>Show features used for transcript classification</span>\n"); -printf("<div id='collapseGLP' style='display: none;'>\n"); +panelPrompt("collapseGLP", "Show features used for transcript classification"); printf("<p><ul>\n"); printf("<li>Percent intact, ignoring missing sequence: %s</li>\n", info->perc_intact_ign_M); printf("<li>Percent intact, treating missing as intact sequence: %s</li>\n", info->perc_intact_int_M); printf("<li>Proportion of intact codons: %s</li>\n", info->intact_codon_prop); printf("<li>Percent of CDS not covered by this chain (0 unless the chain covers only a part of the gene): %s</li>\n", info->ouf_prop); if (sameWord(info->mid_intact, ONE_)) { printf("<li>Middle 80 percent of CDS intact: %s</li>\n", YES_); } else { printf("<li>Middle 80 percent of CDS intact: %s</li>\n", NO_); } if (sameWord(info->mid_pres, ONE_)) { printf("<li>Middle 80 percent of CDS present: %s</li>\n", YES_); } else { printf("<li>Middle 80 percent of CDS present: %s</li>\n", NO_); } if (info->numExonsMutated != NULL && info->percentExonsMutated != NULL) { printf("<li>Number of exons with inactivating mutations: %s (%s%% of the present exons; threshold is 20%%)</li>\n", info->numExonsMutated, info->percentExonsMutated); } printf("</ul></p>\n</div>\n"); printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("<h4>Predicted protein sequence</h4>\n"); -printf("<span class='hideToggle' data-target='collapseProt' style='cursor: pointer;'>Show protein sequence of query</span>\n"); -printf("<div id='collapseProt' style='display: none;'>\n"); +panelPrompt("collapseProt", "Show protein sequence of query"); printf("<p><TT>"); HLprintQueryProtSeqForAli(info->prot_alignment); printf("\n</TT></p>\n</div><BR>\n"); if (info->protseqFrameCorrected != NULL) { - printf("<span class='hideToggle' data-target='collapseProtFrameCorrected' style='cursor: pointer;'>Show frame-corrected protein sequence of query (potential frameshifts are masked)</span>\n"); - printf("<div id='collapseProtFrameCorrected' style='display: none;'>\n"); + panelPrompt("collapseProtFrameCorrected", "Show frame-corrected protein sequence of query (potential frameshifts are masked)"); printf("<p><TT>"); print_with_newlines(info->protseqFrameCorrected); printf("\n</TT></p>\n</div>\n"); } if (info->CDSseq != NULL) { printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("<h4>Predicted coding (DNA) sequence</h4>\n"); - printf("<span class='hideToggle' data-target='collapseCDS' style='cursor: pointer;'>Show coding sequence of query</span>\n"); - printf("<div id='collapseCDS' style='display: none;'>\n"); + panelPrompt("collapseCDS", "Show coding sequence of query"); printf("<p><TT>"); print_with_newlines(info->CDSseq); printf("\n</TT></p>\n</div>\n"); } // and show protein sequence printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("<h4>Protein sequence alignment</h4>\n"); -printf("<span class='hideToggle' data-target='collapseProtAli' style='cursor: pointer;'>Show alignment between reference and query</span>\n"); -printf("<div id='collapseProtAli' style='display: none;'>\n"); +panelPrompt("collapseProtAli", "Show alignment between reference and query"); printf("<p><TT>%s</TT>\n", info->prot_alignment); printf("</p></div>\n"); // show inactivating mutations if required printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("<h4>List of inactivating mutations</h4>\n"); -printf("<span class='hideToggle' data-target='collapseMuts' style='cursor: pointer;'>Show inactivating mutations</span>\n"); -printf("<div id='collapseMuts' style='display: none;'>\n"); +panelPrompt("collapseMuts", "Show inactivating mutations"); printf("<p><table border = \"1\" width = \"640\">\n"); // init table printf("<tr><th>Exon number</th><th>Codon number</th><th>Mutation class</th><th>Mutation</th><th>Treated as inactivating</th><th>Mutation ID</th>\n"); printf("</tr>\n"); printf("%s\n", info->inact_mut_html_table); printf("</table></p>\n"); printf("</div>\n\n"); // show exons data printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("<h4>Exon alignments</h4>\n"); -printf("<span class='hideToggle' data-target'collapseExons' style='cursor: pointer;'>Show exon sequences and features</span>\n"); -printf("<div id='collapseExons' style='display: none;'>\n"); +panelPrompt("collapseExons", "Show exon sequences and features"); printf("<p>%s</p>\n", info->exon_ali_html); printf("<hr style='margin-bottom:-0.5em;color:black;'>\n"); printf("</div>\n<BR><BR>\n"); printTrackHtml(tdb); // and do I need this? } void doHillerLabTOGAGene(char *database, struct trackDb *tdb, char *item, char *table_name) /* Put up TOGA Gene track info. */ { //int start = cartInt(cart, "o"); char headerTitle[512]; char suffix[512]; @@ -523,32 +521,31 @@ sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaDataTableName, item); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { info = togaDataLoad(row); // parse sql output // fill HTML template: printf("<B>Reference transcript: </B><A HREF=\"http://www.ensembl.org/Homo_sapiens/transview?transcript=%s\" target=_blank>%s</A><BR>", info->ref_trans_id, info->ref_trans_id); printf("<B>Genomic locus in reference: </B>%s<BR>\n", info->ref_region); printf("<B>Genomic locus in query: </B>%s<BR>\n", info->query_region); printf("<B>Projection classification: </B>%s<BR>\n", info->status); printf("<B>Probability that query locus is orthologous: </B>%s<BR>\n", info->chain_score); // list of chain features (for orthology classification) - printf("<span class='hideToggle' data-target='collapseChain' style='cursor: pointer;'>Show features used for ortholog probability</span>\n"); - printf("<div id='collapseChain' style='display: none;'"); + panelPrompt("collapseChain", "Show features used for ortholog probability"); printf("<p><ul>\n"); printf("<li>Synteny (log10 value): %s</li>\n", info->chain_synteny); printf("<li>Global CDS fraction: %s</li>\n", info->chain_gl_cds_fract); printf("<li>Local CDS fraction: %s</li>\n", info->chain_loc_cds_fract); printf("<li>Local intron fraction: %s</li>\n", info->chain_intron_cov); printf("<li>Local CDS coverage: %s</li>\n", info->chain_exon_cov); printf("<li>Flank fraction: %s</li>\n", info->chain_flank); printf("</ul></p>\n"); printf("<br>\n<b>Feature description:</b>\n"); printf("For each projection (one reference transcript and one overlapping chain),\n"); printf("TOGA computes the following features by intersecting the reference coordinates of aligning\n"); printf("blocks in the chain with different gene parts (coding exons, UTR (untranslated region) exons, introns)\n"); printf("and the respective intergenic regions.\n<br>\n"); @@ -580,86 +577,82 @@ printf("<li>"local CDS coverage" as c / CDS, which is only used for single-exon genes. </li>\n"); printf("</ul>\n"); printf("</ul>\n</div>\n<BR>\n"); htmlHorizontalLine(); // show inact mut plot printf("<h4>Visualization of inactivating mutations on exon-intron structure</h4>\n"); printf("%s<BR>\n", info->svg_line); printf("<BR>Exons shown in grey are missing (often overlap assembly gaps).\nExons shown in"); printf(" red or blue are deleted or do not align at all.\nRed indicates that the exon deletion "); printf("shifts the reading frame, while blue indicates that exon deletion(s) are framepreserving.<br>\n"); // GLP features - printf("<span class='hideToggle' data-target='collapseGLP' style='cursor: pointer;'>Show features used for transcript classification</span>\n"); - printf("<div id='collapseGLP' style='display:none;'>\n"); + panelPrompt("collapseGLP", "Show features used for transcript classification"); printf("<p><ul>\n"); printf("<li>Percent intact, ignoring missing sequence: %s</li>\n", info->perc_intact_ign_M); printf("<li>Percent intact, treating missing as intact sequence: %s</li>\n", info->perc_intact_int_M); printf("<li>Proportion of intact codons: %s</li>\n", info->intact_codon_prop); printf("<li>Percent of CDS not covered by this chain (0 unless the chain covers only a part of the gene): %s</li>\n", info->ouf_prop); if (sameWord(info->mid_intact, ONE_)) { printf("<li>Middle 80 percent of CDS intact: %s</li>\n", YES_); } else { printf("<li>Middle 80 percent of CDS intact: %s</li>\n", NO_); } if (sameWord(info->mid_pres, ONE_)) { printf("<li>Middle 80 percent of CDS present: %s</li>\n", YES_); } else { printf("<li>Middle 80 percent of CDS present: %s</li>\n", NO_); } printf("</ul></p>\n</div>\n<BR>\n"); printf("<HR ALIGN=\"CENTER\"><h4>Query protein sequence</h4><BR>"); - printf("<span class='hideToggle' data-target='collapseProt' style='cursor: pointer;'>Show protein sequence of query</span>\n"); - printf("<div id='collapseProt' style='display:none;'>\n"); + panelPrompt("collapseProt", "Show protein sequence of query"); printf("<p><TT>{protein seq of the query without dashes or other things. Should end with *}\n"); printf("<BR>\n</TT></p>\n</div>\n"); // and show protein sequence htmlHorizontalLine(); printf("<h4>Protein sequence alignment</h4><BR>\n"); - printf("<span class='hideToggle' data-target='collapseProtAli' style='cursor: pointer;'>Show alignment between reference and query</span>\n"); - printf("<div id='collapseProtAli' style='display: none;'>\n"); + panelPrompt("collapseProtAli", "Show alignment between reference and query"); printf("<p><TT>%s</TT></p><BR>\n", info->prot_alignment); printf("</div>\n<BR><BR>\n"); // do not forget to free toga data struct togaDataFree(&info); } else { // no data found, need to report this printf("<h3>No found data for %s</h3>\n", item); } sqlFreeResult(&sr); } // show inactivating mutations if required printf("<h4>List of inactivating mutations</h4><BR>\n"); if (hTableExists(database, togaInactMutTableName)) { char query[256]; struct sqlResult *sr = NULL; char **row; sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaInactMutTableName, item); sr = sqlGetResult(conn, query); - printf("<span class='hideToggle' data-target='collapseMuts' style='cursor: pointer;'>Show inactivating mutations</span>\n"); - printf("<div id='collapseMuts' style='display: none;'>\n"); + panelPrompt("collapseMuts", "Show inactivating mutations"); printf("<table border = \"1\" width = \"640\">\n"); // init table printf("<tr><th>Exon number</th><th>Codon number</th><th>Mutation class</th><th>Mutation</th><th>Treated as inactivating</th><th>Mutation ID</th>\n"); printf("</tr>\n"); while ((row = sqlNextRow(sr)) != NULL) { struct togaInactMut *info = NULL; info = togaInactMutLoad(row); printf("<tr>\n"); printf("<td>%s</td>\n", info->exon_num); printf("<td>%s</td>\n", info->position); printf("<td>%s</td>\n", info->mut_class); printf("<td>%s</td>\n", info->mutation); if (sameWord(info->is_inact, ONE_)){ printf("<td>%s</td>\n", YES_); } else { @@ -673,32 +666,31 @@ printf("</table>\n"); printf("</div>\n<BR>\n"); } else { printf("<B>Sorry, cannot find TOGAInactMut table.</B><BR>\n"); } // show exons data htmlHorizontalLine(); printf("<h4>Exon alignments</h4><BR>\n"); if (hTableExists(database, togaNuclTableName)) { char query[256]; struct sqlResult *sr = NULL; char **row; - printf("<span class='hideToggle' data-target='collapseExons' style='cursor: pointer;'>Show exon sequences and features</span>\n"); - printf("<div id='collapseExons' style='display: none;'>\n"); + panelPrompt("collapseExons", "Show exon sequences and features"); sqlSafef(query, sizeof(query), "select * from %s where transcript='%s'", togaNuclTableName, item); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { struct togaNucl *info = NULL; info = togaNuclLoad(row); printf("<h5>Exon number: %s</h5><BR>\n", info->exon_num); printf("<B>Exon region:</B> %s<BR>\n", info->exon_region); printf("<B>Nucleotide percent identity:</B> %s | <B>BLOSUM:</B> %s <BR>\n", info->pid, info->blosum); if (sameWord(info->gaps, ONE_)){ printf("<B>Intersects assembly gaps:</B> %s<BR>\n", YES_); } else { printf("<B>Intersects assembly gaps:</B> %s<BR>\n", NO_); }