← Examples
countries · world · choropleth · Equal Earth

World Cup 2022 — How Far Each Team Went

The 32 nations of the 2022 FIFA World Cup, shaded by how deep they ran. The scale goes light → dark with each round survived: palest for a group-stage exit, darkest for the one team never eliminated — champions Argentina. Each country is joined to its result by ISO2 code; everyone else is left neutral.

API Call

https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,iso2&format=geojson

Note: the map has one feature for the United Kingdom (GB), so it's colored by England's quarter-final run; Wales exited in the group stage.

Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>World Cup 2022 Elimination</title>
  <script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
  <style>
    body { margin: 0; background: #c9d6db; }
    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; line-height: 1.6; }
  </style>
</head>
<body>
  <div id="tooltip"></div>
  <svg id="map"></svg>
  <script>
    // stage 0 (group) → 5 (champion). GB shown as England's run; Wales was group stage.
    const STAGE = {
      QA:0, EC:0, IR:0, MX:0, SA:0, TN:0, DK:0, DE:0, CR:0, BE:0, CA:0, CM:0, RS:0, UY:0, GH:0,
      US:1, AU:1, PL:1, SN:1, JP:1, KR:1, ES:1, CH:1,
      NL:2, BR:2, PT:2, GB:2,
      HR:3, MA:3,
      FR:4,
      AR:5,
    };
    const COLORS = ["#d9f0d3", "#addd8e", "#78c679", "#41ab5d", "#238443", "#00552e"];
    const LABELS = ["Group stage", "Round of 16", "Quarter-finals", "Semi-finals", "Runner-up", "Champion"];
    const OCEAN = "#c9d6db", NEUTRAL = "#e6e1d6", STROKE = "#ffffff";

    const width = 960, height = 500;
    const tooltip = document.getElementById("tooltip");
    const svg = d3.select("#map").attr("viewBox", `0 0 ${width} ${height}`);
    const projection = d3.geoEqualEarth();
    const path = d3.geoPath(projection);

    d3.json("https://api.mapjson.com/v1/geo?layer=countries&filter=world&detail=low&properties=name,iso2&format=geojson")
      .then((geo) => {
        projection.fitExtent([[8, 8], [width - 8, height - 8]], { type: "Sphere" });
        svg.append("g").selectAll("path").data(geo.features).join("path")
          .attr("d", path)
          .attr("fill", (d) => { const s = STAGE[d.properties.iso2]; return s === undefined ? NEUTRAL : COLORS[s]; })
          .attr("stroke", STROKE).attr("stroke-width", 0.5)
          .on("mousemove", function (event, d) {
            const s = STAGE[d.properties.iso2];
            tooltip.style.left = (event.clientX + 12) + "px";
            tooltip.style.top = (event.clientY - 10) + "px";
            tooltip.style.opacity = 1;
            tooltip.innerHTML = `<strong>${d.properties.name}</strong><br>` +
              (s === undefined ? "did not play" : "reached: " + LABELS[s]);
          })
          .on("mouseleave", () => { tooltip.style.opacity = 0; });
      });
  </script>
</body>
</html>