Skip to content

Commit

Permalink
Changed parentage tool to new parentage viewer with link to Helium.
Browse files Browse the repository at this point in the history
  • Loading branch information
That-Thing committed Dec 16, 2024
1 parent 7acf365 commit 49ffeeb
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 122 deletions.
46 changes: 46 additions & 0 deletions tools/parentage/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.uk-button-primary {
background-color: #235626;
}
.uk-button-primary:hover {
background-color: #1a4720;
}
.uk-button-primary:disabled:hover {
background-color: transparent;
}
.uk-link, a, .uk-nav-default > li > a:hover, .uk-dropdown-nav > li.uk-active > a, .uk-dropdown-nav > li > a:hover {
color: #060;
}
.uk-link:hover, a:hover {
color: #1a4720;
}
.uk-table th {
color: #2b2b2b;
font-weight: 600;
}
html, .uk-text-meta, .uk-textarea, .uk-select, .uk-dropdown-nav > li > a, .uk-nav-default > li > a {
color: #282828;
}
label {
display: block;
}

.letter-filter {
margin: 20px 0;
}

.letter-filter span {
margin-right: 10px;
cursor: pointer;
font-weight: bold;
font-size: 1.2em;
}

.letter-filter span:hover {
color: #1a4720;
text-decoration: underline;
}

.letter-filter span.active {
color: #060;
text-decoration: underline;
}
145 changes: 62 additions & 83 deletions tools/parentage/index.html
Original file line number Diff line number Diff line change
@@ -1,83 +1,62 @@
---
title: Parentage
sitemap: parentage
layout: default

---

<h2>Soy Parentage and Pedigrees</h2>

<p>
The soybean parentage information below was partially gleaned from the Uniform Soybean Tests for the
<a href="https://www.ars.usda.gov/southeast-area/stoneville-ms/crop-genetics-research/docs/uniform-soybean-tests/"><b>Southern</b></a>
and
<a href="https://www.ars.usda.gov/midwest-area/west-lafayette-in/crop-production-and-pest-control-research/docs/uniform-soybean-tests-northern-region/"><b>Northern</b></a>
regions as well as other sources such as USDA technical bulletins, variety registrations and PVP applications.
The strains that appear here were part of the uniform trials and not the preliminary trials. The pedigree of
individual strains was followed back to named strains in both maternal and paternal lineages where possible.
An unknown parent is indicated with "-". When available, PVP registration numbers are noted,
as are synonyms for the strains - including the PI number for lines deposited at GRIN.
Check for additional information about PI lines at the <a href="https://npgsweb.ars-grin.gov/gringlobal/search"><b>GRIN search page</b></a>.
</p>

<p>
Strain names are prefixed with a code that identifies the program that produced them. The code is usually the first two
letters in the strain name followed by the year it was released as a two digit number.
See <a href="/tools/parentage/prefix_codes"><b>code prefixes and descriptions here</b></a>.
</p>

<p>
Pedigrees are represented in column 4. To give an example:
<a href="/tools/parentage/groupc/"><u><b>CS31</b></u></a> has parents <u>S10</u> (maternal) and <u>Mitchell</u> (paternal).
The pedigree string <u>( S10 , Mitchell ( Amsoy , Wayne ) )</u>
can be read as: <u>CS31</u> is progeny of <u>S10</u> and <u>Mitchell</u>;
and <u>Mitchell</u> is progeny of <u>Amsoy</u> and <u>Wayne</u>.
</p>
<p>
The information below is also available for
<a href="https://data.soybase.org/annex/Glycine/max/pedigrees/glyma.mixed.ped.2023-11-08.tsv.gz"><b>download</b>
</a> - for example,
if you wish to filter on pedigrees that contain an accession of interest.<br>
We welcome submissions by the community of new or updated pedigree information.
Please use this
<a href="https://data.soybase.org/annex/Glycine/max/pedigrees/SoyBaseParentageWorksheetV3.xls"><b>data submission spreadsheet</b></a>.
</p>

<p><b>Browse or search accessions beginning with ...</b><p>
<table class="uk-table uk-width-1-2 uk-text-center uk-table-condensed">
<tbody>
{% for item in site.data.parentage_groups %}
{% assign display_name = item.group | remove:"group" %}
<tr>&nbsp;<a href="/tools/parentage/{{item.group | downcase}}">{{ display_name }}</a>&nbsp;</tr>
{% endfor %}
</tbody>
</table>

<div class="uk-overflow-auto">
<table class="uk-table uk-table-small uk-table-hover uk-table-divider uk-table-striped">
<thead>
<tr>
<th><b>Individual</b></th>
<th><b>Female Parent</b></th>
<th><b>Male Parent</b></th>
<th><b>Pedigree</b></th>
<th><b>Synonyms</b></th>
<th><b>Notes</b></th>
</tr>
</thead>
<tbody>
{% for item in site.data.parentage.group0-9 %}
<tr>
<td>{{ item.Individual }}</td>
<td>{{ item.Parent1 }}</td>
<td>{{ item.Parent2 }}</td>
<td>{{ item.Pedigree }}</td>
<td>{{ item.Synonyms}}</td>
<td>{{ item.Comment }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>


---
title: Parentage Viewer
---

<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: 'en' }}">
<head>
{% include head.html %}
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="./js/main.js"></script>
<link rel="stylesheet" href="./css/main.css">
</head>

<body>
<div id="detail-modal" uk-modal>
<div class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical">
<button class="uk-modal-close-full uk-close-large" type="button" uk-close></button>
<h2 id="modal-title"></h2>
<div id="modal-content">
<div id="modal-loader" class="uk-flex uk-flex-center uk-flex-middle" hidden>
<div uk-spinner="ratio: 1"></div>
</div>
</div>
</div>
</div>
<div class="uk-container">
<h1>Parentage</h1>
<p>
Put a description and instructions here...
</p>
<p>
Click on the name to view more information.
</p>
<div id="loader" class="uk-flex uk-flex-center uk-flex-middle" hidden>
<div uk-spinner="ratio: 1"></div>
</div>
<span id="error" class="uk-label uk-label-danger" hidden>
Data could not be loaded. This is likely due to a problem with the server. Please try again later.
</span>
<div class="letter-filter uk-margin"></div>
<table id="parentageTable" class="uk-table uk-table-divider stripe">
<thead>
<tr>
<th>Individual</th>
<th>Female Parent</th>
<th>Male Parent</th>
<!-- <th>Pedigree</th>
<th>Synonyms</th>
<th>Notes</th> -->
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>


<script src="https://cdn.datatables.net/1.13.5/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.5/css/jquery.dataTables.min.css">
</body>

</html>
183 changes: 183 additions & 0 deletions tools/parentage/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
$(document).ready(function () {
var table = $('#parentageTable').DataTable();

// Show and hide the loader
function toggleLoader(show) {
if (show) {
$('#loader').removeAttr('hidden');
} else {
$('#loader').attr('hidden', true);
}
}

// Fetch and populate letters
function fetchAndPopulateLetters() {
toggleLoader(true); // Show loader
$.ajax({
url: 'https://app.soybase.org/api/parentage/genotypes',
method: 'GET',
success: function (data) {
const validData = data.slice(1); // Skip the header
const letters = new Set(
validData.map(item => {
const firstChar = item[0].trim().charAt(0); // Get the first character
return isNaN(firstChar) ? firstChar.toUpperCase() : '0-9'; // Group numbers as "0-9"
})
);

// Sort letters alphabetically, ensuring "0-9" comes first
const sortedLetters = Array.from(letters).sort((a, b) => {
if (a === '0-9') return -1; // "0-9" comes first
if (b === '0-9') return 1;
return a.localeCompare(b); // Alphabetical sort for letters
});

// Populate the letter filter
const letterFilterContainer = $('.letter-filter');
letterFilterContainer.empty(); // Clear existing letters

// Add the "All" option
letterFilterContainer.append('<span data-letter="all" class="active">All</span>');

// Add the rest of the letters
sortedLetters.forEach(letter => {
letterFilterContainer.append(`<span data-letter="${letter}">${letter}</span>`);
});

// Add click event listeners for filtering
letterFilterContainer.find('span').on('click', function () {
$('.letter-filter span').removeClass('active');
$(this).addClass('active');
const selectedLetter = $(this).data('letter');
fetchAndDisplayData(selectedLetter, validData);
});

// Initially fetch all data
fetchAndDisplayData('all', validData);
toggleLoader(false); // Hide loader
},
error: function (error) {
console.error('Error fetching data:', error);
toggleLoader(false); // Hide loader on error
}
});
}

// Function to filter and display data
function fetchAndDisplayData(filterLetter, data) {
table.clear();

data.forEach(function (item) {
const firstChar = item[0].trim().charAt(0).toUpperCase(); // Normalize first character
const isNumber = !isNaN(firstChar); // Check if the first character is a number
if (filterLetter === 'all' || (filterLetter === '0-9' && isNumber) || firstChar === filterLetter) {
const individualLink = `<a href="#" class="individual-link" data-individual="${item[0]}">${item[0] || '-'}</a>`;
table.row.add([
individualLink || '-', // Individual
item[1] || '-', // Female Parent
item[2] || '-', // Male Parent
]);
}
});

table.draw();
}

// Attach delegated event listener to handle clicks on dynamically added links
$('#parentageTable tbody').on('click', '.individual-link', function (e) {
e.preventDefault();
const individualName = $(this).data('individual');
openModal(individualName); // Open the modal and fetch details
});

// Open modal and fetch data for an individual
function openModal(individualName) {
$('#modal-title').text(`Details for ${individualName}`);
$('#modal-content').html(`
<div id="modal-loader" class="uk-flex uk-flex-center uk-flex-middle">
<div uk-spinner="ratio: 1"></div>
</div>
`);

// Fetch data
$.ajax({

url: `https://app.soybase.org/api/parentage?q=${encodeURIComponent(individualName)}`,
method: 'GET',
success: function (response) {
let parsedData;
try {
parsedData = JSON.parse(response); // Response is returned as string, needs to be parsed
} catch (error) {
console.error('Error parsing response:', error);
$('#modal-content').html('<p>Error parsing response data. Please try again later.</p>');
return;
}

let htmlContent = '';

// Link to Helium
htmlContent += `
<h4>Helium Pedigree Viewer</h4>
<p>
<button class="uk-button uk-button-primary" onclick="window.open('https://helium.hutton.ac.uk/#/pedigree?germinateUrl=https://app.soybase.org/api/parentage/pedigree.helium.zip?q=${encodeURIComponent(individualName)}', '_blank')">Pedigree Viewer</button>
</p>
<p class="uk-text-meta">For an interactive plot of the pedigree, click the "Pedigree viewer" button, then choose "Import".</p>
`;

// Text representation of pedigree
if (parsedData.construction && parsedData.construction.length > 0 && !parsedData.construction.some(line => line.includes('Skipping parentage report'))) {
htmlContent += `<h4>Text representation of pedigree for ${individualName}:</h4><pre>`;
parsedData.construction.forEach(line => {
htmlContent += `${line}\n`;
});
htmlContent += `</pre>`;
}

// Lines in the pedigree
if (parsedData.matches && parsedData.matches !== "NULL") {
if (Array.isArray(parsedData.matches) && parsedData.matches.length > 0) {
htmlContent += `
<h4>${individualName} is in the pedigree of these lines:</h4>
<p>${parsedData.matches.slice(0, 10).join(', ')}${parsedData.matches.length > 10 ? ', ...' : ''}</p>
`;
} else if (typeof parsedData.matches === 'string') {
htmlContent += `
<h4>${individualName} is in the pedigree of these lines:</h4>
<p>${parsedData.matches}</p>
`;
}
}

// Alternate names
if (parsedData.synonyms && parsedData.synonyms !== "NULL") {
htmlContent += `
<h4>Alternate names for ${individualName}:</h4>
<p>${parsedData.synonyms}</p>
`;
}

// Comments
if (parsedData.comments && parsedData.comments !== "NULL") {
htmlContent += `
<h4>Comments for ${individualName}:</h4>
<ul>
${parsedData.comments.map(comment => `<li>${comment}</li>`).join('')}
</ul>
`;
}

$('#modal-content').html(htmlContent);
},
error: function (error) {
console.error(`Error fetching data for ${individualName}:`, error);
$('#modal-content').html('<p>Error fetching details. Please try again later.</p>');
}
});

// Open the modal
UIkit.modal('#detail-modal').show();
}

fetchAndPopulateLetters();
});
Loading

0 comments on commit 49ffeeb

Please sign in to comment.