diff --git a/src/locusview/templates/gene.html b/src/locusview/templates/gene.html index 1f2756b..1fb4149 100644 --- a/src/locusview/templates/gene.html +++ b/src/locusview/templates/gene.html @@ -4,14 +4,34 @@ {{ gene.symbol }} — locusview + @@ -22,6 +42,39 @@

{{ gene.symbol }}

(strand {{ gene.strand }}) · internal gene id {{ gene.gene_id }}

+

Regional plot

+
+
+
+ + +
+
+ + +
+
+

Loading…

+
+ lead (click any point to re-pick) + 0.8–1.0 + 0.6–0.8 + 0.4–0.6 + 0.2–0.4 + 0.0–0.2 + no LD data +
+

+ LD = 1000G phase 3 (selected population) — a single-population approximation and a visual aid to + locus structure, not part of the association inference. The dotted line is genome-wide + significance (5×10−8). +

+
+

eQTLs

Showing eQTLs from {{ n_tissues }} of {{ total_tissues }} datasets (bounded for the MVP). @@ -55,5 +108,79 @@

eQTLs

{% endif %}

locusview v{{ version }}

+ + diff --git a/src/locusview/viz.py b/src/locusview/viz.py index c613433..546e30d 100644 --- a/src/locusview/viz.py +++ b/src/locusview/viz.py @@ -8,7 +8,7 @@ import math # LocusZoom.js default r² color scheme. Bins are broken at 0.2 / 0.4 / 0.6 / 0.8. -LD_LEAD_COLOR = "#9632B8" # the reference/lead variant (drawn as a diamond) +LD_LEAD_COLOR = "#f97316" # the reference/lead variant (orange diamond, per Liu Fei's design) LD_NULL_COLOR = "#AAAAAA" # no LD data — distinct from low r² LD_BINS: list[tuple[float, str]] = [ (0.2, "#463699"), # indigo 0.0–0.2 diff --git a/src/locusview/web.py b/src/locusview/web.py index b054549..0b7a0e2 100644 --- a/src/locusview/web.py +++ b/src/locusview/web.py @@ -114,6 +114,7 @@ def gene_page(name: str) -> HTMLResponse: "gene.html", gene=gene, rows=rows, + datasets=datasets, n_tissues=len(datasets), total_tissues=len(all_datasets), ) diff --git a/tests/test_web.py b/tests/test_web.py index 1f021b8..f05eb02 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -45,6 +45,15 @@ def test_gene_page_renders_eqtls() -> None: assert "rs12345" in response.text # variant rendered +def test_gene_page_has_regional_plot_ui() -> None: + html = _gene_client().get("/gene/TP53").text + assert 'id="lv-plot"' in html # Plotly container + assert 'id="lv-tissue"' in html and "Stomach" in html # tissue selector + options + assert 'id="lv-population"' in html # LD population selector + assert "cdn.plot.ly" in html # Plotly loaded + assert "/api/gene/" in html # JS wires the regional endpoint + + def test_gene_page_unknown_gene_is_404() -> None: response = _gene_client().get("/gene/NOPE") assert response.status_code == 404 @@ -98,7 +107,7 @@ def test_regional_endpoint_attaches_r2_and_lead() -> None: by_rs = {v["rs_id"]: v for v in body["variants"]} assert by_rs[111]["is_lead"] is True and by_rs[111]["r2"] == 1.0 assert by_rs[222]["r2"] == 0.9 and by_rs[333]["r2"] == 0.1 - assert by_rs[111]["color"] == "#9632B8" # lead diamond color + assert by_rs[111]["color"] == "#f97316" # lead diamond color (orange, per Liu Fei) def test_regional_unknown_gene_is_404() -> None: