skip to Main Content

I am wondering how I can get the country name returned from the D3 world map when I click on it. I have tried inspecting the DOM but I cant seem to figure out how the country name, code, or population gets linked to the mapping.

The template is ripped from here
https://d3-graph-gallery.com/graph/choropleth_basic.html

// The svg
const svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

// Map and projection
const path = d3.geoPath();
const projection = d3.geoMercator()
  .scale(70)
  .center([0, 20])
  .translate([width / 2, height / 2]);

// Data and color scale
let data = new Map()
const colorScale = d3.scaleThreshold()
  .domain([100000, 1000000, 10000000, 30000000, 100000000, 500000000])
  .range(d3.schemeBlues[7]);

// Load external data and boot
Promise.all([
  d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"),
  d3.csv("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world_population.csv", function(d) {
    data.set(d.name, d.code, +d.pop)
  })
]).then(function(loadData) {
  let topo = loadData[0]
  let mouseClick = function(d) {
    d3.selectAll(".Country")
      .transition()
      .duration(200)
      .style("opacity", .8)
    d3.select(this)
      .transition()
      .duration(200)
      .style("stroke", "transparent")
    console.log(this.name)
  }
  // Draw the map
  svg.append("g")
    .selectAll("path")
    .data(topo.features)
    .join("path")
    // draw each country
    .attr("d", d3.geoPath()
      .projection(projection)
    )
    // set the color of each country
    .attr("fill", function(d) {
      d.total = data.get(d.id) || 0;
      return colorScale(d.total);
    })
  //   .on("click", mouseClick )
})
<script src="https://d3js.org/d3.v6.js"></script>
<svg id="my_dataviz" width="400" height="300"></svg>

2

Answers


  1. You need to modify your mouseClick function in the JavaScript code.

    Code:

    <html>
          <script src="https://d3js.org/d3.v6.js"></script>
          <svg id="my_dataviz" width="400" height="300"></svg>
          <script>
            // The svg
            const svg = d3.select("svg"),
              width = +svg.attr("width"),
              height = +svg.attr("height");
        
            // Map and projection
            const path = d3.geoPath();
            const projection = d3
              .geoMercator()
              .scale(70)
              .center([0, 20])
              .translate([width / 2, height / 2]);
        
            // Data and color scale
            let data = new Map();
            const colorScale = d3
              .scaleThreshold()
              .domain([100000, 1000000, 10000000, 30000000, 100000000, 500000000])
              .range(d3.schemeBlues[7]);
        
            // Load external data and boot
            Promise.all([
              d3.json(
                "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"
              ),
              d3.csv(
                "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world_population.csv",
                function (d) {
                  data.set(d.name, d.code, +d.pop);
                }
              ),
            ]).then(function (loadData) {
              let topo = loadData[0];
        
              // Mouse click function
              let mouseClick = function (event, d) {
                d3.selectAll(".Country")
                  .transition()
                  .duration(200)
                  .style("opacity", 0.8);
                d3.select(this)
                  .transition()
                  .duration(200)
                  .style("stroke", "transparent");
                console.log(d.properties.name); // Log the country name
              };
        
              // Draw the map
              svg
                .append("g")
                .selectAll("path")
                .data(topo.features)
                .join("path")
                // draw each country
                .attr("d", d3.geoPath().projection(projection))
                // set the color of each country
                .attr("fill", function (d) {
                  d.total = data.get(d.id) || 0;
                  return colorScale(d.total);
                })
                .on("click", mouseClick); // Attach the mouseClick function
            });
          </script>
        </html>

    Hope it works for you.

    Login or Signup to reply.
  2. Note : Only add this code snippet

        .attr("country-name", d => d.properties.name)
              .on("click", function(){
               console.log(d3.select(this).attr("country-name"))
              })
    
            // The svg
            const svg = d3.select("svg"),
              width = +svg.attr("width"),
              height = +svg.attr("height");
        
            // Map and projection
            const path = d3.geoPath();
            const projection = d3
              .geoMercator()
              .scale(70)
              .center([0, 20])
              .translate([width / 2, height / 2]);
        
            // Data and color scale
            let data = new Map();
            const colorScale = d3
              .scaleThreshold()
              .domain([100000, 1000000, 10000000, 30000000, 100000000, 500000000])
              .range(d3.schemeBlues[7]);
        
            // Load external data and boot
            Promise.all([
              d3.json(
                "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson"
              ),
              d3.csv(
                "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world_population.csv",
                function (d) {
                  data.set(d.name, d.code, +d.pop);
                }
              ),
            ]).then(function (loadData) {
              let topo = loadData[0];
        
              // Mouse click function
              let mouseClick = function (event, d) {
                d3.selectAll(".Country")
                  .transition()
                  .duration(200)
                  .style("opacity", 0.8);
                d3.select(this)
                  .transition()
                  .duration(200)
                  .style("stroke", "transparent");
                console.log(d.properties.name); // Log the country name
              };
        
              // Draw the map
              svg
                .append("g")
                .selectAll("path")
                .data(topo.features)
                .join("path")
                // draw each country
                .attr("d", d3.geoPath().projection(projection))
                // set the color of each country
                .attr("fill", function (d) {
                  d.total = data.get(d.id) || 0;
                  return colorScale(d.total);
                })
                .attr("country-name", d => d.properties.name)
              .on("click", function(){
               console.log(d3.select(this).attr("country-name"))
              })
                
            });
     
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
     <svg id="my_dataviz" width="400" height="300"></svg>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search