Click event in not working on D3 US Map, and mouseover event is working on particular states only

654 views Asked by At

I refer this chart code reference to draw this chart. In this code I wrote click event like svg.append("g").on("click", function(d){console.log(d.id)}. But it is not working. Click to see the image

    function ready(error, guns, us, emp) {
      emp.forEach(function (d) {
        unemployment.set(d.id, d.rate);
      });

      if (error) throw error;
    
// Draw the map
      svg.append("g")
        .attr("class", "counties")
        .selectAll("path")
        .data(topojson.feature(us, us.objects.counties).features)
        .enter().append("path")
        .attr("fill", function (d) { return color(d.rate = unemployment.get(d.id)); })
        .attr("d", path)
        .style("stroke", "lightgrey")
        .append("title")
        .text(function (d) {
          return `${d.properties.name}: ${d.rate}%`;
        })
        .on('click', function (d) {
          console.log(d.id);
        })       
1

There are 1 answers

0
scrollex On

The reason you're having issues is because your event listener is linked to the title rather than the county paths themselves.

Here's an observable block that should help; I've annotated the changes to your code below and clarified the naming differences by creating a $countyPaths variable:

  const $countyPaths = svg.append("g")
    .selectAll("path")
    .data(topojson.feature(us, us.objects.counties).features)
    .join("path")
  
  
  $countyPaths
      .attr("fill", d => color(data.get(d.id)))
      .attr("d", path)
    .append("title") 
      .text(d => `${d.properties.name}, ${states.get(d.id.slice(0, 2)).name}
      ${format(data.get(d.id))}`);//adding an event listener after this doesn't work, because it would refer to the title
  
  
  //Here the county paths are referred to, and the event listener is appropriately linked
    $countyPaths.on('click',d=>console.log(d.id))

Reading through this link may help explain some of the finer points of selections for d3, but basically, whatever the last appended item is, that's the one that you're going to be referencing in your event listener. Since, in your case, you appended title elements, you're adding an event listener to those. Breaking out code the way that I did in the example below allows you to refer to the joined elements themselves, which are, in your case, the path elements.