19

I made a line graph with d3.js (see the attached image1).

I managed to insert tooltips on graph dots when mouseover. I'd like to change color and size of dots too. I tried in many ways but it seems really difficult. Any help? Here is the piece of code:

  svg.selectAll("dot")    
    .data(data)         
    .enter().append("circle")                               
    .attr("r", 5.5)
    .style("fill", "#fff8ee")    
       .style("opacity", .8)      // set the element opacity
.style("stroke", "#f93")    // set the line colour
 .style("stroke-width", 3.5) 
    .attr("cx", function(d) { return x(d.date); })       
    .attr("cy", function(d) { return y(d.close); })     
    .on("mouseover", function(d) {   

        div.transition()        
            .duration(70)      
            .style("opacity", .7)

             ;      
        div .html(formatTime(d.date) + "<br/>"  + d.close)  
            .style("left", (d3.event.pageX) + "px")     
            .style("top", (d3.event.pageY - 28) + "px");    
        })                  
    .on("mouseout", function(d) {       
        div.transition()        
            .duration(200)      
            .style("opacity", 0);   
    });
Maximilian Peters
  • 30,348
  • 12
  • 86
  • 99
andriatz
  • 622
  • 2
  • 9
  • 22

2 Answers2

43

Just set color and size in the handlers:

.on("mouseover", function(d) {
  d3.select(this).attr("r", 10).style("fill", "red");
})                  
.on("mouseout", function(d) {
  d3.select(this).attr("r", 5.5).style("fill", "#fff8ee");
});
Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
7

I don't know why, but while d3.select(this) used to work, it doesn't anymore. I now use d3.select(event.currentTarget).

So, if we consider svg as the graph and all its circles being red by default, we can change the color of the circles to green on mouseover and return the color to red on mouseout like this:

svg.on("mouseover", function(d){
d3.select(event.currentTarget)
.style("fill", "green");
})
.on("mouseout", function(d){
d3.select(event.currentTarget)
.style("fill", "red");
});
amunnelly
  • 1,144
  • 13
  • 22
  • Your assumption is wrong: the binding of `this` still works as documented and as laid out in the accepted answer. See https://jsfiddle.net/4xjnfqL7/2/ for a working demo. Of course, your approach works too, although it is unnecessarily complicated. The context of your code might be significant as it could change the binding of `this` but since you did not provide any of that I'd consider this not helpful. – altocumulus Jul 12 '19 at 13:13
  • 2
    Thanks altocumulus. The code in the accepted answer isn't quite same as that in your jsfiddle. I've updated my own code to match that in your jsfiddle,and I hope it's useful to somebody. – amunnelly Jul 12 '19 at 13:29
  • The code in the fiddle is pretty much identical to the one in the accepted answer. I added two log statements which do not have any side-effects, though. The way your answer is now is totally wrong and is not going to work; you are trying to select a boolean value! This is not equivalent to what I have in the fiddle nor does it match the question nor the accepted answer. – altocumulus Jul 12 '19 at 13:33
  • Unless you have a working demo for your claims that `d3.select(this)` is not working anymore I suggest you rethink the post and consider deleting it altogether. – altocumulus Jul 12 '19 at 13:35
  • This answer worked for me, but `d3.select(this)` didn't. I'm using `https://d3js.org/d3.v4.min.js` version. – teg_brightly Apr 06 '20 at 15:38
  • 3
    Remember, arrow functions do not have their own `this` as compared with regular functions. – ABCD.ca Jan 13 '21 at 04:56
  • Thanks ABCD.ca. Forgetting the peculiar absence of `this` from arrow functions is a pit into which I've fallen all too often. – amunnelly Jan 14 '21 at 11:24