Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding short gene names to the region plot title, and toning down the color scheme #44

Merged
merged 9 commits into from
Dec 20, 2019
4 changes: 4 additions & 0 deletions pheget/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ def region_view():
# First, load the gene_id -> gene_symbol conversion table (no version numbers at the end of ENSG's)
gene_json = model.get_gene_names_conversion()

# If no symbol is entered but we have gene_id, try to look it up in gene_json
if symbol is None:
symbol = gene_json.get(gene_id.split(".")[0], None)

# Query the sqlite3 database for the range (chrom:start-end) and get the list of all genes
conn = sqlite3.connect(model.get_sig_lookup())
with conn:
Expand Down
181 changes: 109 additions & 72 deletions pheget/frontend/templates/frontend/region.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,128 +14,160 @@
<div id="home-searchbox">
<form id="variant-search">
<div class="input-group">
<div class="input-group-prepend">
<a href="/" class="btn btn-secondary btn-sm" role="button" aria-pressed="true"><span class="fa fa-home"></span></a>
</div>
<input id="query-field" name="query-field" autocomplete="off" class="form-control"
type="text"
placeholder="Search for a variant, e.g. chr19:488506 or rs10424907" autofocus/>
<div class="input-group-append">
<button id="navigate-variant" class="btn btn-primary" type="submit">Search <span
<button id="navigate-variant" class="btn btn-secondary" type="submit"><span
class="fa fa-search"></span></button>
</div>
</div>
</form>
</div>
</div>
</div>
<center>
<a href="/" class="btn btn-primary btn-sm" role="button" aria-pressed="true"><span class="fa fa-home"></span> Back
to PheGET Homepage</a>
</center>

<br>
{# FIXME: This label does not update as the plot is panned or zoomed. We can resolve this in the future when we move to a dynamic frontend #}
<h1 style="margin-top: 1em;"><strong>Single-tissue eQTLs near {{ chrom }}:{{ "{:,}".format(center) }} </strong></h1>
<h1 style="margin-top: 1em;"><strong>Single-tissue eQTLs in {{ chrom }}:{{ "{:,}".format(start) }}-{{ "{:,}".format(end) }} </strong></h1>
</div>

<div class="container-fluid">
<div class="row">
<div id="lz-plot" class="ten columns">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small aside: "ten columns" is a skeleton.css construct; this page started life copied from a locuszoom example. It has no effect in bootstrap, which is what we are using for layout now. (I've pushed a change to remove that; feel free to clean up any other usages you might see)

</div>
</div>
</div>

<!-- Bootstrap dropdown menu to choose an additional tissue to plot -->
<div class="container-fluid">
<div class="row justify-content-start pb-1">
<div class="row justify-content-start">
<div class="col-sm">
Set a default gene or tissue as the anchor<br>
<div class="btn-group pr-1">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-html="true"
title="Add a new tissue with the current anchor gene, or add a new gene with the current anchor tissue">
<button type="button" class="btn btn-secondary" style="pointer-events: none;"> <span class="fa fa-plus"></span></button>
title="Choose a new <b>anchor tissue</b> or <b>gene</b>. All other added plots will be based on these anchors: when you add a <b>new gene</b>, the eQTLs plotted will be between that gene and the <b>anchor tissue</b>; when you add a <b>new tissue</b>, the eQTLs plotted will be between that tissue and the <b>anchor gene</b>. <br>Changing either anchor will delete all other plots and generate a single new plot, with eQTLs for the anchor gene in the anchor tissue.">
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;"><span class="fa fa-info-circle"></span> <span class="fa fa-anchor"></span></button>
</span>
<div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" id="dropdown_tissueselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Add a new panel with the selected tissue and the current anchor gene">
Tissue
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdown_anchorgeneselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a gene to serve as an anchor">
<i><span class="anchorgene"></span></i>
</button>
<!-- Dynamically generate tissue buttons from tissue_list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_tissueselect">
{% for single_tissue in tissue_list %}
<button class="dropdown-item tissueselect-class" type="button" value="{{ single_tissue }}">{{ single_tissue }}</button>
{% endfor %}
</div>
</div>
<div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" id="dropdown_geneselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Add a new panel with the selected gene and the current anchor tissue">
Gene
</button>
<!-- Dynamically generate gene list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_geneselect">
<!-- Dynamically generate anchor gene list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_anchorgeneselect">
{% for single_geneid, single_symbol in gene_list.items() %}
<button class="dropdown-item geneselect-class" type="button" value="{{ single_geneid }}"><i>{{ single_symbol }}</i></button>
<button class="dropdown-item anchorgeneselect-class" type="button" data-genesymbol="{{ single_symbol }}" data-geneid="{{ single_geneid }}"><i>{{ single_symbol }}</i></button>
{% endfor %}
</div>
</div>
</div>

<div class="btn-group">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-html="true"
title="Choose a new anchor tissue or gene">
<button type="button" class="btn btn-secondary" style="pointer-events: none;"> <span class="fa fa-anchor"></span></button>
<span class="d-inline-block">
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;"> in</button>
</span>

<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdown_anchortissueselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a tissue to serve as an anchor">
<span class="anchortissue"></span>
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdown_anchortissueselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a tissue to serve as an anchor">
<span class="anchortissue"></span>
</button>
<!-- Dynamically generate list of anchor tissue buttons -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_anchortissueselect">
{% for single_tissue in tissue_list %}
<button class="dropdown-item anchortissueselect-class" type="button" value="{{ single_tissue }}">{{ single_tissue }}</button>
<button class="dropdown-item anchortissueselect-class" type="button" value="{{ single_tissue }}">{{ single_tissue }}</button>
{% endfor %}
</div>
</div>

</div>
</div>
<div class="col-sm">
Add plot for a new gene in the anchor tissue<br>
<div class="btn-group pr-1">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-html="true"
title="Add an eQTL plot for a gene in the current anchor tissue">
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;"> <span class="fa fa-plus"></span></button>
</span>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdown_anchorgeneselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a gene to serve as an anchor">
<i><span class="anchorgene"></span></i>
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdown_geneselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a gene to add a new panel showing eQTLs between that gene and the current anchor tissue">
Gene
</button>
<!-- Dynamically generate anchor gene list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_anchorgeneselect">
<!-- Dynamically generate gene list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_geneselect">
{% for single_geneid, single_symbol in gene_list.items() %}
<button class="dropdown-item anchorgeneselect-class" type="button" value="{{ single_geneid }}"><i>{{ single_symbol }}</i></button>
<button class="dropdown-item geneselect-class" type="button" data-genesymbol="{{ single_symbol }}" data-geneid="{{ single_geneid }}"><i>{{ single_symbol }}</i></button>
{% endfor %}
</div>
</div>
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;">in</button>
<button type="button" class="btn btn-outline-secondary anchor-tissue-label" style="pointer-events: none;">{{ tissue }}</button>
</div>
</div>
</div>
</div>

<div class="container-fluid">
<div class="row justify-content-start pb-1">
<div class="col-sm">
<form class="yaxis-display" id="transform-y">
<div class="btn-group btn-group-toggle" data-toggle="buttons">
Add plot for the anchor gene in a new tissue
<div class="btn-group pr-1">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-html="true"
title="Switches the y variable between -log<sub>10</sub>(P-value) and Normalized Effect Size (NES). Triangles indicate eQTLs for upregulation (pointing up) or downregulation (pointing down) of gene expression with P-values < 0.05.">
<button type="button" class="btn btn-secondary" style="pointer-events: none;"> <span class="fa fa-arrows-alt-v"></span> Show on Y-Axis: </button>
title="Add a new tissue with the current anchor gene">
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;"> <span class="fa fa-plus"></span></button>
</span>
<label class="btn btn-success active" data-toggle="tooltip" data-placement="top" data-html="true"
title="Display -log<sub>10</sub>(P-values) on the Y-axis">
<input type="radio" name="y-options" autocomplete=off id="show-log-pvalue" value="log_pvalue"> P-values
</label>
<label class="btn btn-success" data-toggle="tooltip" data-placement="top" data-html="true"
title="Displays Normalized Effect Size (NES) on the Y-axis. See <a href='https://www.gtexportal.org/home/documentationPage'>the GTEx Portal</a> for an explanation of NES.">
<input type="radio" name="y-options" autocomplete=off id="show-beta" value="beta"> Effect Size (NES)
</label>
<button type="button" class="btn btn-outline-secondary anchor-gene-label" style="pointer-events: none;"><i>{{ symbol }}</i></button>
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;">in</button>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdown_tissueselect" data-toggle="dropdown" data-toggle-second="tooltip"
aria-haspopup="true" aria-expanded="false" title="Choose a tissue to add a new panel with eQTLs between that tissue and the current anchor gene">
Tissue
</button>
<!-- Dynamically generate tissue buttons from tissue_list -->
<div class="dropdown-menu scrollable-menu" aria-labelledby="dropdown_tissueselect">
{% for single_tissue in tissue_list %}
<button class="dropdown-item tissueselect-class" type="button" value="{{ single_tissue }}">{{ single_tissue }}</button>
{% endfor %}
</div>
</div>
</form>
</div>
</div>
<div class="col-sm">
Change the plotted values
<div class="btn-group pr-1">
<form class="yaxis-display" id="transform-y">
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-html="true"
title="Switches the y variable between -log<sub>10</sub>(P-value) and Normalized Effect Size (NES). Triangles indicate eQTLs for upregulation (pointing up) or downregulation (pointing down) of gene expression with P-values < 0.05.">
<button type="button" class="btn btn-outline-secondary" style="pointer-events: none;"> <span class="fa fa-arrows-alt-v"></span> Y-Axis: </button>
</span>
<label class="btn btn-secondary active" data-toggle="tooltip" data-placement="top" data-html="true"
title="Display -log<sub>10</sub>(P-values) on the Y-axis">
<input type="radio" name="y-options" autocomplete=off id="show-log-pvalue" value="log_pvalue"> P-values
</label>
<label class="btn btn-secondary" data-toggle="tooltip" data-placement="top" data-html="true"
title="Displays Normalized Effect Size (NES) on the Y-axis. See <a href='https://www.gtexportal.org/home/documentationPage'>the GTEx Portal</a> for an explanation of NES.">
<input type="radio" name="y-options" autocomplete=off id="show-beta" value="beta"> Effect Size
</label>
</div>
</form>
</div>
</div>

</div>
</div>

<br>

<div class="container-fluid">
<div class="row">
<div id="lz-plot" class="ten columns">
</div>
<div class="container-fluid">
<div class="card">
<div class="card-body">
<span class="d-inline-block" tabindex="0" data-toggle="tooltip" data-placement="top" data-html="true"
title="Created by Alan Kwong, Mukai Wang, Andy Boughton, Peter VandeHaar, and Hyun Min Kang. Source code can be found on <a href=https://github.com/statgen/pheget/>GitHub</a>.">
<span class="badge badge-pill badge-secondary" style="pointer-events: none;">
<span class="fa fa-lightbulb-o"></span> Credits
</span>
</span>
</div>
</div>
</div>

{% endblock %}

Expand All @@ -156,10 +188,11 @@ <h1 style="margin-top: 1em;"><strong>Single-tissue eQTLs near {{ chrom }}:{{ "{:
<script type="application/javascript">
'use strict';
var ANCHOR_GENE = {{gene_id|tojson}};
var ANCHOR_SYMBOL = {{symbol|tojson}};
var ANCHOR_TISSUE = {{tissue|tojson}};
var GENE_DICT = {{gene_list|tojson}};

[window.plot, window.datasources] = makeSinglePlot(ANCHOR_GENE, ANCHOR_TISSUE, '#lz-plot');
[window.plot, window.datasources] = makeSinglePlot(ANCHOR_GENE, ANCHOR_TISSUE, '#lz-plot', ANCHOR_SYMBOL);

// Use omnisearch (https://portaldev.sph.umich.edu/api/v1/annotation/omnisearch) to parse
document.getElementById('variant-search').addEventListener('submit', function (event) {
Expand All @@ -176,14 +209,14 @@ <h1 style="margin-top: 1em;"><strong>Single-tissue eQTLs near {{ chrom }}:{{ "{:
var tissueElements = document.getElementsByClassName('tissueselect-class');
Array.from(tissueElements).forEach((selectedTissue) => {
selectedTissue.addEventListener('click', (event) => {
addTrack(window.plot, window.datasources, ANCHOR_GENE, event.currentTarget.value);
addTrack(window.plot, window.datasources, ANCHOR_GENE, event.currentTarget.value, ANCHOR_SYMBOL);
});
});

var geneElements = document.getElementsByClassName('geneselect-class');
Array.from(geneElements).forEach((selectedGene) => {
selectedGene.addEventListener('click', (event) => {
addTrack(window.plot, window.datasources, event.currentTarget.value, ANCHOR_TISSUE);
addTrack(window.plot, window.datasources, event.currentTarget.dataset.geneid, ANCHOR_TISSUE, event.currentTarget.dataset.genesymbol);
});
});

Expand All @@ -192,31 +225,35 @@ <h1 style="margin-top: 1em;"><strong>Single-tissue eQTLs near {{ chrom }}:{{ "{:
selectedAnchorTissue.addEventListener('click', (event) => {
ANCHOR_TISSUE = event.currentTarget.value;
document.querySelector('.anchortissue').innerHTML = ANCHOR_TISSUE;
document.querySelector('.anchor-tissue-label').innerHTML = ANCHOR_TISSUE;
let panel_ids = Array.from(plot.layout.panels, panel => panel.id);
panel_ids.forEach(function(id){
if (id !=='genes'){
plot.removePanel(id);
}
});
// FIXME: seems to be an ugly way of removing panels one by one
addTrack(window.plot, window.datasources, ANCHOR_GENE, ANCHOR_TISSUE);
// TODO: When changing anchors, simply redirect to new URL with the new anchors
addTrack(window.plot, window.datasources, ANCHOR_GENE, ANCHOR_TISSUE, ANCHOR_SYMBOL);
});
});

var anchorgeneElements = document.getElementsByClassName('anchorgeneselect-class');
Array.from(anchorgeneElements).forEach((selectedAnchorGene) => {
selectedAnchorGene.addEventListener('click', (event) => {
ANCHOR_GENE = event.currentTarget.value;
ANCHOR_GENE = event.currentTarget.dataset.geneid;
ANCHOR_SYMBOL = event.currentTarget.dataset.genesymbol;
document.querySelector('.anchorgene').innerHTML = GENE_DICT[ANCHOR_GENE];
document.querySelector('.anchor-gene-label').innerHTML = GENE_DICT[ANCHOR_GENE]
let panel_ids = Array.from(plot.layout.panels, panel => panel.id);
panel_ids.forEach(function(id){
if (id !=='genes'){
plot.removePanel(id);
}
});
// FIXME: seems to be an ugly way of removing panels one by one
// TODO: Delete all other tracks
addTrack(window.plot, window.datasources, ANCHOR_GENE, ANCHOR_TISSUE);
// TODO: Same as above - redirect to new URL with new anchors
addTrack(window.plot, window.datasources, ANCHOR_GENE, ANCHOR_TISSUE, ANCHOR_SYMBOL);
});
});

Expand Down
Loading