Wars & Conflicts Through Time Simulator

Filtered Conflicts

  • Adjust filters and click "Show Conflicts".

Conflict Details

Select a conflict from the list to see details.

Timeline (Selected Period)

Period: ${formatYear(conflict.startYear)} – ${formatYear(conflict.endYear)}

Region(s): ${conflict.regions.join(', ')}

Key Belligerents: ${formatBelligerents(conflict.belligerents)}

Summary: ${conflict.summary}

`; } else { clearConflictDetails(); } } function clearConflictDetails() { conflictDetailNameEl.textContent = "Conflict Details"; conflictDetailContentEl.innerHTML = '

Select a conflict from the list to see details, or adjust filters.

'; currentSelectedConflictId = null; // Also remove highlight from list document.querySelectorAll('#wctsConflictsList li').forEach(item => item.classList.remove('wcts-selected')); } // --- Render Timeline Visualization --- function renderTimeline(conflicts, viewStartYear, viewEndYear) { timelineBarContainerEl.innerHTML = ''; const viewDuration = viewEndYear - viewStartYear; if (viewDuration < 0 || conflicts.length === 0) { // Allow viewDuration === 0 for single year view timelineStartLabelEl.textContent = (viewDuration < 0) ? '' : formatYear(viewStartYear); timelineEndLabelEl.textContent = (viewDuration < 0) ? '' : formatYear(viewEndYear); let message = '

Timeline will appear here when conflicts are displayed for a valid time range.

'; if (viewDuration === 0 && conflicts.length > 0) { message = `

Displaying conflicts active in ${formatYear(viewStartYear)}.

`; } else if (viewDuration < 0) { message = '

Invalid time range for timeline.

'; } timelineBarContainerEl.innerHTML = message; timelineBarContainerEl.style.height = '30px'; return; } timelineStartLabelEl.textContent = formatYear(viewStartYear); timelineEndLabelEl.textContent = formatYear(viewEndYear); let yOffset = 0; const barHeight = 20; const barMargin = 5; const minVisualBarWidthPercentage = 0.5; // Minimum 0.5% width for visibility conflicts.forEach(conflict => { const conflictStartInView = Math.max(conflict.startYear, viewStartYear); const conflictEndInView = Math.min(conflict.endYear, viewEndYear); let durationInView = conflictEndInView - conflictStartInView; // For single-year conflicts or conflicts that are points in time within a single year view if (conflict.startYear === conflict.endYear || durationInView < 0) { // durationInView < 0 could happen if startYear = endYear and it's clamped. durationInView = 0; // Treat as a point in time or very short event } let leftPercentage; let proportionalWidthPercentage; if (viewDuration === 0) { // Handling single year view leftPercentage = 0; // All events start at the beginning of the single year block // If event is point-like (start=end) or fully contains the year, make it full width for single year view if (conflict.startYear <= viewStartYear && conflict.endYear >= viewEndYear) { proportionalWidthPercentage = 100; } else { // Otherwise, it's a point, give it a small marker width proportionalWidthPercentage = minVisualBarWidthPercentage * 2; // Make point events slightly wider } } else { leftPercentage = ((conflictStartInView - viewStartYear) / viewDuration) * 100; proportionalWidthPercentage = ((durationInView + (conflict.startYear === conflict.endYear ? 0 : 1)) / viewDuration) * 100; // Add 1 to duration for non-point events to ensure even a single year conflict has some width // If conflict.startYear === conflict.endYear, it's a point, durationInView might be 0, so proportionalWidth will be 0. if (conflict.startYear === conflict.endYear) { // Explicitly make point events minimally visible proportionalWidthPercentage = (1 / viewDuration) * 100; // represent as 1 unit of time wide } } let displayWidthPercentage = Math.max(minVisualBarWidthPercentage, proportionalWidthPercentage); displayWidthPercentage = Math.min(100, displayWidthPercentage); let actualLeftPercentage = Math.max(0, leftPercentage); if (actualLeftPercentage + displayWidthPercentage > 100) { actualLeftPercentage = 100 - displayWidthPercentage; } actualLeftPercentage = Math.max(0, actualLeftPercentage); // Final check const bar = document.createElement('div'); bar.className = 'wcts-conflict-bar'; bar.style.left = `${actualLeftPercentage}%`; bar.style.width = `${displayWidthPercentage}%`; bar.style.top = `${yOffset}px`; bar.textContent = conflict.name; if (displayWidthPercentage > proportionalWidthPercentage && proportionalWidthPercentage < minVisualBarWidthPercentage) { bar.classList.add('wcts-min-width-applied'); bar.title = `${conflict.name} (${formatYear(conflict.startYear)} - ${formatYear(conflict.endYear)}) - Visual width enhanced for visibility`; } else { bar.title = `${conflict.name} (${formatYear(conflict.startYear)} - ${formatYear(conflict.endYear)})`; } bar.dataset.conflictId = conflict.id; bar.addEventListener('click', () => { displayConflictDetails(conflict.id); document.querySelectorAll('#wctsConflictsList li').forEach(item => item.classList.remove('wcts-selected')); document.querySelector(`#wctsConflictsList li[data-conflict-id="${conflict.id}"]`)?.classList.add('wcts-selected'); currentSelectedConflictId = conflict.id; }); timelineBarContainerEl.appendChild(bar); yOffset += barHeight + barMargin; }); timelineBarContainerEl.style.height = `${Math.max(25, yOffset)}px`; } // --- PDF Download --- downloadPdfBtn.addEventListener('click', function() { if (currentlyDisplayedConflicts.length === 0 && conflictsListUl.querySelector('.wcts-no-results')) { // Check if the "no results" message is literally the only thing there const noResultsLi = conflictsListUl.querySelector('.wcts-no-results'); if (noResultsLi && conflictsListUl.children.length === 1 && conflictsListUl.firstChild === noResultsLi) { alert("No conflicts to download. Please filter first."); return; } } if (currentlyDisplayedConflicts.length === 0 && !conflictsListUl.hasChildNodes()){ alert("No conflicts to download. Please filter first."); return; } const startYearVal = parseInt(startYearEl.value); // Use the actual value from input for report const endYearVal = parseInt(endYearEl.value); const selectedRegionVal = regionFilterEl.value; let filtersText = `Time Period: ${formatYear(startYearVal)} to ${formatYear(endYearVal)}. `; filtersText += `Region: ${selectedRegionVal}.`; let pdfHtmlContent = ` Wars & Conflicts Report

Wars & Conflicts Report

Note: To save this report as a PDF, please use your browser's "Print" option (usually Ctrl+P or Cmd+P) and select "Save as PDF" or "Microsoft Print to PDF" as the printer/destination.

Report generated for filters: ${filtersText}

`; if (currentlyDisplayedConflicts.length === 0) { pdfHtmlContent += '

No conflicts matched the selected filters for this report.

'; } else { currentlyDisplayedConflicts.forEach(conflict => { pdfHtmlContent += `

${conflict.name}

Period: ${formatYear(conflict.startYear)} – ${formatYear(conflict.endYear)}

Region(s): ${conflict.regions.join(', ')}

Key Belligerents: ${formatBelligerents(conflict.belligerents)}

Summary: ${conflict.summary}

`; }); } pdfHtmlContent += ``; const pdfWindow = window.open('', '_blank'); if (pdfWindow) { pdfWindow.document.open(); pdfWindow.document.write(pdfHtmlContent); pdfWindow.document.close(); } else { alert("Failed to open printable report window. Please check your browser's pop-up blocker settings."); } }); // --- Event Listeners --- showConflictsBtn.addEventListener('click', displayConflicts); // --- Initial Setup --- populateRegionFilter(); displayConflicts(); });
Scroll to Top