-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Maciej Spiegel
committed
Feb 8, 2024
0 parents
commit d39cc33
Showing
6 changed files
with
1,261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/.DS_Store | ||
/README.md |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
// Dictionary to store publications data | ||
let publicationsData = []; | ||
|
||
// Function to parse BibTeX data and extract specific fields for a single entry | ||
function parseBibTeXEntry(entryData) { | ||
// Initialize variables to store extracted fields | ||
let year = ""; | ||
let title = ""; | ||
let authors = []; | ||
let journal = ""; | ||
let keywords = []; | ||
let doi = ""; | ||
|
||
// Split the entry data by lines | ||
const lines = entryData.split('\n'); | ||
|
||
// Loop through each line to find and extract the fields | ||
lines.forEach(line => { | ||
if (line.includes("year = {")) { | ||
year = line.match(/(\d{4})/)[0]; | ||
} else if (line.trim().startsWith("title = {")) { | ||
title = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).replace(/{|}/g, "").trim(); // Extract entire title and remove all { and } characters from the title | ||
} else if (line.includes("author = {")) { | ||
// Extract authors using comma and "and" as separators | ||
const authorString = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).trim(); | ||
authors = extractAuthors(authorString); | ||
} else if (line.includes("journal = {")) { | ||
journal = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).trim(); | ||
} else if (line.includes("keywords = {")) { | ||
keywords = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).split(",").map(keyword => keyword.trim().toLowerCase()); // Convert to lowercase | ||
} else if (line.includes("doi = {")) { | ||
doi = line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")).trim(); | ||
} | ||
}); | ||
|
||
// Construct and return an object with the extracted fields | ||
return { year, title, authors, journal, keywords, doi }; | ||
} | ||
|
||
// Function to extract authors' names from the author string using 'and' as separator | ||
function extractAuthors(authorString) { | ||
// Split author string by 'and' and trim whitespace | ||
const authorNames = authorString.split(/\s+and\s+/).map(name => name.trim()); | ||
// Initialize array to store individual authors' names | ||
const authors = authorNames.map(authorName => { | ||
const [surname, ...rest] = authorName.split(/\s*,\s*/); | ||
return `${rest.join(" ")} ${surname}`; | ||
}); | ||
return authors; | ||
} | ||
|
||
// Function to parse BibTeX data and extract fields for all entries | ||
function parseBibTeX(bibtex) { | ||
const entries = bibtex.split('@').filter(entry => entry.trim() !== ''); | ||
const data = []; | ||
|
||
entries.forEach(entry => { | ||
const parsedEntry = parseBibTeXEntry('@' + entry.trim()); | ||
data.push(parsedEntry); | ||
}); | ||
|
||
return data; | ||
} | ||
|
||
|
||
// Function to add years to the list | ||
function addYearsToList() { | ||
const yearsList = document.getElementById("years-list"); | ||
|
||
// Extract unique years from publicationsData | ||
const uniqueYears = [...new Set(publicationsData.map((publication) => publication.year))]; | ||
|
||
// Sort the unique years array in descending order | ||
uniqueYears.sort((a, b) => b - a); | ||
|
||
uniqueYears.forEach((year) => { | ||
const listItem = createYearListItem(year); | ||
yearsList.appendChild(listItem); | ||
}); | ||
} | ||
|
||
// Call the function to add years to the list | ||
addYearsToList(); | ||
|
||
|
||
// Function to load BibTeX data from external file | ||
function loadBibTeXData() { | ||
fetch('publications.bib') // Assuming the BibTeX file is named publications.bib | ||
.then(response => { | ||
if (!response.ok) { | ||
throw new Error('Failed to load BibTeX data'); | ||
} | ||
return response.text(); | ||
}) | ||
.then(data => { | ||
publicationsData = parseBibTeX(data); | ||
addYearsToList(); // Call function to add years to the list | ||
}) | ||
.catch(error => { | ||
console.error('Error loading BibTeX data:', error); | ||
}); | ||
} | ||
|
||
// Call the function to load BibTeX data | ||
loadBibTeXData(); | ||
|
||
// Function to create a timeline item | ||
function createTimelineItem(year, title, authors, journal, tags, doi) { | ||
const timelineItem = document.createElement("div"); | ||
timelineItem.classList.add("timeline-item"); | ||
|
||
// Map each tag to a Bootstrap badge | ||
const tagsHTML = tags.map(tag => `<span class="badge bg-primary-subtle border border-primary-subtle text-primary-emphasis rounded-pill">${tag}</span>`).join(' '); | ||
|
||
// Create a string of authors separated by commas | ||
const authorsString = authors.join(', ').replace(/, and/, ' and'); // Replace comma before 'and' | ||
|
||
const content = ` | ||
<div class="timeline-content"> | ||
<div class="altmetric-embed" data-badge-type="bar" data-link-target="_blank" data-doi="${doi}" style="display: inline-block"></div> | ||
<h3>${title}</h3> | ||
<small>${authorsString}<br> | ||
<i>${journal}, ${year}</small></i> | ||
<p>${tagsHTML}</p> | ||
</div> | ||
`; | ||
|
||
timelineItem.innerHTML = content; | ||
|
||
return timelineItem; | ||
} | ||
|
||
|
||
// Function to filter publications by year | ||
let isExpanded = 0; // Declare isExpanded in the global scope | ||
|
||
function filterPublications(selectedYear) { | ||
const timeline = document.querySelector(".timeline"); | ||
|
||
// Clear existing timeline items | ||
timeline.innerHTML = ''; | ||
|
||
// Filter publications based on the selected year | ||
const filteredPublications = publicationsData.filter(publication => publication.year == selectedYear); | ||
|
||
if (filteredPublications.length === 0) { | ||
const noPublicationItem = document.createElement("div"); | ||
noPublicationItem.textContent = "No publications for the selected year."; | ||
timeline.appendChild(noPublicationItem); | ||
return; | ||
} | ||
|
||
filteredPublications.forEach((publication) => { | ||
const { year, title, authors, journal, keywords, doi } = publication; | ||
const timelineItem = createTimelineItem(year, title, authors, journal, keywords, doi); | ||
timeline.appendChild(timelineItem); | ||
}); | ||
|
||
// Hide other buttons if the timeline is not collapsed | ||
const yearsList = document.getElementById("years-list"); | ||
let buttons = yearsList.querySelectorAll("button"); | ||
let parentRect = yearsList.getBoundingClientRect(); // Get the bounding rectangle of the parent element | ||
let parentCenter = (parentRect.left + parentRect.right) / 2; // Calculate the center of the parent element | ||
|
||
// Proceed with hiding/showing buttons based on collapse state | ||
console.log("isExpanded:", isExpanded); | ||
if (isExpanded === 0) { | ||
console.log("Collapsing timeline..."); | ||
buttons.forEach(button => { | ||
if (button.textContent == selectedYear.toString()) { | ||
// Centering the button horizontally | ||
let buttonRect = button.getBoundingClientRect(); // Get the bounding rectangle of the button | ||
let buttonCenter = (buttonRect.left + buttonRect.right) / 2; // Calculate the center of the button | ||
let translateXValue = parentCenter - buttonCenter; // Calculate the translation value | ||
button.style.transition = "transform 0.5s ease"; | ||
button.style.transform = `translateX(${translateXValue}px)`; // Correctly center the button | ||
} else { | ||
// Hiding buttons for years other than the selected one | ||
button.style.transition = "opacity 0.5s ease, transform 0.5s ease"; | ||
button.style.opacity = "0"; | ||
button.style.transform = "translateY(-50%)"; | ||
setTimeout(() => { | ||
button.style.visibility = "hidden"; // Use "none" to hide the button | ||
}, 500); | ||
} | ||
}); | ||
isExpanded = 1; // Update flag variable | ||
} else { // If timeline is expanded | ||
console.log("Expanding timeline..."); | ||
buttons.forEach(button => { | ||
console.log("Showing button:", button.textContent); | ||
button.style.transition = "opacity 0.5s ease, transform 0.5s ease"; // Adding transition effect | ||
button.style.visibility = "visible"; // Set display to inline before opacity transition | ||
setTimeout(() => { | ||
button.style.opacity = "1"; // Set opacity to 1 after display change | ||
button.style.transform = "translateY(0)"; // Move the button back to its original position | ||
}, 50); // Delay opacity change after display transition | ||
}); | ||
isExpanded = 0; // Update flag variable | ||
} | ||
|
||
_altmetric_embed_init(); // Assuming this function is correctly defined elsewhere | ||
} | ||
|
||
function createYearListItem(year) { | ||
const listItem = document.createElement("li"); | ||
listItem.classList.add("me-3"); | ||
listItem.innerHTML = `<button class="btn btn-link" data-bs-toggle="collapse" data-bs-target="#timelineitems" onclick="filterPublications(${year})">${year}</button>`; | ||
return listItem; | ||
} | ||
|
||
|
||
// Scrol Top Button | ||
document.addEventListener("DOMContentLoaded", function () { | ||
|
||
const scrollToTopBtn = document.getElementById("scrollToTopBtn"); | ||
|
||
// Show or hide the button based on scroll position | ||
window.onscroll = function () { | ||
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) { | ||
scrollToTopBtn.style.opacity = "1"; | ||
} else { | ||
scrollToTopBtn.style.opacity = "0"; | ||
} | ||
}; | ||
|
||
// Scroll to the top when the button is clicked | ||
scrollToTopBtn.addEventListener("click", function () { | ||
document.body.scrollTop = 0; // For Safari | ||
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE, and Opera | ||
}); | ||
}); | ||
|
||
// Function to generate a random delay between min and max seconds before showing toast | ||
function getRandomDelay(min, max) { | ||
return Math.floor(Math.random() * (max - min + 1) + min) * 1000; // Convert seconds to milliseconds | ||
} | ||
|
||
// Function to show the toast after a random delay between 5 and 10 seconds | ||
function showRandomToast() { | ||
var toastElement = document.getElementById('myToast'); | ||
var toast = new bootstrap.Toast(toastElement); | ||
var delay = getRandomDelay(5, 10); // Random delay between 5 and 10 seconds | ||
setTimeout(function () { | ||
toast.show(); | ||
}, delay); | ||
} | ||
|
||
// Call the function to show the toast | ||
showRandomToast(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* UNDER CONSTRUCTIOn - Research Papers Timeline */ | ||
|
||
|
||
.timeline { | ||
position: relative; | ||
padding: 20px 0; | ||
margin-top: 20px; | ||
} | ||
|
||
.timeline-item { | ||
display: flex; | ||
margin-bottom: 20px; | ||
} | ||
|
||
.timeline-year { | ||
font-size: 1.5rem; | ||
font-weight: bold; | ||
margin-right: 20px; | ||
color: #333; | ||
} | ||
|
||
.timeline-content { | ||
flex: 1; | ||
} | ||
|
||
.timeline-content h3 { | ||
font-size: 1.2rem; | ||
margin-bottom: 5px; | ||
} | ||
|
||
.timeline-content p { | ||
font-size: 1rem; | ||
color: #666; | ||
} | ||
|
||
/* Add styles for the years buttons */ | ||
#years-list { | ||
list-style: none; | ||
padding: 0; | ||
display: flex; | ||
gap: 10px; | ||
} | ||
|
||
#years-list button { | ||
background-color: #f0f0f0; | ||
color: #333; | ||
border: 1px solid #ccc; | ||
border-radius: 5px; | ||
/* Adjusted border-radius for a sharper look */ | ||
padding: 8px 16px; | ||
cursor: pointer; | ||
transition: background-color 0.3s ease; | ||
} | ||
|
||
#years-list button:hover { | ||
background-color: #e0e0e0; | ||
} | ||
|
||
|
||
/* WORKING - Outlined text of research areas */ | ||
.outlined-text { | ||
font-size: 2rem; | ||
/* Adjust the size as needed */ | ||
line-height: 1.4; | ||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); | ||
white-space: break-space; | ||
} | ||
|
||
/* WORKING - Divider */ | ||
.divider { | ||
width: 100%; | ||
height: 3rem; | ||
background-color: rgba(0, 0, 0, .1); | ||
border: solid rgba(0, 0, 0, .15); | ||
border-width: 1px 0; | ||
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15); | ||
} | ||
|
||
/* WORKING - Scroll to Top button */ | ||
#scrollToTopBtn { | ||
position: fixed; | ||
bottom: 20px; | ||
right: 20px; | ||
width: 32px; | ||
height: 32px; | ||
opacity: 0; | ||
transition: opacity 0.3s ease; | ||
} | ||
|
||
#scrollToTopBtn button { | ||
background-color: #f8f9fa; | ||
/* Adjust the background color as needed */ | ||
color: #343a40; | ||
/* Adjust the text color as needed */ | ||
border: none; | ||
width: 100%; | ||
height: 100%; | ||
padding: 0; | ||
font-size: 1rem; | ||
/* Adjusted font size for better fit */ | ||
cursor: pointer; | ||
transition: background-color 0.3s ease, box-shadow 0.3s ease, color 0.3s ease; | ||
} | ||
|
||
#scrollToTopBtn button:hover { | ||
background-color: #e9ecef; | ||
/* Adjust the hover background color as needed */ | ||
} | ||
|
||
/* Icon styling */ | ||
#scrollToTopBtn i { | ||
font-size: 1.25rem; | ||
/* Adjusted icon size for better fit */ | ||
/* Adjust other icon styles as needed */ | ||
} | ||
|
||
/* Hide the button by default */ | ||
#scrollToTopBtn.hidden { | ||
display: none; | ||
} |