Every country and territory whose opt-in currencies property includes the US dollar — not just the United States, but Ecuador, El Salvador, Timor-Leste, Panama, Zimbabwe, Cambodia (dollarized or co-circulating), and a string of US and former-Dutch Caribbean/Pacific territories. Zoom and pan to see the small ones; hover any country for its actual currency list.
https://api.mapjson.com/v1/geo?layer=countries&detail=medium&properties=name,currencies
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>USD Currency</title>
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/topojson-client@3/dist/topojson-client.min.js"></script>
<style>
body { margin: 0; background: #cfe0ea; }
svg { width: 100%; height: 100vh; display: block; }
.tooltip {
position: fixed;
background: #1a1a1a;
color: #fafafa;
font-family: monospace;
font-size: 11px;
padding: 6px 10px;
pointer-events: none;
opacity: 0;
transition: opacity 0.1s;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="tooltip" id="tooltip"></div>
<svg id="map"></svg>
<script>
const url = "https://api.mapjson.com/v1/geo?layer=countries&detail=medium&properties=name,currencies";
const usesUSD = (d) => (d.properties.currencies || []).some((c) => c.code === "USD");
const width = 960, height = 500;
const tooltip = document.getElementById("tooltip");
const svg = d3.select("#map").attr("viewBox", `0 0 ${width} ${height}`);
const g = svg.append("g");
const projection = d3.geoEqualEarth().scale(160).translate([width / 2, height / 2 + 20]);
const path = d3.geoPath(projection);
g.append("path").datum({ type: "Sphere" }).attr("fill", "#22485e").attr("d", path);
g.append("path").datum(d3.geoGraticule()()).attr("fill", "none")
.attr("stroke", "#a9c3d1").attr("stroke-width", 0.3).attr("d", path);
function showTooltip(event, d) {
const currencies = d.properties.currencies;
tooltip.style.left = (event.clientX + 12) + "px";
tooltip.style.top = (event.clientY - 10) + "px";
tooltip.style.opacity = 1;
tooltip.innerHTML =
`<strong>${d.properties.name || d.properties.gid}</strong><br>` +
(currencies?.length ? currencies.map((c) => `${c.name} (${c.code})`).join(", ") : "no currency data");
}
d3.json(url).then(topo => {
const features = topojson.feature(topo, topo.objects.geo).features;
g.selectAll(".bg").data(features.filter((d) => !usesUSD(d))).join("path")
.attr("d", path).attr("fill", "#ddd8cc").attr("stroke", "#f0ece6").attr("stroke-width", 0.5)
.on("mousemove", showTooltip).on("mouseleave", () => tooltip.style.opacity = 0);
g.selectAll(".usd").data(features.filter(usesUSD)).join("path")
.attr("d", path).attr("fill", "#4a8f6b").attr("stroke", "#2f6b4c").attr("stroke-width", 0.8)
.style("cursor", "pointer")
.on("mousemove", showTooltip).on("mouseleave", () => tooltip.style.opacity = 0);
});
</script>
</body>
</html>