Drop the breadcrumb, the collapse button, and two shortcuts

#9
by lvwerra HF Staff - opened
Files changed (3) hide show
  1. README.md +2 -2
  2. atlas.css +1 -6
  3. taxonomy.py +4 -12
README.md CHANGED
@@ -17,13 +17,13 @@ Future features and open design decisions are tracked in the [feature backlog](F
17
 
18
  ## GenBank taxonomy
19
 
20
- The landing page opens with an interactive **tree of eukaryotic life**, using NCBI's current GenBank assembly summary and taxonomy. It is drawn as a Sankey diagram running **down the page**: each group is a horizontal bar split into annotated (green) and not-annotated (gray) assemblies, and flows carry both parts from a group into its lineages on the level below. Expanding a group adds a level underneath rather than a column to the right, so a full lineage — eukaryotes down to humans is about thirty levels — is one ordinary page scroll instead of an endless sideways one. The chart itself only scrolls on screens too narrow to keep the labels legible. Shortcut buttons above the tree jump straight to a lineage: animals, mammals, humans, birds, ray-finned fish, insects, jellyfish, green plants, flowering plants and fungi. Each group shows a silhouette, its scientific name and its English name; counts and percentages live in the tooltip, which appears over a group or over the flux arriving at it. The flux feeding the current selection stays highlighted, so the trunk you have walked reads against the lineages you passed over. Each group is labelled with its scientific name and, where one exists, a plain-English name underneath, so the Latin backbone of the tree (Opisthokonta, Eumetazoa, Ecdysozoa) stays readable without prior knowledge. The two views sit inside one curved panel, switched by a full-width toggle at the top: the **Genome Atlas** holds the tree and its lineage controls, and **Database** holds accession search, segment visualization, and downloads over the full published-file snapshot. A **Show database results** button carries the current group across, handing the Database tab one annotated assembly from the selected lineage; it says so plainly when a group has none. RefSeq exploration can be added beneath the tree.
21
 
22
  The viewer is restricted to **Eukaryota (NCBI taxid 2759) and its descendants**, including search, breadcrumbs, and parent navigation. The model predicts eukaryotic annotations; bacteria, archaea, and viruses are outside this display. The current eukaryotic snapshot contains **70,395 assemblies**, of which **17,561 (24.9%)** have published annotations. The underlying SQLite snapshot retains the full NCBI inventory for refresh/provenance, while the interface uses only the eukaryotic subtree and its denominators. Assemblies with unresolved taxonomy cannot be assigned to that subtree and are excluded.
23
 
24
  The inventory accepts `GCA_` accessions with `version_status=latest`. Each assembly contributes once to its taxon and each ancestor. These counts describe genome assemblies, not all GenBank nucleotide records. An assembly counts as having annotations when it occurs in the publication inventory; this includes partial assemblies and does not imply full base coverage. Exact accession versions are matched to the NCBI snapshot. Published versions outside that snapshot are excluded from percentages.
25
 
26
- Click a group to open its direct lineages as a new level below; every ancestor level stays visible, so the full path from Eukaryota is always on screen. Clicking a group in an earlier level replaces the levels after it. Use breadcrumbs, “Collapse last group”, or shortcuts to go back. Nodes support Enter/Space keyboard navigation. The opening view expands the actual animal/fungal ancestor, Opisthokonta. Each level shows six direct lineages, an expandable remainder, and the selected lineage if it falls outside the top six. Bar and flow widths follow assembly counts within a level; every level is rescaled to the full width. “Other lineages” is an explicitly labeled display aggregate, not an invented clade; its counts sum the remaining siblings. Repeated expansion reaches all siblings without truncating them. Search reaches individual taxa by scientific name, taxon ID, or English name, so "sponges", "jellyfish" or "house mouse" all work; matches appear as a list with the closest first and already selected, and Enter opens it. Level spacing does not encode time. Expanding nudges the page down only when the new level has fallen past the viewport.
27
 
28
  English names come from `data/common_names.json`, built by `refresh_common_names.py` from NCBI Taxonomy's `genbank common name` and `common name` entries (about 9,200 taxa) plus a curated table of roughly 190 short glosses for the large unranked clades NCBI leaves unnamed. Glosses are plain-language summaries of the living members of a clade, not formal synonyms; the scientific name stays the primary label and a gloss that merely repeats it is dropped at build time. Rebuild it with `python refresh_common_names.py` once `.cache/coverage/taxdump.tar.gz` is present; the build fails if a curated taxid no longer matches its scientific name in the snapshot.
29
 
 
17
 
18
  ## GenBank taxonomy
19
 
20
+ The landing page opens with an interactive **tree of eukaryotic life**, using NCBI's current GenBank assembly summary and taxonomy. It is drawn as a Sankey diagram running **down the page**: each group is a horizontal bar split into annotated (green) and not-annotated (gray) assemblies, and flows carry both parts from a group into its lineages on the level below. Expanding a group adds a level underneath rather than a column to the right, so a full lineage — eukaryotes down to humans is about thirty levels — is one ordinary page scroll instead of an endless sideways one. The chart itself only scrolls on screens too narrow to keep the labels legible. Shortcut buttons above the tree jump straight to a lineage: animals, mammals, humans, birds, ray-finned fish, insects, jellyfish, green plants and fungi. Each group shows a silhouette, its scientific name and its English name; counts and percentages live in the tooltip, which appears over a group or over the flux arriving at it. The flux feeding the current selection stays highlighted, so the trunk you have walked reads against the lineages you passed over. Each group is labelled with its scientific name and, where one exists, a plain-English name underneath, so the Latin backbone of the tree (Opisthokonta, Eumetazoa, Ecdysozoa) stays readable without prior knowledge. The two views sit inside one curved panel, switched by a full-width toggle at the top: the **Genome Atlas** holds the tree and its lineage controls, and **Database** holds accession search, segment visualization, and downloads over the full published-file snapshot. A **Show database results** button carries the current group across, handing the Database tab one annotated assembly from the selected lineage; it says so plainly when a group has none. RefSeq exploration can be added beneath the tree.
21
 
22
  The viewer is restricted to **Eukaryota (NCBI taxid 2759) and its descendants**, including search, breadcrumbs, and parent navigation. The model predicts eukaryotic annotations; bacteria, archaea, and viruses are outside this display. The current eukaryotic snapshot contains **70,395 assemblies**, of which **17,561 (24.9%)** have published annotations. The underlying SQLite snapshot retains the full NCBI inventory for refresh/provenance, while the interface uses only the eukaryotic subtree and its denominators. Assemblies with unresolved taxonomy cannot be assigned to that subtree and are excluded.
23
 
24
  The inventory accepts `GCA_` accessions with `version_status=latest`. Each assembly contributes once to its taxon and each ancestor. These counts describe genome assemblies, not all GenBank nucleotide records. An assembly counts as having annotations when it occurs in the publication inventory; this includes partial assemblies and does not imply full base coverage. Exact accession versions are matched to the NCBI snapshot. Published versions outside that snapshot are excluded from percentages.
25
 
26
+ Click a group to open its direct lineages as a new level below; every ancestor level stays visible, so the full path from Eukaryota is always on screen. Clicking a group in an earlier level replaces the levels after it. Every ancestor is already on screen, so going back is a click on a level above; the shortcuts jump elsewhere entirely. Nodes support Enter/Space keyboard navigation. The opening view expands the actual animal/fungal ancestor, Opisthokonta. Each level shows six direct lineages, an expandable remainder, and the selected lineage if it falls outside the top six. Bar and flow widths follow assembly counts within a level; every level is rescaled to the full width. “Other lineages” is an explicitly labeled display aggregate, not an invented clade; its counts sum the remaining siblings. Repeated expansion reaches all siblings without truncating them. Search reaches individual taxa by scientific name, taxon ID, or English name, so "sponges", "jellyfish" or "house mouse" all work; matches appear as a list with the closest first and already selected, and Enter opens it. Level spacing does not encode time. Expanding nudges the page down only when the new level has fallen past the viewport.
27
 
28
  English names come from `data/common_names.json`, built by `refresh_common_names.py` from NCBI Taxonomy's `genbank common name` and `common name` entries (about 9,200 taxa) plus a curated table of roughly 190 short glosses for the large unranked clades NCBI leaves unnamed. Glosses are plain-language summaries of the living members of a clade, not formal synonyms; the scientific name stays the primary label and a gloss that merely repeats it is dropped at build time. Rebuild it with `python refresh_common_names.py` once `.cache/coverage/taxdump.tar.gz` is present; the build fails if a curated taxid no longer matches its scientific name in the snapshot.
29
 
atlas.css CHANGED
@@ -12,15 +12,10 @@
12
  .atlas-summary span { font-size:11px; line-height:1.6; color:var(--muted); }
13
  .atlas-badge { padding:7px 9px; font-size:13px; background:#dfeedd; color:#285b40; border-radius:8px; white-space:nowrap; }
14
  .atlas button { font:inherit; cursor:pointer; }
15
- .atlas-nav { display:flex; justify-content:space-between; align-items:center; gap:12px; margin:25px 0 14px; }
16
  .atlas-shortcuts { display:flex; flex-wrap:wrap; gap:7px; }
17
  .atlas-shortcuts button { border:1px solid #cfdcc9; background:#ffffff80; border-radius:30px; padding:8px 15px; color:#315641; font-size:12px; transition:background .15s; }
18
  .atlas-shortcuts button:hover { background:#dfeedd; }
19
- .atlas .atlas-back { color:#647467; background:transparent; border:0; font-size:12px; padding:8px; white-space:nowrap; }
20
- .atlas-breadcrumb { display:flex; align-items:center; flex-wrap:wrap; gap:7px; color:#6c7d6a; font-size:11px; min-height:20px; }
21
- .atlas-breadcrumb button { border:0; background:none; color:inherit; padding:2px 0; }
22
- .atlas-breadcrumb button:hover { text-decoration:underline; }
23
- .crumb-divider { opacity:.4; }
24
  .tree-scroll { margin:0 -5px; }
25
  .life-tree { display:block; width:100%; height:auto; overflow:visible; }
26
  .flow { stroke:none; transition:opacity .15s; }
 
12
  .atlas-summary span { font-size:11px; line-height:1.6; color:var(--muted); }
13
  .atlas-badge { padding:7px 9px; font-size:13px; background:#dfeedd; color:#285b40; border-radius:8px; white-space:nowrap; }
14
  .atlas button { font:inherit; cursor:pointer; }
15
+ .atlas-nav { display:flex; align-items:center; gap:12px; margin:25px 0 10px; }
16
  .atlas-shortcuts { display:flex; flex-wrap:wrap; gap:7px; }
17
  .atlas-shortcuts button { border:1px solid #cfdcc9; background:#ffffff80; border-radius:30px; padding:8px 15px; color:#315641; font-size:12px; transition:background .15s; }
18
  .atlas-shortcuts button:hover { background:#dfeedd; }
 
 
 
 
 
19
  .tree-scroll { margin:0 -5px; }
20
  .life-tree { display:block; width:100%; height:auto; overflow:visible; }
21
  .flow { stroke:none; transition:opacity .15s; }
taxonomy.py CHANGED
@@ -35,7 +35,7 @@ MAX_LABEL = 22
35
  # like. Order runs broad to narrow.
36
  SHORTCUTS = ((33208, "Animals"), (40674, "Mammals"), (9606, "Humans"), (8782, "Birds"),
37
  (7898, "Ray-finned fish"), (50557, "Insects"), (6142, "Jellyfish"),
38
- (33090, "Green plants"), (3398, "Flowering plants"), (4751, "Fungi"))
39
 
40
 
41
  COLUMN_LIMIT = 6
@@ -394,12 +394,6 @@ class Taxonomy:
394
  selected_name = f"Other lineages of {lineage[-1]['name']}" if focus.get('aggregate') else focus['label']
395
  if focus.get('english'):
396
  selected_name += f" · {focus['english']}"
397
- crumbs = []
398
- for depth, (row, (_, offset)) in enumerate(zip(lineage, steps)):
399
- name = "Other lineages" if offset else row['name']
400
- crumbs.append(f'<button data-path="{encode_path(steps[:depth + 1])}">{escape(name)}</button>')
401
- breadcrumbs = ' <span class="crumb-divider">/</span> '.join(crumbs)
402
- parent = encode_path(steps[:-1] or steps)
403
  stamp = (self.coverage or self.metadata)['created_at'][:10]
404
  if self.coverage:
405
  summary = (f'<div class="atlas-kicker">{escape(selected_name)} · ASSEMBLY COVERAGE</div>'
@@ -411,7 +405,7 @@ class Taxonomy:
411
  summary = f'<div class="atlas-kicker">{escape(selected_name)}</div><div class="atlas-summary"><strong>{total:,}</strong><span>GenBank assemblies<br>Coverage unavailable</span></div>'
412
  legend = '<div class="atlas-legend"><i class="atlas-swatch atlas-missing"></i><span>Assemblies · coverage unavailable</span></div>'
413
  jumps = ''.join(f'<button data-path="{shortcuts[t]}">{escape(name)}</button>' for t, name in SHORTCUTS)
414
- leaf_note = '<p class="atlas-leaf-note">This is a terminal taxon in the assembly snapshot. Use the breadcrumb to explore its relatives.</p>' if not has_children else ''
415
  return f'''<section class="atlas" aria-label="Tree of eukaryotic life">
416
  <header class="atlas-header">
417
  <div><h1>The tree of eukaryotic life<span>.</span></h1>
@@ -419,11 +413,9 @@ class Taxonomy:
419
  <div class="atlas-summary-block">{summary}</div>
420
  </header>
421
  <nav class="atlas-nav" aria-label="Explore major lineages">
422
- <div class="atlas-shortcuts"><button data-path="{DEFAULT_PATH}">All eukaryotes</button>{jumps}</div>
423
- <button class="atlas-back" data-path="{parent}">← Collapse last group</button>
424
  </nav>
425
- <div class="atlas-breadcrumb">{breadcrumbs}</div>
426
- <div class="tree-scroll" tabindex="0" aria-label="Interactive tree. Scroll horizontally to see deeper lineages.">{svg}</div>
427
  {leaf_note}<div class="atlas-tooltip" role="tooltip" hidden></div>
428
  <footer class="atlas-footer">{legend}
429
  <span>Click a group to open it below</span>
 
35
  # like. Order runs broad to narrow.
36
  SHORTCUTS = ((33208, "Animals"), (40674, "Mammals"), (9606, "Humans"), (8782, "Birds"),
37
  (7898, "Ray-finned fish"), (50557, "Insects"), (6142, "Jellyfish"),
38
+ (33090, "Green plants"), (4751, "Fungi"))
39
 
40
 
41
  COLUMN_LIMIT = 6
 
394
  selected_name = f"Other lineages of {lineage[-1]['name']}" if focus.get('aggregate') else focus['label']
395
  if focus.get('english'):
396
  selected_name += f" · {focus['english']}"
 
 
 
 
 
 
397
  stamp = (self.coverage or self.metadata)['created_at'][:10]
398
  if self.coverage:
399
  summary = (f'<div class="atlas-kicker">{escape(selected_name)} · ASSEMBLY COVERAGE</div>'
 
405
  summary = f'<div class="atlas-kicker">{escape(selected_name)}</div><div class="atlas-summary"><strong>{total:,}</strong><span>GenBank assemblies<br>Coverage unavailable</span></div>'
406
  legend = '<div class="atlas-legend"><i class="atlas-swatch atlas-missing"></i><span>Assemblies · coverage unavailable</span></div>'
407
  jumps = ''.join(f'<button data-path="{shortcuts[t]}">{escape(name)}</button>' for t, name in SHORTCUTS)
408
+ leaf_note = '<p class="atlas-leaf-note">This is a terminal taxon in the assembly snapshot. Pick a level above to explore its relatives.</p>' if not has_children else ''
409
  return f'''<section class="atlas" aria-label="Tree of eukaryotic life">
410
  <header class="atlas-header">
411
  <div><h1>The tree of eukaryotic life<span>.</span></h1>
 
413
  <div class="atlas-summary-block">{summary}</div>
414
  </header>
415
  <nav class="atlas-nav" aria-label="Explore major lineages">
416
+ <div class="atlas-shortcuts">{jumps}</div>
 
417
  </nav>
418
+ <div class="tree-scroll" tabindex="0" aria-label="Interactive tree. Expanding a group adds a level below it.">{svg}</div>
 
419
  {leaf_note}<div class="atlas-tooltip" role="tooltip" hidden></div>
420
  <footer class="atlas-footer">{legend}
421
  <span>Click a group to open it below</span>