Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/lib/
/dist/
/test/
/test-results/
16 changes: 4 additions & 12 deletions dev/examples/lis-gene-search-with-linkouts.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ <h1>&lt;lis-gene-search-element&gt; with &lt;lis-linkout-element&gt; and &lt;lis
strain { identifier }
geneFamilyAssignments { geneFamily { identifier } }
panGeneSets { identifier }
locations { chromosome { identifier } supercontig { identifier } start end strand }
locations { locatedOn { identifier } start end strand }
}
pageInfo {
pageSize
Expand Down Expand Up @@ -153,17 +153,9 @@ <h1>&lt;lis-gene-search-element&gt; with &lt;lis-linkout-element&gt; and &lt;lis
gene.panGeneSets
.map(({identifier}) => `<a href="#modal" data-pangeneset="${identifier}" uk-toggle>${identifier}</a>`);
const locations =
gene.locations.map(({chromosome, supercontig, start, end, strand}) => {
let location = `unknown`;
let type = '';
if (chromosome?.identifier) {
location = chromosome?.identifier;
type = 'chromosome';
} else if (supercontig?.identifier) {
location = supercontig?.identifier;
type = 'supercontig';
}
const text = `${location}:${start}-${end} (${strand}) (${type})`;
gene.locations.map(({locatedOn, start, end, strand}) => {
const location = locatedOn?.identifier ?? 'unknown';
const text = `${location}:${start}-${end} (${strand})`;
return `<a href="#modal"
data-location="${location}"
data-start="${start}"
Expand Down
3 changes: 2 additions & 1 deletion dev/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// https://github.com/legumeinfo/graphql-server

// Note: using port 4444 since port 4000 is default for jekyll site
const uri = 'https://graphql.lis.ncgr.org/';
//const uri = 'https://graphql.lis.ncgr.org/';
const uri = 'https://mines.dev.lis.ncgr.org/graphql-genefunction/';

// A function that gets data from a GraphQL server via a POST request.
// Adapted from https://graphql.org/graphql-js/graphql-clients/
Expand Down
6 changes: 3 additions & 3 deletions dev/lis-allele-search-element.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ <h1>&lt;lis-allele-search-element&gt;</h1>
// 1. Connector Functions

// Location Search -> GraphQL
// Query: genes(identifier: $id) { results { locations { chromosome { identifier } start end } } }
// Query: genes(identifier: $id) { results { locations { locatedOn { identifier } start end } } }
async function locationSearchFunction(identifier, abortSignal) {
// Trim whitespace from the identifier.
if (typeof identifier === 'string') {
Expand All @@ -70,7 +70,7 @@ <h1>&lt;lis-allele-search-element&gt;</h1>
genes(identifier: $identifier) {
results {
locations {
chromosome { identifier }
locatedOn { identifier }
start
end
}
Expand All @@ -84,7 +84,7 @@ <h1>&lt;lis-allele-search-element&gt;</h1>
const loc = result.locations[0];
// The alleles API expects the full contig identifier from the VCF,
// e.g. "glyma.Wm82.gnm4.Gm16", not just "Gm16".
const fullChrom = loc.chromosome.identifier;
const fullChrom = loc.locatedOn.identifier;

return {
chromosome: fullChrom,
Expand Down
203 changes: 203 additions & 0 deletions dev/lis-gene-function-search-element.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<!DOCTYPE html>

<html>

<head>
<meta charset="utf-8" />
<title>LIS Web-Components - &lt;lis-gene-function-search-element&gt;</title>
<!-- CSS framework -->
<link rel="stylesheet" type="text/css" href="../node_modules/uikit/dist/css/uikit.min.css">
<script src="../node_modules/uikit/dist/js/uikit.min.js"></script>
<!-- web components polyfills -->
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="../node_modules/lit/polyfill-support.js"></script>
<!-- GraphQL -->
<script type="text/javascript" src="./graphql.js"></script>
<!-- web components -->
<script type="module" src="../lib/index.js"></script>
</head>

<body>

<div class="uk-container uk-margin-bottom">
<h1>&lt;lis-gene-function-search-element&gt;</h1>
<p>
TODO: Add description here.
</p>
<p>
Optionally, all searches can be limited to a specific genus by setting the <code>genus</code> attribute/property.
This will cause the genus field of the search form to be automatically set and disabled so that users cannot change it.
Similarly, all searches can be limited to a specific species by setting the <code>species</code> attribute/property in conjunction with the <code>genus</code> attribute/property.
You can try setting the <code>genus</code> and <code>species</code> properties in this example using the <code>geneFunctionSearchElement</code> variable in the Web console.
</p>
<p>
Example text for the Gene ID, Traits, Publication ID, and Author fields can be provided by setting the <code>geneIdentifierExample</code>, <code>traitsExample</code>, <code>publicationExample</code>, and <code>authorExample</code> attributes/properties, respectively.
</p>

<hr>
</div>

<div class="uk-container uk-container-expand">
<!-- the custom gene function search element -->
<lis-gene-function-search-element id="gene-function-search" geneIdentifierExample="Glyma01g37810, E9, Dt1 FT" traitsExample="flowering, maturity, height" publicationExample="10.1111/jipb.13070 or 33458938" authorExample="Watanobe"></lis-gene-function-search-element>
</div>

<!-- set the search function by property because functions can't be set as attributes -->
<script type="text/javascript">

// uses the LIS GraphQL API to get data used to construct the search form
const formDataQuery = `
query FormDataQuery {
organisms {
results {
genus
species
}
}
}
`;

function getFormData({abortSignal}) {
return graphqlQuery(uri, formDataQuery, {}, abortSignal)
.then(({data}) => {
// bin the strains by genus then species
const binnedFormData = {};
data.organisms.results.forEach(({genus, species}) => {
if (!(genus in binnedFormData)) {
binnedFormData[genus] = [];
}
binnedFormData[genus].push(species);
});
// collapse the bins into arrays of objects
const genuses =
Object.entries(binnedFormData).map(([genus, binnedSpecies]) => {
const species = binnedSpecies.map((species) => {
return {species};
});
return {genus, species};
});
// return the expected form data object
return {genuses};
});
}

const geneFunctionQuery = `
query GeneFunctions($symbol: String, $trait: String, $gene: String, $genus: String, $species: String, $publicationId: String, $author: String, $page: Int, $pageSize: Int) {
geneFunctions(symbol: $symbol, trait: $trait, gene: $gene, genus: $genus, species: $species, publicationId: $publicationId, author: $author, page: $page, pageSize: $pageSize) {
pageInfo {
currentPage
pageSize
numResults
pageCount
hasPreviousPage
hasNextPage
}
results {
symbol
symbolLong
classicalLocus
synonyms
pubName
genes {
name
identifier
}
synopsis
traits {
name
}
publications {
citation
title
doi
}
}
}
}
`;

// search function
function getGeneFunctions(searchData,{abortSignal}) {
const variables = {
symbol: null,
trait: searchData['traits'],
gene: searchData['geneIdentifier'],
genus: searchData['genus'],
species: searchData['species'],
publicationId: searchData['pubId'],
author: searchData['author'],
page: searchData['page'],
pageSize: 10
};

// shim the results for the Web Component
return graphqlQuery(uri, geneFunctionQuery, variables, abortSignal)
.then(({data}) => {
// extract the page info
const {hasNextPage: hasNext, numResults, pageSize, pageCount: numPages}
= data.geneFunctions.pageInfo;

// flatten results
const results =
data.geneFunctions.results.map(({symbol, symbolLong, synonyms, classicalLocus, pubName, genes, synopsis, traits, publications}) => {
return {
geneSymbols: [symbol, ...synonyms.filter(i => ![symbol, symbolLong].includes(i)).map(s => ({value: s, linkable: false}))],
geneSymbolDescription: symbolLong,
geneModelPubName: pubName,
geneModelFullName: genes[0]?.identifier,
synopsis,
traits: traits.map(t => t.name).join(', '),
citations: publications
};
});


// construct the expected paginated results object
const paginatedResults = {hasNext, numResults, pageSize, numPages, results};
return paginatedResults;
});
}

const geneLinkoutsQuery = `
query GeneLinkoutsQuery($identifier: ID!) {
geneLinkouts(identifier: $identifier) {
results {
href
text
}
}
}
`;

function geneLinkoutsFunction({type, variables}, {abortSignal} = {}) {
if (type === 'gene') {
return graphqlQuery(uri, geneLinkoutsQuery, variables, abortSignal)
.then(({data}) => ({results: data.geneLinkouts.results}));
}
if (type === 'symbol') {
const href = `https://mines.dev.lis.ncgr.org/glycinemine/genefunction:${variables.identifier}`;
return Promise.resolve({results: [{href, text: href}]});
}
if (type === 'publication') {
const href = `https://doi.org/${variables.identifier}`;
const text = variables.label || href;
return Promise.resolve({results: [{href, text}]});
}
return Promise.reject(new Error(`Unknown linkout type: ${type}`));
}

// bind component properties
const geneFunctionSearchElement = document.getElementById('gene-function-search');
geneFunctionSearchElement.formDataFunction = getFormData;
geneFunctionSearchElement.searchFunction = getGeneFunctions;
geneFunctionSearchElement.linkoutFunction = geneLinkoutsFunction;
geneFunctionSearchElement.linkoutColumns = {
geneSymbols: 'symbol',
geneModelFullName: 'gene',
};

</script>

</body>

</html>
10 changes: 4 additions & 6 deletions dev/lis-gene-search-element.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ <h1>&lt;lis-gene-search-element&gt;</h1>
strain { identifier }
geneFamilyAssignments { geneFamily { identifier } }
panGeneSets { identifier }
locations { chromosome { identifier } supercontig { identifier } start end strand }
locations { locatedOn { identifier } start end strand }
}
pageInfo {
hasNextPage
Expand Down Expand Up @@ -157,12 +157,10 @@ <h1>&lt;lis-gene-search-element&gt;</h1>
gene.panGeneSets
.map(({identifier}) => identifier);
const locations =
gene.locations.map(({chromosome, supercontig, start, end, strand}) => {
gene.locations.map(({locatedOn, start, end, strand}) => {
const interval = `${start}-${end} (${strand})`;
if (chromosome?.identifier) {
return `${chromosome?.identifier}:${interval} (chromosome)`;
} else if (supercontig?.identifier) {
return `${supercontig?.identifier}:${interval} (supercontig)`;
if (locatedOn?.identifier) {
return `${locatedOn.identifier}:${interval}`;
}
return `unknown:${interval}`;
});
Expand Down
4 changes: 2 additions & 2 deletions dev/lis-trait-association-search-element.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ <h1>&lt;lis-trait-association-search-element&gt;</h1>
genus
species
}
dataSet {
dataSets {
publication {
firstAuthor
pubMedId
Expand All @@ -119,7 +119,7 @@ <h1>&lt;lis-trait-association-search-element&gt;</h1>
genus
species
}
dataSet {
dataSets {
publication {
firstAuthor
pubMedId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<li><strong>species:</strong> The selected species in the search for.</li>
<li><strong>type:</strong> The selected type in the search form. Either 'GWAS' or 'QTL'.</li>
<li><strong>traits:</strong> The traits provided in the search form.</li>
<li><strong>pubid</strong> The publication ID provided in the search form. Either a PubMed ID or a DOI.</li>
<li><strong>pubId</strong> The publication ID provided in the search form. Either a PubMed ID or a DOI.</li>
<li><strong>author</strong> The author provided in the search form.</li>
<li><strong>page:</strong> What page of results is loaded. Starts at 1.</li>
</ul>
Expand Down
Loading
Loading