Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Maciej Spiegel committed Feb 8, 2024
0 parents commit d39cc33
Show file tree
Hide file tree
Showing 6 changed files with 1,261 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.DS_Store
/README.md
Binary file added JAJA.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
368 changes: 368 additions & 0 deletions main.html

Large diffs are not rendered by default.

521 changes: 521 additions & 0 deletions publications.bib

Large diffs are not rendered by default.

250 changes: 250 additions & 0 deletions scripts.js
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();
120 changes: 120 additions & 0 deletions styles.css
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;
}

0 comments on commit d39cc33

Please sign in to comment.