Skip to content

Commit

Permalink
Merge pull request #44 from statgen/gene-name-in-region-plot
Browse files Browse the repository at this point in the history
Adding short gene names to the region plot title, and toning down the color scheme
  • Loading branch information
abought authored Dec 20, 2019
2 parents 7be01e3 + ccebbac commit 869dd38
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 250 deletions.
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">
</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

0 comments on commit 869dd38

Please sign in to comment.