Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>World Military & Trade Dashboard</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.country:hover { | |
stroke: #000; | |
stroke-width: 1.5px; | |
} | |
.tooltip { | |
position: absolute; | |
padding: 10px; | |
background: rgba(0, 0, 0, 0.8); | |
color: #fff; | |
border-radius: 5px; | |
pointer-events: none; | |
font-size: 14px; | |
max-width: 300px; | |
z-index: 100; | |
} | |
.legend { | |
font-size: 12px; | |
} | |
.flag-emoji { | |
font-size: 24px; | |
margin-right: 5px; | |
} | |
.map-container { | |
position: relative; | |
} | |
.loading { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
font-size: 24px; | |
color: #555; | |
} | |
.country-card { | |
transition: all 0.3s ease; | |
} | |
.country-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 10px 20px rgba(0,0,0,0.1); | |
} | |
.progress-bar { | |
height: 8px; | |
border-radius: 4px; | |
background: #e0e0e0; | |
overflow: hidden; | |
} | |
.progress-fill { | |
height: 100%; | |
border-radius: 4px; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100"> | |
<div class="container mx-auto px-4 py-8"> | |
<header class="mb-8 text-center"> | |
<h1 class="text-4xl font-bold text-gray-800 mb-2">Global Military & Trade Dashboard</h1> | |
<p class="text-lg text-gray-600">Interactive visualization of military spending, trade relations with USA, and armed forces size</p> | |
</header> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"> | |
<div class="bg-white p-6 rounded-lg shadow-md"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">Key Metrics</h2> | |
<div class="space-y-4"> | |
<div> | |
<p class="text-sm text-gray-500">Total Military Spending (Global)</p> | |
<p class="text-2xl font-bold text-blue-600">$2.24 Trillion</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Largest Military (Personnel)</p> | |
<p class="text-xl font-bold flex items-center"> | |
<span class="flag-emoji">🇨🇳</span> | |
<span>China: 2.18M</span> | |
</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Highest % GDP on Military</p> | |
<p class="text-xl font-bold flex items-center"> | |
<span class="flag-emoji">🇸🇦</span> | |
<span>Saudi Arabia: 8.4%</span> | |
</p> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white p-6 rounded-lg shadow-md"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">USA Trade Relations</h2> | |
<div class="space-y-4"> | |
<div> | |
<p class="text-sm text-gray-500">Largest Trade Surplus</p> | |
<p class="text-xl font-bold flex items-center"> | |
<span class="flag-emoji">🇳🇱</span> | |
<span>Netherlands: +$22B</span> | |
</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Largest Trade Deficit</p> | |
<p class="text-xl font-bold flex items-center"> | |
<span class="flag-emoji">🇨🇳</span> | |
<span>China: -$382B</span> | |
</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Total US Trade Deficit</p> | |
<p class="text-2xl font-bold text-red-600">$1.18 Trillion</p> | |
</div> | |
</div> | |
</div> | |
<div class="bg-white p-6 rounded-lg shadow-md"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">Data Filters</h2> | |
<div class="space-y-4"> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Display Mode</label> | |
<select id="display-mode" class="w-full p-2 border rounded-md"> | |
<option value="military_spending">Military Spending (% GDP)</option> | |
<option value="trade_deficit">Trade Deficit with USA</option> | |
<option value="military_size">Military Personnel</option> | |
</select> | |
</div> | |
<div> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Region Focus</label> | |
<select id="region-filter" class="w-full p-2 border rounded-md"> | |
<option value="world">World</option> | |
<option value="asia">Asia</option> | |
<option value="europe">Europe</option> | |
<option value="africa">Africa</option> | |
<option value="americas">Americas</option> | |
</select> | |
</div> | |
<button id="reset-btn" class="w-full bg-gray-200 hover:bg-gray-300 text-gray-800 py-2 px-4 rounded-md transition"> | |
Reset View | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="map-container bg-white p-6 rounded-lg shadow-md mb-8"> | |
<div class="loading" id="loading">Loading world map...</div> | |
<div id="map" style="width: 100%; height: 600px;"></div> | |
<div id="legend" class="mt-4 text-center"></div> | |
</div> | |
<div class="bg-white p-6 rounded-lg shadow-md mb-8"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">Country Details</h2> | |
<div id="country-details" class="grid grid-cols-1 gap-4"> | |
<!-- Detailed country information will be inserted here when a country is clicked --> | |
<div class="text-center text-gray-500 py-10"> | |
<i class="fas fa-globe-americas text-4xl mb-4 text-gray-300"></i> | |
<p>Click on any country to view detailed information</p> | |
</div> | |
</div> | |
</div> | |
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8"> | |
<div class="bg-white p-6 rounded-lg shadow-md"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">Top Military Spenders (% GDP)</h2> | |
<canvas id="militarySpendingChart" height="300"></canvas> | |
</div> | |
<div class="bg-white p-6 rounded-lg shadow-md"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">Largest Trade Deficits with USA</h2> | |
<canvas id="tradeDeficitChart" height="300"></canvas> | |
</div> | |
</div> | |
<footer class="text-center text-gray-600 text-sm mt-8"> | |
<p>Data sources: World Bank, SIPRI, CIA World Factbook, US Census Bureau (2023 estimates)</p> | |
<p class="mt-2">© 2023 Global Military & Trade Dashboard | Created with D3.js and TailwindCSS</p> | |
</footer> | |
</div> | |
<div id="tooltip" class="tooltip"></div> | |
<script> | |
// Sample data (in a real app, this would come from an API) | |
const countryData = { | |
"USA": { | |
name: "United States", | |
flag: "🇺🇸", | |
militarySpending: 3.5, | |
militarySize: 1395000, | |
tradeDeficit: 0, | |
gdp: 25439.70, | |
region: "americas", | |
population: 331900000, | |
militaryBudget: 877000, | |
exportsToUSA: 0, | |
importsFromUSA: 0, | |
allies: ["GBR", "CAN", "AUS", "JPN", "KOR"], | |
conflicts: ["RUS", "CHN"], | |
description: "The United States has the world's largest military budget and is a global superpower with military bases in over 70 countries." | |
}, | |
"CHN": { | |
name: "China", | |
flag: "🇨🇳", | |
militarySpending: 1.7, | |
militarySize: 2180000, | |
tradeDeficit: -382000, | |
gdp: 17963.17, | |
region: "asia", | |
population: 1412000000, | |
militaryBudget: 292000, | |
exportsToUSA: 563000, | |
importsFromUSA: 181000, | |
allies: ["RUS", "PAK"], | |
conflicts: ["USA", "IND"], | |
description: "China has the world's largest standing army and has been rapidly modernizing its military capabilities in recent decades." | |
}, | |
"RUS": { | |
name: "Russia", | |
flag: "🇷🇺", | |
militarySpending: 4.1, | |
militarySize: 1014000, | |
tradeDeficit: -12000, | |
gdp: 1835.91, | |
region: "europe", | |
population: 143400000, | |
militaryBudget: 86100, | |
exportsToUSA: 29000, | |
importsFromUSA: 17000, | |
allies: ["CHN", "IND"], | |
conflicts: ["USA", "UKR"], | |
description: "Russia possesses the world's largest nuclear arsenal and has been involved in several regional conflicts in recent years." | |
}, | |
"IND": { | |
name: "India", | |
flag: "🇮🇳", | |
militarySpending: 2.5, | |
militarySize: 1455000, | |
tradeDeficit: -32000, | |
gdp: 3173.40, | |
region: "asia", | |
population: 1380000000, | |
militaryBudget: 76600, | |
exportsToUSA: 78000, | |
importsFromUSA: 46000, | |
allies: ["USA", "RUS"], | |
conflicts: ["PAK", "CHN"], | |
description: "India has the world's second-largest standing army and is a nuclear power with ongoing border disputes with neighbors." | |
}, | |
"GBR": { | |
name: "United Kingdom", | |
flag: "🇬🇧", | |
militarySpending: 2.3, | |
militarySize: 153500, | |
tradeDeficit: -9000, | |
gdp: 3070.67, | |
region: "europe", | |
population: 67200000, | |
militaryBudget: 71500, | |
exportsToUSA: 62000, | |
importsFromUSA: 53000, | |
allies: ["USA", "CAN", "AUS"], | |
conflicts: [], | |
description: "The UK maintains a technologically advanced military with global power projection capabilities and is a permanent member of the UN Security Council." | |
}, | |
"FRA": { | |
name: "France", | |
flag: "🇫🇷", | |
militarySpending: 2.0, | |
militarySize: 208700, | |
tradeDeficit: -15000, | |
gdp: 2778.09, | |
region: "europe", | |
population: 67400000, | |
militaryBudget: 58600, | |
exportsToUSA: 52000, | |
importsFromUSA: 37000, | |
allies: ["USA", "DEU"], | |
conflicts: [], | |
description: "France has the largest military in the EU and maintains nuclear capabilities, with military bases in Africa and the Middle East." | |
}, | |
"DEU": { | |
name: "Germany", | |
flag: "🇩🇪", | |
militarySpending: 1.4, | |
militarySize: 183500, | |
tradeDeficit: -68000, | |
gdp: 4082.47, | |
region: "europe", | |
population: 83200000, | |
militaryBudget: 56000, | |
exportsToUSA: 142000, | |
importsFromUSA: 74000, | |
allies: ["USA", "FRA"], | |
conflicts: [], | |
description: "Germany has one of Europe's most technologically advanced militaries but has traditionally kept defense spending low due to historical reasons." | |
}, | |
"JPN": { | |
name: "Japan", | |
flag: "🇯🇵", | |
militarySpending: 1.1, | |
militarySize: 247000, | |
tradeDeficit: -72000, | |
gdp: 4231.14, | |
region: "asia", | |
population: 125000000, | |
militaryBudget: 54100, | |
exportsToUSA: 143000, | |
importsFromUSA: 71000, | |
allies: ["USA"], | |
conflicts: ["CHN"], | |
description: "Japan's military (officially called the Self-Defense Forces) is constrained by its pacifist constitution but remains technologically advanced." | |
}, | |
"SAU": { | |
name: "Saudi Arabia", | |
flag: "🇸🇦", | |
militarySpending: 8.4, | |
militarySize: 257000, | |
tradeDeficit: -5000, | |
gdp: 833.54, | |
region: "asia", | |
population: 35800000, | |
militaryBudget: 69500, | |
exportsToUSA: 28000, | |
importsFromUSA: 23000, | |
allies: ["USA"], | |
conflicts: ["IRN"], | |
description: "Saudi Arabia spends the highest percentage of GDP on military in the world and is a major purchaser of US and European weapons systems." | |
}, | |
"ISR": { | |
name: "Israel", | |
flag: "🇮🇱", | |
militarySpending: 5.2, | |
militarySize: 173000, | |
tradeDeficit: -11000, | |
gdp: 488.51, | |
region: "asia", | |
population: 9260000, | |
militaryBudget: 24300, | |
exportsToUSA: 23000, | |
importsFromUSA: 12000, | |
allies: ["USA"], | |
conflicts: ["PSE", "LBN", "SYR"], | |
description: "Israel maintains a technologically advanced military with compulsory conscription and is widely believed to possess nuclear weapons." | |
}, | |
"BRA": { | |
name: "Brazil", | |
flag: "🇧🇷", | |
militarySpending: 1.4, | |
militarySize: 366500, | |
tradeDeficit: -30000, | |
gdp: 1920.10, | |
region: "americas", | |
population: 213000000, | |
militaryBudget: 27200, | |
exportsToUSA: 31000, | |
importsFromUSA: 61000, | |
allies: ["USA"], | |
conflicts: [], | |
description: "Brazil has the largest military in Latin America and focuses primarily on border security and peacekeeping operations." | |
}, | |
"ZAF": { | |
name: "South Africa", | |
flag: "🇿🇦", | |
militarySpending: 0.9, | |
militarySize: 73000, | |
tradeDeficit: -2000, | |
gdp: 405.71, | |
region: "africa", | |
population: 59300000, | |
militaryBudget: 3700, | |
exportsToUSA: 9000, | |
importsFromUSA: 7000, | |
allies: [], | |
conflicts: [], | |
description: "South Africa has a relatively small but well-equipped military compared to other African nations." | |
}, | |
"NGA": { | |
name: "Nigeria", | |
flag: "🇳🇬", | |
militarySpending: 0.6, | |
militarySize: 223000, | |
tradeDeficit: -5000, | |
gdp: 477.39, | |
region: "africa", | |
population: 206000000, | |
militaryBudget: 2900, | |
exportsToUSA: 5000, | |
importsFromUSA: 10000, | |
allies: [], | |
conflicts: ["Boko Haram"], | |
description: "Nigeria has Africa's largest economy but spends relatively little on defense, focusing primarily on internal security threats." | |
}, | |
"AUS": { | |
name: "Australia", | |
flag: "🇦🇺", | |
militarySpending: 2.1, | |
militarySize: 90000, | |
tradeDeficit: -12000, | |
gdp: 1675.42, | |
region: "asia", | |
population: 25700000, | |
militaryBudget: 32700, | |
exportsToUSA: 11000, | |
importsFromUSA: 23000, | |
allies: ["USA", "GBR"], | |
conflicts: [], | |
description: "Australia maintains a technologically advanced military focused on regional security and is a key US ally in the Pacific." | |
}, | |
"CAN": { | |
name: "Canada", | |
flag: "🇨🇦", | |
militarySpending: 1.4, | |
militarySize: 70000, | |
tradeDeficit: -82000, | |
gdp: 1990.76, | |
region: "americas", | |
population: 38200000, | |
militaryBudget: 28600, | |
exportsToUSA: 355000, | |
importsFromUSA: 437000, | |
allies: ["USA", "GBR"], | |
conflicts: [], | |
description: "Canada's military is relatively small but well-equipped, with close defense ties to the United States through NORAD." | |
}, | |
"MEX": { | |
name: "Mexico", | |
flag: "🇲🇽", | |
militarySpending: 0.7, | |
militarySize: 280000, | |
tradeDeficit: -130000, | |
gdp: 1414.19, | |
region: "americas", | |
population: 126000000, | |
militaryBudget: 9900, | |
exportsToUSA: 435000, | |
importsFromUSA: 565000, | |
allies: ["USA"], | |
conflicts: ["Drug Cartels"], | |
description: "Mexico's military focuses primarily on internal security and drug cartel operations, with limited power projection capabilities." | |
}, | |
"KOR": { | |
name: "South Korea", | |
flag: "🇰🇷", | |
militarySpending: 2.8, | |
militarySize: 600000, | |
tradeDeficit: -23000, | |
gdp: 1675.42, | |
region: "asia", | |
population: 51700000, | |
militaryBudget: 46900, | |
exportsToUSA: 110000, | |
importsFromUSA: 87000, | |
allies: ["USA"], | |
conflicts: ["PRK"], | |
description: "South Korea maintains a large standing army due to tensions with North Korea and benefits from close military cooperation with the US." | |
}, | |
"PAK": { | |
name: "Pakistan", | |
flag: "🇵🇰", | |
militarySpending: 4.0, | |
militarySize: 654000, | |
tradeDeficit: -3000, | |
gdp: 376.53, | |
region: "asia", | |
population: 225000000, | |
militaryBudget: 15000, | |
exportsToUSA: 5000, | |
importsFromUSA: 2000, | |
allies: ["CHN"], | |
conflicts: ["IND"], | |
description: "Pakistan is a nuclear-armed state with a large military that has historically focused on its rivalry with India." | |
}, | |
"TUR": { | |
name: "Turkey", | |
flag: "🇹🇷", | |
militarySpending: 2.1, | |
militarySize: 425000, | |
tradeDeficit: -8000, | |
gdp: 905.99, | |
region: "asia", | |
population: 84700000, | |
militaryBudget: 19000, | |
exportsToUSA: 9000, | |
importsFromUSA: 17000, | |
allies: [], | |
conflicts: ["SYR"], | |
description: "Turkey has NATO's second-largest standing army and plays a strategic role in the Middle East and Eastern Europe." | |
}, | |
"ITA": { | |
name: "Italy", | |
flag: "🇮🇹", | |
militarySpending: 1.5, | |
militarySize: 175000, | |
tradeDeficit: -28000, | |
gdp: 2010.43, | |
region: "europe", | |
population: 59500000, | |
militaryBudget: 30200, | |
exportsToUSA: 58000, | |
importsFromUSA: 30000, | |
allies: ["USA", "DEU"], | |
conflicts: [], | |
description: "Italy maintains a modern military with significant naval capabilities and participates in numerous NATO and EU missions." | |
} | |
}; | |
// Initialize charts | |
function initCharts() { | |
// Military Spending Chart | |
const militaryCtx = document.getElementById('militarySpendingChart').getContext('2d'); | |
const militaryChart = new Chart(militaryCtx, { | |
type: 'bar', | |
data: { | |
labels: Object.values(countryData) | |
.sort((a, b) => b.militarySpending - a.militarySpending) | |
.slice(0, 10) | |
.map(c => `${c.flag} ${c.name}`), | |
datasets: [{ | |
label: 'Military Spending (% of GDP)', | |
data: Object.values(countryData) | |
.sort((a, b) => b.militarySpending - a.militarySpending) | |
.slice(0, 10) | |
.map(c => c.militarySpending), | |
backgroundColor: 'rgba(54, 162, 235, 0.7)', | |
borderColor: 'rgba(54, 162, 235, 1)', | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
responsive: true, | |
scales: { | |
y: { | |
beginAtZero: true, | |
title: { | |
display: true, | |
text: '% of GDP' | |
} | |
} | |
} | |
} | |
}); | |
// Trade Deficit Chart | |
const tradeCtx = document.getElementById('tradeDeficitChart').getContext('2d'); | |
const tradeChart = new Chart(tradeCtx, { | |
type: 'bar', | |
data: { | |
labels: Object.values(countryData) | |
.sort((a, b) => a.tradeDeficit - b.tradeDeficit) | |
.slice(0, 10) | |
.map(c => `${c.flag} ${c.name}`), | |
datasets: [{ | |
label: 'Trade Deficit with USA (Millions USD)', | |
data: Object.values(countryData) | |
.sort((a, b) => a.tradeDeficit - b.tradeDeficit) | |
.slice(0, 10) | |
.map(c => c.tradeDeficit / 1000), | |
backgroundColor: 'rgba(255, 99, 132, 0.7)', | |
borderColor: 'rgba(255, 99, 132, 1)', | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
responsive: true, | |
scales: { | |
y: { | |
title: { | |
display: true, | |
text: 'Billions USD' | |
} | |
} | |
} | |
} | |
}); | |
} | |
// Initialize map | |
async function initMap() { | |
const width = document.getElementById('map').clientWidth; | |
const height = 600; | |
// Remove loading indicator | |
document.getElementById('loading').style.display = 'none'; | |
// Create SVG | |
const svg = d3.select("#map") | |
.append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
// Create projection | |
const projection = d3.geoMercator() | |
.scale(130) | |
.center([0, 20]) | |
.translate([width / 2, height / 2]); | |
const path = d3.geoPath().projection(projection); | |
// Load world map data | |
const world = await d3.json("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"); | |
// Create countries | |
const countries = topojson.feature(world, world.objects.countries).features; | |
// Color scales | |
const militaryColor = d3.scaleQuantize() | |
.domain([0, 10]) | |
.range(d3.schemeBlues[7]); | |
const tradeColor = d3.scaleDiverging() | |
.domain([-400000, 0, 400000]) | |
.interpolator(d3.interpolateRdBu); | |
const sizeColor = d3.scaleQuantize() | |
.domain([0, 2500000]) | |
.range(d3.schemeOranges[7]); | |
// Draw countries | |
svg.selectAll(".country") | |
.data(countries) | |
.enter() | |
.append("path") | |
.attr("class", "country") | |
.attr("d", path) | |
.attr("fill", d => { | |
const country = countryData[d.id]; | |
if (country) { | |
return militaryColor(country.militarySpending); | |
} | |
return "#ccc"; | |
}) | |
.on("mouseover", function(event, d) { | |
const country = countryData[d.id]; | |
if (country) { | |
const tooltip = d3.select("#tooltip"); | |
tooltip.transition().duration(200).style("opacity", 0.9); | |
tooltip.html(` | |
<div class="font-bold text-lg mb-2">${country.flag} ${country.name}</div> | |
<div class="grid grid-cols-2 gap-2"> | |
<div> | |
<span class="font-semibold">Military Spending:</span> ${country.militarySpending}% of GDP | |
</div> | |
<div> | |
<span class="font-semibold">Military Size:</span> ${country.militarySize.toLocaleString()} | |
</div> | |
<div> | |
<span class="font-semibold">Trade Deficit with USA:</span> $${Math.abs(country.tradeDeficit).toLocaleString()}M | |
</div> | |
<div> | |
<span class="font-semibold">GDP:</span> $${country.gdp.toLocaleString()}B | |
</div> | |
</div> | |
`) | |
.style("left", (event.pageX + 10) + "px") | |
.style("top", (event.pageY - 28) + "px"); | |
d3.select(this).style("stroke", "#000").style("stroke-width", 2); | |
} | |
}) | |
.on("mouseout", function() { | |
d3.select("#tooltip").transition().duration(500).style("opacity", 0); | |
d3.select(this).style("stroke", "#000").style("stroke-width", 0.5); | |
}) | |
.on("click", function(event, d) { | |
const country = countryData[d.id]; | |
if (country) { | |
showCountryDetails(country); | |
} | |
}); | |
// Add legend | |
const legend = d3.select("#legend") | |
.append("svg") | |
.attr("width", width) | |
.attr("height", 50); | |
const legendMilitary = legend.append("g") | |
.attr("transform", "translate(20, 20)"); | |
const legendScale = d3.scaleLinear() | |
.domain([0, 10]) | |
.range([0, 200]); | |
const legendAxis = d3.axisBottom(legendScale) | |
.ticks(5) | |
.tickFormat(d => d + "%"); | |
legendMilitary.append("g") | |
.attr("class", "axis") | |
.attr("transform", "translate(0, 20)") | |
.call(legendAxis); | |
const defs = legend.append("defs"); | |
const linearGradient = defs.append("linearGradient") | |
.attr("id", "linear-gradient"); | |
linearGradient.selectAll("stop") | |
.data(d3.schemeBlues[7].map((color, i) => ({offset: i*100/6, color}))) | |
.enter().append("stop") | |
.attr("offset", d => d.offset + "%") | |
.attr("stop-color", d => d.color); | |
legendMilitary.append("rect") | |
.attr("width", 200) | |
.attr("height", 10) | |
.style("fill", "url(#linear-gradient)") | |
.attr("transform", "translate(0, 10)"); | |
legendMilitary.append("text") | |
.attr("x", 100) | |
.attr("y", 0) | |
.attr("text-anchor", "middle") | |
.text("Military Spending (% of GDP)"); | |
// Add country flags (simplified for demo) | |
countries.forEach(d => { | |
const country = countryData[d.id]; | |
if (country) { | |
const centroid = path.centroid(d); | |
if (centroid[0] && centroid[1]) { | |
svg.append("text") | |
.attr("x", centroid[0]) | |
.attr("y", centroid[1]) | |
.attr("text-anchor", "middle") | |
.attr("dy", ".35em") | |
.text(country.flag) | |
.attr("class", "flag-emoji") | |
.style("font-size", "16px") | |
.style("pointer-events", "none"); | |
} | |
} | |
}); | |
// Update display based on dropdown | |
document.getElementById('display-mode').addEventListener('change', function() { | |
const mode = this.value; | |
svg.selectAll(".country") | |
.attr("fill", d => { | |
const country = countryData[d.id]; | |
if (country) { | |
if (mode === "military_spending") { | |
return militaryColor(country.militarySpending); | |
} else if (mode === "trade_deficit") { | |
return tradeColor(country.tradeDeficit); | |
} else if (mode === "military_size") { | |
return sizeColor(country.militarySize); | |
} | |
} | |
return "#ccc"; | |
}); | |
// Update legend | |
if (mode === "military_spending") { | |
legendMilitary.select("text").text("Military Spending (% of GDP)"); | |
legendMilitary.select("rect").style("fill", "url(#linear-gradient)"); | |
} else if (mode === "trade_deficit") { | |
legendMilitary.select("text").text("Trade Deficit with USA (Millions USD)"); | |
legendMilitary.select("rect").style("fill", "none"); | |
} else if (mode === "military_size") { | |
legendMilitary.select("text").text("Military Personnel"); | |
legendMilitary.select("rect").style("fill", "url(#linear-gradient)"); | |
} | |
}); | |
// Region filter | |
document.getElementById('region-filter').addEventListener('change', function() { | |
const region = this.value; | |
if (region === "world") { | |
projection.scale(130).center([0, 20]); | |
} else if (region === "asia") { | |
projection.scale(300).center([100, 30]); | |
} else if (region === "europe") { | |
projection.scale(300).center([15, 50]); | |
} else if (region === "africa") { | |
projection.scale(250).center([20, 0]); | |
} else if (region === "americas") { | |
projection.scale(200).center([-80, 20]); | |
} | |
svg.selectAll(".country").attr("d", path); | |
}); | |
// Reset button | |
document.getElementById('reset-btn').addEventListener('click', function() { | |
projection.scale(130).center([0, 20]); | |
svg.selectAll(".country").attr("d", path); | |
document.getElementById('region-filter').value = "world"; | |
document.getElementById('display-mode').value = "military_spending"; | |
svg.selectAll(".country").attr("fill", d => { | |
const country = countryData[d.id]; | |
if (country) { | |
return militaryColor(country.militarySpending); | |
} | |
return "#ccc"; | |
}); | |
legendMilitary.select("text").text("Military Spending (% of GDP)"); | |
legendMilitary.select("rect").style("fill", "url(#linear-gradient)"); | |
}); | |
} | |
// Show detailed country information | |
function showCountryDetails(country) { | |
const detailsContainer = document.getElementById('country-details'); | |
// Format allies and conflicts | |
const formatAllies = country.allies.map(code => { | |
const ally = Object.values(countryData).find(c => c.flag === countryData[code].flag); | |
return ally ? `${ally.flag} ${ally.name}` : ''; | |
}).filter(a => a).join(', '); | |
const formatConflicts = country.conflicts.map(code => { | |
const conflict = Object.values(countryData).find(c => c.flag === countryData[code].flag); | |
return conflict ? `${conflict.flag} ${conflict.name}` : code; | |
}).join(', '); | |
// Calculate military spending per capita | |
const spendingPerCapita = (country.militaryBudget * 1000000) / country.population; | |
detailsContainer.innerHTML = ` | |
<div class="country-card bg-white p-6 rounded-lg shadow-lg border border-gray-200"> | |
<div class="flex flex-col md:flex-row gap-6"> | |
<div class="flex-1"> | |
<div class="flex items-center mb-6"> | |
<span class="flag-emoji text-5xl">${country.flag}</span> | |
<h3 class="text-3xl font-bold ml-4">${country.name}</h3> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6"> | |
<div class="bg-blue-50 p-4 rounded-lg"> | |
<h4 class="font-semibold text-blue-800 mb-2">Military Overview</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span>Spending (% GDP):</span> | |
<span class="font-semibold">${country.militarySpending}%</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Budget:</span> | |
<span class="font-semibold">$${(country.militaryBudget / 1000).toLocaleString()}B</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Personnel:</span> | |
<span class="font-semibold">${(country.militarySize / 1000).toLocaleString()}K</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Per Capita:</span> | |
<span class="font-semibold">$${spendingPerCapita.toFixed(2)}</span> | |
</div> | |
</div> | |
</div> | |
<div class="bg-green-50 p-4 rounded-lg"> | |
<h4 class="font-semibold text-green-800 mb-2">Economic Overview</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span>GDP:</span> | |
<span class="font-semibold">$${country.gdp.toLocaleString()}B</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Population:</span> | |
<span class="font-semibold">${(country.population / 1000000).toLocaleString()}M</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>GDP Per Capita:</span> | |
<span class="font-semibold">$${Math.round(country.gdp * 1000000000 / country.population)}</span> | |
</div> | |
</div> | |
</div> | |
<div class="bg-purple-50 p-4 rounded-lg"> | |
<h4 class="font-semibold text-purple-800 mb-2">Trade with USA</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span>Total Trade:</span> | |
<span class="font-semibold">$${(Math.abs(country.tradeDeficit) + (country.exportsToUSA + country.importsFromUSA)).toLocaleString()}M</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Exports to USA:</span> | |
<span class="font-semibold">$${country.exportsToUSA.toLocaleString()}M</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Imports from USA:</span> | |
<span class="font-semibold">$${country.importsFromUSA.toLocaleString()}M</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Balance:</span> | |
<span class="font-semibold ${country.tradeDeficit < 0 ? 'text-red-600' : 'text-green-600'}"> | |
$${Math.abs(country.tradeDeficit).toLocaleString()}M ${country.tradeDeficit < 0 ? 'Deficit' : 'Surplus'} | |
</span> | |
</div> | |
</div> | |
</div> | |
<div class="bg-yellow-50 p-4 rounded-lg"> | |
<h4 class="font-semibold text-yellow-800 mb-2">Relationships</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span>Allies:</span> | |
<span class="font-semibold">${formatAllies || 'None'}</span> | |
</div> | |
<div class="flex justify-between"> | |
<span>Conflicts:</span> | |
<span class="font-semibold">${formatConflicts || 'None'}</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-6"> | |
<h4 class="font-semibold text-gray-800 mb-2">Military Spending Comparison</h4> | |
<div class="space-y-2"> | |
<div> | |
<div class="flex justify-between mb-1"> | |
<span>Global Average (2.2%)</span> | |
<span>${country.militarySpending}%</span> | |
</div> | |
<div class="progress-bar"> | |
<div class="progress-fill bg-blue-500" style="width: ${(country.militarySpending / 10) * 100}%"></div> | |
</div> | |
</div> | |
<div> | |
<div class="flex justify-between mb-1"> | |
<span>NATO Target (2.0%)</span> | |
<span>${country.militarySpending}%</span> | |
</div> | |
<div class="progress-bar"> | |
<div class="progress-fill bg-blue-500" style="width: ${(country.militarySpending / 10) * 100}%"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="flex-1"> | |
<div class="bg-gray-50 p-4 rounded-lg h-full"> | |
<h4 class="font-semibold text-gray-800 mb-4">Country Description</h4> | |
<p class="text-gray-700 mb-6">${country.description}</p> | |
<h4 class="font-semibold text-gray-800 mb-4">Key Statistics</h4> | |
<div class="grid grid-cols-2 gap-4"> | |
<div class="bg-white p-3 rounded-lg shadow-sm text-center"> | |
<div class="text-2xl font-bold text-blue-600">${country.militarySpending}%</div> | |
<div class="text-sm text-gray-600">of GDP on military</div> | |
</div> | |
<div class="bg-white p-3 rounded-lg shadow-sm text-center"> | |
<div class="text-2xl font-bold text-blue-600">${(country.militarySize / 1000).toLocaleString()}K</div> | |
<div class="text-sm text-gray-600">active personnel</div> | |
</div> | |
<div class="bg-white p-3 rounded-lg shadow-sm text-center"> | |
<div class="text-2xl font-bold ${country.tradeDeficit < 0 ? 'text-red-600' : 'text-green-600'}"> | |
$${Math.abs(country.tradeDeficit).toLocaleString()}M | |
</div> | |
<div class="text-sm text-gray-600">trade ${country.tradeDeficit < 0 ? 'deficit' : 'surplus'} with USA</div> | |
</div> | |
<div class="bg-white p-3 rounded-lg shadow-sm text-center"> | |
<div class="text-2xl font-bold text-blue-600">$${(country.gdp / 1000).toLocaleString()}T</div> | |
<div class="text-sm text-gray-600">GDP</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
`; | |
} | |
// Initialize everything | |
document.addEventListener('DOMContentLoaded', function() { | |
initCharts(); | |
initMap(); | |
}); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=silverkiwi/liberation-day" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body> | |
</html> |