0

Trying to use a callback function .call() on mouseover to change opacity. Is this is a wrong selection? I've noticed that if I change const mouseOverFunc = d => d3.selectAll("circle") or even const mouseOverFunc = d => circle this leads all circles to show up. How to display one circle at a time? I understand that the promblem is I dont have to do groups.selectAll("circle") instead I have to append circle to groups same as I do with a path, but what I don't understand is to have access emissions d.year and d.amount for "cx" : xScale and "cy" : yScale.

Codepen

    let groups = svg.selectAll("g")
            .data(dataset)
            .enter()
            .append("g")



        groups.append("title")
            .text(d => d.country)


       groups
        .append("path").classed("line", true)
        .attr("d", d => line(d.emissions))
        .style("stroke-width", d => 
            d.country === "China" ? 1 : 0.2
        )

       let circle = groups.selectAll("circle")
            .data(d => d.emissions)
            .enter()
            .append("circle");


           circle.attrs({
                "cx": d => xScale(d.year),
                "cy": d => yScale(d.amount),
                "r" : 3
            })
            .style("opacity", 0)




           circle.on("mouseover", () => 
                d3.select(this)
                    .call(mouseOverFunc));

            const mouseOverFunc = selection => 
                selection
                    .transition()
                    .duration(10)
                    .style("opacity", 1)
                    .style("fill", "turquoise")
                    .attr("r", 3)   
Edgar Kiljak
  • 1,160
  • 7
  • 27

1 Answers1

2

Like written in altocumulus' comment, the reason is that this does work differently with arrow functions. If you are using an arrow function, you cannot use d3.select(this).

You can solve your problem in two ways:

Examples:

  circle.on("mouseover", function() { 
    d3.select(this)
      .call(mouseOverFunc);
  });
    
  const mouseOverFunc = selection => 
    selection
      .transition()
      .duration(10)
      .style("opacity", 1)
      .style("fill", "turquoise")
      .attr("r", 3);

OR

 circle.on("mouseover", (d, i, nodes) => 
   d3.select(nodes[i])
     .call(mouseOverFunc));
   
 const mouseOverFunc = selection => 
   selection
     .transition()
     .duration(10)
     .style("opacity", 1)
     .style("fill", "turquoise")
     .attr("r", 3);
thibautg
  • 2,004
  • 1
  • 14
  • 17