← Examples
countries · low detail · properties · hover · zoom

World Countries

The mapjson.com homepage map. Equal Earth projection with ocean sphere, graticule, hover tooltips, and zoom + pan. Uses properties=name to attach country names for the tooltip.

API Call

https://api.mapjson.com/v1/geo?properties=name

Code

<!DOCTYPE html>
<html>
<head>
  <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 { background: #18303f; margin: 0; }
    svg { width: 100%; display: block; }
    #tooltip {
      position: fixed; background: #000; color: #fff;
      font-size: 12px; padding: 4px 8px; pointer-events: none; opacity: 0;
    }
  </style>
</head>
<body>
  <div id="map"></div>
  <div id="tooltip"></div>
  <script>
    const width = 960, height = 500;
    const svg = d3.select("#map").append("svg").attr("viewBox", `0 0 ${width} ${height}`);
    const tooltip = d3.select("#tooltip");
    const projection = d3.geoEqualEarth().scale(160).translate([width / 2, height / 2 + 20]);
    const path = d3.geoPath().projection(projection);
    const g = svg.append("g");

    g.append("path").datum({ type: "Sphere" }).attr("d", path).attr("fill", "#22485e");
    g.append("path").datum(d3.geoGraticule()()).attr("d", path)
      .attr("fill", "none").attr("stroke", "#2e5870").attr("stroke-width", 0.5);

    d3.json("https://api.mapjson.com/v1/geo?properties=name").then(topo => {
      g.append("g")
        .selectAll("path")
        .data(topojson.feature(topo, topo.objects.geo).features)
        .join("path")
        .attr("d", path)
        .attr("fill", "#c8b888")
        .attr("stroke", "#3a5e70")
        .attr("stroke-width", 0.4)
        .style("cursor", "pointer")
        .on("mouseover", function(event, d) {
          d3.select(this).attr("fill", "#e8ce78");
          if (d.properties.name) tooltip.style("opacity", 1).text(d.properties.name);
        })
        .on("mousemove", function(event) {
          tooltip.style("left", (event.clientX + 14) + "px").style("top", (event.clientY - 10) + "px");
        })
        .on("mouseout", function() {
          d3.select(this).attr("fill", "#c8b888");
          tooltip.style("opacity", 0);
        });
    });

    const zoom = d3.zoom().scaleExtent([1, 12]).on("zoom", event => {
      g.attr("transform", event.transform);
    });
    svg.call(zoom);
  </script>
</body>
</html>