@@ -551,15 +551,12 @@ def _write_results_html(
551551 ).format (n_total = n_diagnostic_sites )
552552 snps_only_note_html = ""
553553 cols = [
554- ("id" , "ID" , False ),
555- ("length" , "len " , True ),
554+ ("id" , "Sample ID" , False ),
555+ ("length" , "Length (bp) " , True ),
556556 ("n_diagnostic_snps" , "Diagnostic sites" , True ),
557- ("n_ia" , f"n_{ ref1_label } " , True ),
558- ("n_ib" , f"n_{ ref2_label } " , True ),
559- ("n_other" , "n_other" , True ),
560- ("pct_ia" , f"% { ref1_label } " , True ),
561- ("pct_ib" , f"% { ref2_label } " , True ),
562- ("pct_other" , "% other" , True ),
557+ (("n_ia" , "pct_ia" ), f"{ ref1_label } (n | %)" , True ),
558+ (("n_ib" , "pct_ib" ), f"{ ref2_label } (n | %)" , True ),
559+ (("n_other" , "pct_other" ), "other (n | %)" , True ),
563560 ("consensus_snp" , "consensus (SNP)" , False ),
564561 ("recombinant_call" , "recombinant" , False ),
565562 ]
@@ -593,21 +590,27 @@ def _ref_box(label: str, spec: Optional[str]) -> str:
593590 for ri , r in enumerate (results ):
594591 cells = []
595592 for i , (key , _label , is_num ) in enumerate (cols ):
596- val = r .get (key , "" )
597593 cls = ' class="num"' if is_num else ""
598- if key == "id" :
599- val_str = str (val ).strip ()
594+ if isinstance (key , tuple ):
595+ key1 , key2 = key
596+ val1 = r .get (key1 , "" )
597+ val2 = r .get (key2 , "" )
598+ cells .append (f"<td{ cls } >{ html_escape (str (val1 ))} | { html_escape (str (val2 ))} </td>" )
599+ elif key == "id" :
600+ val_str = str (r .get (key , "" )).strip ()
601+ display_str = val_str [:20 ] + ("\u2026 " if len (val_str ) > 20 else "" )
602+ title_attr = f' title="{ html_escape (val_str )} "' if len (val_str ) > 20 else ""
600603 if val_str and _looks_like_accession (val_str ):
601604 url = "https://www.ncbi.nlm.nih.gov/nuccore/" + urllib .parse .quote (val_str , safe = "" )
602- cells .append (f'<td{ cls } ><a class="accession-link" href="{ html_escape (url )} " target="_blank" rel="noopener">{ html_escape (val_str )} </a></td>' )
605+ cells .append (f'<td{ cls } ><a class="accession-link" href="{ html_escape (url )} " target="_blank" rel="noopener"{ title_attr } >{ html_escape (display_str )} </a></td>' )
603606 else :
604- cells .append (f"<td{ cls } >{ html_escape (val_str )} </td>" )
607+ cells .append (f"<td{ cls } { title_attr } >{ html_escape (display_str )} </td>" )
605608 elif key == "recombinant_call" :
606- rec = str (val )
609+ rec = str (r . get ( key , "" ) )
607610 badge_cls = "recombinant-badge potential" if rec == "potential recombinant" else "recombinant-badge no"
608611 cells .append (f'<td{ cls } ><span class="{ badge_cls } ">{ html_escape (rec )} </span></td>' )
609612 else :
610- cells .append (f"<td{ cls } >{ html_escape (str (val ))} </td>" )
613+ cells .append (f"<td{ cls } >{ html_escape (str (r . get ( key , '' ) ))} </td>" )
611614 rec = r .get ("recombinant_call" , "" )
612615 row_cls = " class=\" recombinant\" " if rec == "potential recombinant" else ""
613616 rows_html .append (f'<tr data-row="{ ri } " data-recombinant="{ html_escape (rec )} "{ row_cls } >' + "" .join (cells ) + "</tr>" )
@@ -638,7 +641,10 @@ def _ref_box(label: str, spec: Optional[str]) -> str:
638641 filter_row = "<tr id=\" filterrow\" >" + "" .join (filter_cells ) + "</tr>"
639642
640643 # Build list of dicts per row for JS (exclude allegiances to keep JSON small)
641- data_list = [{c [0 ]: r .get (c [0 ], "" ) for c in cols } for r in results ]
644+ # Flatten tuple keys (merged display columns) and always include chart keys
645+ _chart_keys = {"id" , "pct_ia" , "pct_ib" , "pct_other" }
646+ _data_keys = {k for c in cols for k in (c [0 ] if isinstance (c [0 ], tuple ) else (c [0 ],))} | _chart_keys
647+ data_list = [{k : r .get (k , "" ) for k in _data_keys } for r in results ]
642648 data_json = json .dumps (data_list ).replace ("</" , "<\\ /" )
643649
644650 # Diagnostic sites per sample: strip (genome position, color Ia/Ib/other) + table for ALL consensus genomes
@@ -1611,7 +1617,7 @@ def row(r: Dict[str, Any]) -> str:
16111617 f"when minor ref % ≥ { minor_threshold :g} %, the sample is flagged as potential recombinant."
16121618 )
16131619 other_explanation = (
1614- "%% other = diagnostic sites where the query neither matched %s nor %s (different base; at SNPs, gap/N count as other)."
1620+ "%% other = diagnostic sites where the query neither matched %s nor %s (different base or gap/N count as other)."
16151621 ) % (ref1_label , ref2_label )
16161622
16171623 # HTML: one file if <= HTML_CHUNK_SIZE genomes, else one file per chunk of 100 (overzichtelijk)
0 commit comments